Gdzie jest moja tabela?



Podobne dokumenty
Mapowanie obiektowo-relacyjne z wykorzystaniem Hibernate

Automatyczne generowanie kodu. 4Developers, 26 marca 2010

Pony ORM. Dominik Kozaczko, PyWaw #73

Podejście obiektowe do relacyjnych baz danych Hibernate.

Programowanie wielowarstwowe i komponentowe

Protokół JDBC współpraca z relacyjnymi bazami danych lab3

15. Funkcje i procedury składowane PL/SQL

Sexy unit testy. czyli o kilku praktykach w testach jednostkowych

Podzapytania do tabel W miejscu w którym możemy użyć nazwy tabeli, możemy użyć podzapytania

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Projektowanie bazy danych. Jarosław Kuchta Projektowanie Aplikacji Internetowych

Leszek Stasiak Zastosowanie technologii LINQ w

XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Metody dostępu do danych

Bazy danych dla producenta mebli tapicerowanych. Bartosz Janiak Marcin Sikora Wrocław r.

Programowanie w języku Java. Bazy danych SQLite w Javie

Podstawowe wykorzystanie Hibernate

NHibernate. Narzędzie mapowania obiektowo - relacyjnego

Wzorce logiki dziedziny

Uniwersytet im. Adama Mickiewicza w Poznaniu Wydział Matematyki i Informatyki. Projekt bazy danych <Moja baza>

Metody dostępu do danych

JPA Java Persistance API

Wprowadzenie do BD Operacje na bazie i tabelach Co poza zapytaniami? Algebra relacji. Bazy Danych i Systemy informacyjne Wykład 2.

Wielojęzykowość w aplikacjach J2EE. Tomasz.Skutnik@e-point.pl

Java a średni (?) projekt informatyczny

Generowanie raportów

Karolina Rusin, Paweł Biczysko, Michał Olejnik. 11 maja 2009

Paweł Cieśla. Dokumentacja projektu

Post-relacyjne bazy danych

Zapytania z ograniczeniem czasowym w Oracle

*Grafomania z. Neo4j. Praktyczne wprowadzenie do grafowej bazy danych.

Od wymagań do Javy w mgnieniu oka

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Obiektowość BD Powtórka Czas odpowiedzi. Bazy Danych i Systemy informacyjne Wykład 14. Piotr Syga

Przykład połączenie z bazą danych

SPRING FRAMEWORK. dr inż. Jakub Chłapioski

Wykład 05 Bazy danych

NARZĘDZIA WIZUALIZACJI

Map Reduce Proste zliczanie słów i zapytania SQL

NHibernate Hibernate dla platformy.net. Hibernate posiada także dużą społeczność, zatem nietrudno uzyskać jakieś wsparcie w przypadku problemów.

Programowanie obiektowe

Języki programowania wysokiego poziomu. PHP cz.4. Bazy danych

Zadanie polega na stworzeniu bazy danych w pamięci zapewniającej efektywny dostęp do danych baza osób.

Baza danych sql. 1. Wprowadzenie

Biblioteka. Bazy danych I dokumentacja projektu. Cel projektu:

Migracja do PostgreSQL za pomocą narzędzi Enterprise DB

Java Persistence API - zagadnienia zaawansowane

Protokół JDBC współpraca z relacyjnymi bazami danych lab4. Dr inż. Zofia Kruczkiewicz Programowanie aplikacji internetowych

Aplikacja webowa w Javie szybkie programowanie biznesowych aplikacji Spring Boot + Vaadin

Obsługa błędów w SQL i transakcje. Obsługa błędów w SQL

Wieloplatformowe aplikacje sieciowe. dr inż. Juliusz Mikoda mgr inż. Anna Wawszczak

22 października Akademia Górniczo-Hutnicza, Automatyka i Robotyka. Porównanie LINQ i NHibernate. Mateusz Mazur Ale o co chodzi?

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

Wprowadzenie do projektowania i wykorzystania baz danych Relacje

Tuning SQL Server dla serwerów WWW

Programowanie obiektowe

Założenia do ćwiczeń: SQL Server UWM Express Edition: \SQLEXPRESS. Zapoznaj się ze sposobami użycia narzędzia T SQL z wiersza poleceń.

Podstawy frameworka Spring

Enterprise JavaBeans

Hibernate. Adrian Gawor, Adam Klekotka, Piotr Kubisz. Technologie Biznesu Elektronicznego. 12 maja 2009

