Tag: SqlResultSetMapping
piękno leży w oku patrzącego. Tak jak „ease”:
dowiedz się więcej o mapowaniu zestawów wyników SQL i z łatwością obsługuj natywne wyniki zapytań: http://t.co/WH4BTlClIP # JPA # Java # JavaEE
– Thorben Janssen (@thjanssen123) April 15, 2015
Thorben pisze bardzo dobre i przydatne artykuły o JPA, a ostatnio rozpoczął doskonałą serię o nowych funkcjach JPA 2.1. W tym: mapowanie zbioru wyników. Możesz znać mapowanie zestawów wyników ze stron takich jak CTMMC lub annotatiomania.com. możemy podsumować tę procedurę mapowania w następujący sposób:
a) zdefiniuj mapowanie
@SqlResultSetMapping( name = "BookAuthorMapping", entities = { @EntityResult( entityClass = Book.class, fields = { @FieldResult(name = "id", column = "id"), @FieldResult(name = "title", column = "title"), @FieldResult(name = "author", column = "author_id"), @FieldResult(name = "version", column = "version")}), @EntityResult( entityClass = Author.class, fields = { @FieldResult(name = "id", column = "authorId"), @FieldResult(name = "firstName", column = "firstName"), @FieldResult(name = "lastName", column = "lastName"), @FieldResult(name = "version", column = "authorVersion")})})
powyższe mapowanie jest raczej proste. Określa sposób mapowania kolumn bazy danych do pól encji i do encji jako całości. Następnie nadajesz temu mapowaniu nazwę ("BookAuthorMapping"
), którą możesz następnie ponownie wykorzystać w całej aplikacji, np. z natywnymi zapytaniami JPA.
szczególnie podoba mi się to, że Thorben wtedy pisze:
jeśli nie lubisz dodawać tak dużego bloku adnotacji do swojej jednostki, Możesz również zdefiniować mapowanie w pliku XML
… wracamy więc do zastąpienia ogromnych bloków adnotacji ogromnymi blokami XML – techniki, której wielu z nas chciało uniknąć… :- )
b) zastosuj mapowanie
gdy mapowanie zostanie statycznie zdefiniowane dla jakiegoś typu Java, możesz pobrać te jednostki, stosując powyższe BookAuthorMapping
List<Object> results = this.em.createNativeQuery( "SELECT b.id, b.title, b.author_id, b.version, " + " a.id as authorId, a.firstName, a.lastName, " + " a.version as authorVersion " + "FROM Book b " + "JOIN Author a ON b.author_id = a.id", "BookAuthorMapping").getResultList();results.stream().forEach((record) -> { Book book = (Book)record; Author author = (Author)record;});
zauważ, że nadal musisz pamiętać typy Book
i Author
i rzucać wyraźnie, ponieważ żadna weryfikowalna informacja o typie nie jest tak naprawdę dołączona do czegokolwiek.
definicja „złożonego”
teraz artykuł twierdzi, że jest to mapowanie „złożone” i bez wątpienia zgodzę się z tym. To bardzo proste zapytanie z prostym połączeniem już powoduje taki bałagan w adnotacji, jeśli chcesz naprawdę zmapować swoje jednostki za pomocą JPA. Nie chcesz widzieć adnotacji mapowania Thorbena, gdy zapytania staną się nieco bardziej złożone. I pamiętaj, @SqlResultSetMapping
chodzi o mapowanie (natywne!) Wyniki SQL, więc nie jesteśmy już w Krainie obiekt-Wykres-trwałość, jesteśmy w Krainie SQL, gdzie zbiorcze pobieranie, denormalizacja, agregowanie i inne „fantazyjne” rzeczy SQL jest królem.
problem jest tutaj:
Java 5 wprowadza adnotacje. Adnotacje pierwotnie miały być używane jako „sztuczne modyfikatory”, czyli takie rzeczy jak static
, final
, protected
(co ciekawe, Cejlon zna tylko adnotacje, bez modyfikatorów). To ma sens. Projektanci języka Java mogą wprowadzać nowe modyfikatory / ” słowa kluczowe „bez łamania istniejącego kodu – ponieważ” prawdziwe ” słowa kluczowe są słowami zastrzeżonymi, które trudno jest wprowadzić w języku. Pamiętasz enum
?
tak więc dobre przypadki użycia adnotacji (a jest ich tylko kilka) są:
@Override
-
@Deprecated
(chociaż atrybut komentarza byłby fantazyjny) @FunctionalInterface
JPA (i inne API Java EE, a także Spring) całkowicie zwariowały na temat używania adnotacji. Powtarzaj za mną:
żaden język
@Before
lub@After
Java nigdy nie nadużywał adnotacji tak bardzo, jak Java(pomysł @ Before / @After był lennoffem, na Reddicie)
czytając powyższe mam silne déjà vu. Pamiętasz co następuje?
żaden język przed lub po Javie nigdy nie nadużywał sprawdzonych wyjątków tak bardzo, jak Java
wszyscy będziemy głęboko żałować adnotacji Java do 2020 roku.
adnotacje są dużą Wartą w systemie typu Java. Mają bardzo ograniczone uzasadnione zastosowanie, a to, co my, programiści Java Enterprise, robimy obecnie, absolutnie nie mieści się w granicach „uzasadnionych”. Nadużywamy ich do konfiguracji rzeczy, dla których powinniśmy pisać kod.
oto jak wykonasz to samo zapytanie za pomocą jOOQ (lub dowolnego innego API wykorzystującego generics I type safety dla SQL):
Book b = BOOK.as("b");Author a = AUTHOR.as("a");DSL.using(configuration) .select(b.ID, b.TITLE, b.AUTHOR_ID, b.VERSION, a.ID, a.FIRST_NAME, a.LAST_NAME, a.VERSION) .from(b) .join(a).on(b.AUTHOR_ID.eq(a.ID)) .fetch() .forEach(record -> { BookRecord book = record.into(b); AuthorRecord author = record.into(a); });
ten przykład łączy zarówno adnotacje JPA 2.1, jak i zapytania. Wszystkie meta informacje o projektowanych „entities” są już zawarte w zapytaniu, a więc w Result
, która jest wytwarzana metodą fetch()
. Ale to nie ma znaczenia, chodzi o to, że to wyrażenie lambda…
record -> { BookRecord book = record.into(b); AuthorRecord author = record.into(a);}
… to może być cokolwiek chcesz! Podobnie jak bardziej wyrafinowane przykłady, które pokazaliśmy w poprzednich wpisach na blogu:
- koniec z ORMs
- Przekształć dane SQL w Wykresy za pomocą jOOQ i JavaFX
mapowanie można definiować ad-hoc, w locie, za pomocą funkcji. Funkcje są idealnymi maperami, ponieważ pobierają dane wejściowe, wytwarzają dane wyjściowe i są całkowicie bezpaństwowe. Najlepsze w funkcjach w Javie 8 jest to, że są kompilowane przez kompilator Javy i mogą być używane do sprawdzania mapowania. I można przypisywać funkcje do obiektów, co pozwala na ponowne wykorzystanie funkcji, gdy dany algorytm mapowania może być użyty kilka razy.
w rzeczywistości klauzula SQL SELECT
sama w sobie jest taką funkcją. Funkcja, która przekształca wejściowe krotki / wiersze w wyjściowe krotki / wiersze i można dostosować tę funkcję w locie za pomocą dodatkowych wyrażeń.
nie ma absolutnie żadnego sposobu, aby sprawdzić cokolwiek w poprzednim natywnym oświadczeniu SQL JPA 2.1 i przykładzie @SqlResultSetMapping
. Wyobraź sobie zmianę nazwy kolumny:
List<Object> results = this.em.createNativeQuery( "SELECT b.id, b.title as book_title, " + " b.author_id, b.version, " + " a.id as authorId, a.firstName, a.lastName, " + " a.version as authorVersion " + "FROM Book b " + "JOIN Author a ON b.author_id = a.id", "BookAuthorMapping").getResultList();
zauważyłeś różnicę? Kolumna b.title
została przemianowana na book_title
. W łańcuchu SQL. Który wybucha w czasie biegu! Jak pamiętać, że trzeba również dostosować
@FieldResult(name = "title", column = "title")
… aby być
@FieldResult(name = "title", column = "book_title")
i odwrotnie, jak pamiętać, że po zmianie nazwy column
w @FieldResult
, będziesz musiał również sprawdzić, gdzie jest używana ta "BookAuthorMapping"
, a także zmienić nazwy kolumn w tych zapytaniach.
@SqlResultSetMapping( name = "BookAuthorMapping", ...)
adnotacje są złe
Możesz lub nie zgadzasz się z niektórymi z powyższych. Możesz lub nie lubić jOOQ jako alternatywy dla JPA, to jest całkowicie w porządku. Ale naprawdę trudno się nie zgodzić z faktem, że:
- Java 5 wprowadziła bardzo przydatne adnotacje
- Java EE / Spring mocno nadużywała tych adnotacji, aby zastąpić XML
- mamy teraz równoległy system typów wszechświata w Javie
- ten równoległy system typów wszechświata jest całkowicie bezużyteczny, ponieważ kompilator nie może go introspektować
- Java SE 8 wprowadza Programowanie funkcyjne i wiele wnioskowania typów
- Java SE 9-10 wprowadzi więcej niesamowitych funkcji językowych
- teraz staje się jasne, że to, co było konfiguracją (XML lub adnotacje), powinno być kodem w pierwszej kolejności
- JPA 2.1 stał się nowym EJB 2.0: przestarzały
, jak powiedziałem. Trudno się nie zgodzić. Lub innymi słowy:
kod jest o wiele lepszy w wyrażaniu algorytmów niż konfiguracja
spotkałem Thorbena osobiście przy wielu okazjach na konferencjach. Ten rant tutaj nie był przeznaczony osobiście, Thorben: -) Twoje artykuły o JPA są bardzo interesujące. Jeśli czytelnicy tego artykułu używają JPA, zajrzyjcie na Blog Thorbena: http://www.thoughts-on-java.org.
w międzyczasie chciałbym nominować Thorbena do szanowanego tytułu „Annotatiomaniak roku 2015”
Write a Reply or Comment