Enterprise JavaBeans. 1. Architektura EJB: komponenty encyjne, komponenty sesyjne, komponenty sterowane komunikatami. 2. Kontenery EJB JBoss.

Programowanie kontraktowe w Javie

Odnawialne Źródła Energii I rok. Tutorial PostgreSQL

Relacyjne bazy danych. Podstawy SQL

Automatyka i Robotyka ROK III TEMAT: TWORZENIE I ZARZĄDZANIE INTERNETOWĄ BAZĄ DANYCH

Język SQL, zajęcia nr 1

XML w bazie danych IBM DB2

Programowanie w Ruby

ORACLE (Wykład 1) aragorn.pb.bialystok.pl/~aonisko. Typy rozproszonych baz danych. Systemy klient-serwer. Klient-serwer: Przykład

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Paweł Rajba

DECLARE VARIABLE zmienna1 typ danych; BEGIN

Programowanie w języku Java WYKŁAD

Programowanie w Javie cz. 1 Wstęp. Łódź, 24 luty 2014 r.

Bazy danych tworzenie aplikacji bazodanowych ORM / JPA

Relacje. 1. Modelowanie relacji. - siedem rodzajów relacji J2EE. - relacje jedno i wielokierunkowe, - relacje reprezentowane przez kolekcje.

LAB 3 (część 1 Projektu)

Integralność danych Wersje języka SQL Klauzula SELECT i JOIN

Typy metod: konstruktory, destruktory, selektory, zapytania, iteratory.

Dokumentacja techniczna API systemu SimPay.pl

Relacje. 1. Modelowanie relacji. - siedem rodzajów relacji J2EE. - relacje jedno i wielokierunkowe, - relacje reprezentowane przez kolekcje.

SYSTEM MONITORINGU PARAMETRÓW WĘZŁÓW PRZECHOWYWANIA DANYCH DLA PROJEKTU KRAJOWY MAGAZYN DANYCH PODRĘCZNIK DEWELOPERA

MVC w praktyce tworzymy system artykułów. cz. 1

Programowanie obiektowe

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Laboratorium 3. Odkrywanie reguł asocjacyjnych.

Monika Kruk Mariusz Grabowski. Informatyka Stosowana WFiIS, AGH 13 grudzień 2006

Oracle PL/SQL. Paweł Rajba.

koledzy, Jan, Nowak, ul. Niecała 8/23, , Wrocław, , ,

Bazy danych. Bazy danych. Podstawy języka SQL. Dr inż. Paweł Kasprowski.

Java i bazy danych. 1. JDBC podstawy, transakcje. 2. Mapowanie relacyjno obiektowe. Hibernate, przykład.

Programowanie w Ruby

Cel przedmiotu. Wymagania wstępne w zakresie wiedzy, umiejętności i innych kompetencji 1 Język angielski 2 Inżynieria oprogramowania

AKADEMIA GÓRNICZO-HUTNICZA Wydział Elektrotechniki, Automatyki, Elektroniki i Informatyki

Bazy i Systemy Bankowe Sp. z o.o. ul. Kasprzaka 3, Bydgoszcz

Wykład 6. SQL praca z tabelami 3

Testowanie II. Celem zajęć jest zapoznanie studentów z oceną jakości testów przy wykorzystaniu metryk pokrycia kodu testami (ang. code coverage).

Transkrypt:

Gdzie jest moja tabela? Czyli jak sobie radzić w Javie i SQL gdy zmienia się schemat bazy danych. Tomasz Skutnik 21 Listopada 2011 r

UWIELBIAM piratów programować. Dziś koduję sklep internetowy.

Jak rozmawiać z bazą danych? Hibernate, JPA, JDO, JDBC? To może użyję Hibernate.

public class Order { private Integer id; private Customer customer; private Integer ordertotal; private Date orderdate; <hibernate-mapping> <class name="samples.order" table="order"> <id name="id" type="java.lang.integer"> <column name="id" /> <generator class="increment" /> Dlaczego mi nie działa?

public class Order { private Integer id; private Customer customer; private Integer ordertotal; private Date orderdate; <hibernate-mapping> <class name="samples.order" table="`order`"> <id name="id" type="java.lang.integer"> <column name="id" /> <generator class="increment" /> Kilka godzin później.

Order order = new Order(); order.setcustomer((customer) session.get(customer.class, 1)); order.setorderdate(new Date()); List<OrderItem> items = new ArrayList<OrderItem>(); int ordertotal = 0; OrderItem orderitem = new OrderItem(); orderitem.setitemno(1); Criteria criteria = session.createcriteria(product.class); criteria.add(restrictions.eq("name", "Raft")); Product product = (Product) criteria.list().get(0); orderitem.setquantity(1); orderitem.setproduct(product); orderitem.setprice(product.getprice()); orderitem.setitemtotal(orderitem.getprice() * orderitem.getquantity()); items.add(orderitem); ordertotal += orderitem.getitemtotal(); for (OrderItem item : items) { session.persist(item); } order.setorderitems(items); order.setordertotal(ordertotal); session.persist(order); (50 linijek) Jeszcze tylko 99 przypadków testowych.

Testy przynoszą złe wieści. Och! Tam też to miałem zmienić?

Problem 1: Jak nie zepsuć zapytań przy zmienianiu nazw? Query query = session.createquery( "select sum(sumtotal)" + " from Order order" + " where order.orderdate >= :lastmonth"); query.setparameter("lastmonth", getlastmonthcutoff()); return ((Number) query.uniqueresult()).intvalue();

Problem 1: Jak nie zepsuć zapytań przy zmienianiu nazw? Query query = session.createquery( "select sum(sumtotal)" + " from Order order" + " where order.orderdate >= :lastmonth"); query.setparameter("lastmonth", getlastmonthcutoff()); return ((Number) query.uniqueresult()).intvalue(); Przyczyna: Duplikacja nazw (Java, HQL, XML, skrypty). Ciągi znaków (String) nie mają struktury. W przypadku błędu kompilator Cię nie ostrzeże.

Rozwiązanie 1: użycie stałych w zapytaniach. Query query = session.createquery( "select sum(" + Order.ORDER_TOTAL + ")" + " from " + Order.ENTITY + " order" + " where order." + Order.ORDER_DATE + " >= :lastmonth"); query.setparameter("lastmonth", getlastmonthcutoff()); return ((Number) query.uniqueresult()).intvalue(); Zalety Zmiana nazwy w jednym miejscu Wszystkie miejsca użycia znajduje IDE (CTRL+SHIFT+G) Wady Wciąż możliwe błędy składniowe Kodowanie stałych BARDZO KOSZTOWNE

Rozwiązanie 2: obiektowe API do budowy zapytań (Fluent Interface). SelectQuery query = new SelectQuery(Order.class, AExp.sum(Order.ORDER_TOTAL)).where(Order.ORDER_DATE.gt(getLastMonthCutoff())); return orderdao.selectobject(query, new IntegerRowHandler()); Zalety: Szybkie kodowanie w IDE (CTRL+SPACE) Kompilator wyłapuje pomyłki w nazwach Nie ma błędów składniowych Wady: Kodowanie stałych wciąż BARDZO KOSZTOWNE

Uruchomienie produkcyjne to nowe problemy. Ile trwa to zapytanie? Zadzwonię po DBA.

Przychodzi DBA i pyta: jaki jest schemat bazy danych? które zapytanie SQL obciąża serwer? jak wygląda plan zapytania?

To jest ważne dla programisty.

To jest ważne dla DBA: => EXPLAIN ANALYZE VERBOSE select orderitems1_.id as ID2_, orderitems1_.itemno as ITEMNO2_, orderitems1_.product as PRODUCT2_, orderitems1_.price as PRICE2_, orderitems1_.quantity as QUANTITY2_, orderitems1_.itemtotal as ITEMTOTAL2_ from "order" order0_ inner join ORDERITEM orderitems1_ on order0_.id=orderitems1_.orderid where order0_.orderdate>='mon Apr 04 04:32:16 CEST 2011' and order0_.customer=1 ; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Hash Join (cost=31.02..35.11 rows=6 width=24) (actual time=0.050..0.160 rows=73 loops=1) Output: orderitems1_.id, orderitems1_.itemno, orderitems1_.product, orderitems1_.price, orderitems1_.quantity Hash Cond: (orderitems1_.orderid = order0_.id) -> Seq Scan on orderitem orderitems1_ (cost=0.00..3.47 rows=147 width=28) (actual time=0.004..0.036 rows=1 Output: orderitems1_.id, orderitems1_.itemno, orderitems1_.product, orderitems1_.price, orderitems1_.qu -> Hash (cost=31.00..31.00 rows=2 width=4) (actual time=0.037..0.037 rows=25 loops=1) Output: order0_.id -> Seq Scan on "order" order0_ (cost=0.00..31.00 rows=2 width=4) (actual time=0.008..0.022 rows=25 l Output: order0_.id Filter: ((orderdate >= '2011-04-04 04:32:16'::timestamp without time zone) AND (customer = 1))

Problem 2: Jak nie przeciążyć bazy danych kosztownym zapytaniem? Query query = session.createquery( "select order.orderitems" + " from Order order" + " where order.orderdate >= :lastmonth" + " and order.customer = :customer"); query.setparameter("lastmonth", getlastmonthcutoff()); query.setparameter("customer", customer); Set<Product> products = new HashSet<Product>(); Iterator<?> i = query.list().iterator(); while (i.hasnext()) { OrderItem oi = (OrderItem) i.next(); products.add(oi.getproduct()); } return new ArrayList<Product>(products);

Problem 2: Jak nie przeciążyć bazy danych kosztownym zapytaniem? Query query = session.createquery( "select order.orderitems" + " from Order order" + " where order.orderdate >= :lastmonth" + " and order.customer = :customer"); query.setparameter("lastmonth", getlastmonthcutoff()); query.setparameter("customer", customer); Set<Product> products = new HashSet<Product>(); Iterator<?> i = query.list().iterator(); while (i.hasnext()) { OrderItem oi = (OrderItem) i.next(); products.add(oi.getproduct()); } return new ArrayList<Product>(products); Przyczyna: Mała kontrola nad generowanym SQL (N+1 zapytań, niejawny JOIN) Brak optymalizacji bazy danych (statystyki, indeksy) Cieknąca abstrakcja bazy danych.

Nowe wymagania? O nie! Znowu!

Co mówi doświadczenie: HQL nie upraszcza lecz komplikuje: n+1 zapytań strategie wczytywania encji zależnych generacja HQL SQL Cache często maskuje błędy. Nie da się ukryć bazy danych za obiektową abstrakcją.

To co mam zrobić? Znasz lepszy sposób?

Tak! JEST lepszy sposób: ERD i SQL. customer id INTEGER <pk> not null email VARCHAR(320) not null product id INTEGER <pk> not null name VARCHAR(100) not null price INTEGER not null quantity INTEGER not null order id INTEGER <pk> not null customer_id VARCHAR(100) <fk> not null order_date DATE not null shipment_date DATE not null order_total INTEGER not null order_id order_item INTEGER <pk,fk1> not null item_no INTEGER <pk> not null product_id INTEGER <fk2> not null price INTEGER not null quantity INTEGER not null item_total INTEGER not null Czyli jak przestałem się martwić i pokochałem bazę danych.

Modelowanie ERD dla piratów programistów: Projektowanie wizualne łatwiejsze niż pisanie annotacji. Cała informacja o strukturze bazy danych w jednym miejscu. Pełna kontrola nad strukturą fizyczną (klucze, ograniczenia, indeksy). Dobre narzędzia zapewniają: automatyczną migrację schematu i danych dostęp do rozszerzonych funkcji bazy

ERD

ERD SQL

ERD Java SQL

Zaraz, zaraz! Teraz mam jeszcze więcej kodowania!

Problem 3: Jak utrzymać zgodność modelu ERD i kodu Java? Ręczne kodowanie zbyt kosztowne i podatne na błędy. Co synchronizować: Encje (POJO, DTO) DAO Zapytania

Rozwiązanie: Nie koduj generuj. Zaprojektuj bazę używając ERD. Wygeneruj kod Java z modelu ERD. Programuj zapytania SQL używając obiektowego API (Fluent Interface).

ERD

Nazwy ERD Encje DAO

Nazwy ERD Encje Aplikacja DAO

A co się stanie jak zmienię model?

Nazwy ERD Encje Aplikacja DAO

Nazwy ERD Encje Aplikacja DAO

ERD Błąd kompilacji Aplikacja

Co JA będę z tego mieć?

Koniec przykrych niespodzianek.

Koniec nudnego kodowania Koniec błędów składniowych Konflikt w bazie = błąd kompilacji

Podsumowanie Zaprojektuj bazę używając ERD Wygeneruj kod Java z modelu ERD Buduj zapytania SQL używając obiektowego API (Fluent Interface)

Programowałem do późna, by zdążyć na czas. Teraz napraw swoją bazę, a ja się zdrzemnę.

Dziękuję. Czy są pytania? Tomasz.Skutnik@e-point.pl