Panduan untuk Querydsl dengan JPA

1. Ikhtisar

Querydsl adalah kerangka kerja Java yang luas, yang membantu membuat dan menjalankan kueri dengan tipe aman dalam bahasa khusus domain yang mirip dengan SQL .

Pada artikel ini kita akan menjelajahi Querydsl dengan Java Persistence API.

Catatan singkat di sini adalah bahwa HQL untuk Hibernate adalah bahasa target pertama untuk Querydsl, tetapi saat ini mendukung JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections dan RDFBean sebagai backend.

2. Persiapan

Mari pertama-tama tambahkan dependensi yang diperlukan ke dalam proyek Maven kita:

 2.5.0   com.querydsl querydsl-apt ${querydsl.version} provided   com.querydsl querydsl-jpa ${querydsl.version}   org.slf4j slf4j-log4j12 1.6.1 

Dan sekarang mari kita konfigurasikan plugin Maven APT:

   ...  com.mysema.maven apt-maven-plugin 1.1.3    process   target/generated-sources com.querydsl.apt.jpa.JPAAnnotationProcessor     ...   

The JPAAnnotationProcessor akan menemukan jenis domain dijelaskan dengan javax.persistence.Entity penjelasan dan menghasilkan permintaan jenis bagi mereka.

3. Query Dengan Querydsl

Kueri dibuat berdasarkan jenis kueri yang dihasilkan yang mencerminkan properti jenis domain Anda. Juga pemanggilan fungsi / metode dibangun dengan cara yang sepenuhnya aman.

Jalur dan operasi kueri sama di semua implementasi dan juga antarmuka Kueri memiliki antarmuka dasar yang sama.

3.1. Entitas dan Jenis Kueri Querydsl

Pertama mari kita tentukan entitas sederhana yang akan kita gunakan saat kita melalui contoh:

@Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String firstname; @Column private String surname; Person() { } public Person(String firstname, String surname) { this.firstname = firstname; this.surname = surname; } // standard getters and setters }

Querydsl akan menghasilkan tipe kueri dengan nama sederhana QPerson ke dalam paket yang sama dengan Person . QPerson dapat digunakan sebagai variabel yang diketik secara statis dalam kueri Querydsl sebagai perwakilan untuk tipe Person .

Pertama - QPerson memiliki variabel contoh default yang dapat diakses sebagai bidang statis:

QPerson person = QPerson.person;

Alternatifnya, Anda dapat menentukan variabel Person Anda sendiri seperti ini:

QPerson person = new QPerson("Erich", "Gamma");

3.2. Buat Kueri Menggunakan JPAQuery

Kami sekarang dapat menggunakan instance JPAQuery untuk kueri kami:

JPAQuery query = new JPAQuery(entityManager);

Perhatikan bahwa entityManager adalah JPA EntityManager .

Sekarang mari kita ambil semua orang dengan nama depan " Kent " sebagai contoh cepat:

QPerson person = QPerson.person; List persons = query.from(person).where(person.firstName.eq("Kent")).list(person);

The dari panggilan mendefinisikan sumber permintaan dan proyeksi, yang mana bagian mendefinisikan filter dan daftar memberitahu Querydsl untuk mengembalikan semua elemen cocok.

Kami juga dapat menggunakan banyak filter:

query.from(person).where(person.firstName.eq("Kent"), person.surname.eq("Beck"));

Atau:

query.from(person).where(person.firstName.eq("Kent").and(person.surname.eq("Beck")));

Dalam format JPQL asli, kueri akan ditulis seperti ini:

select person from Person as person where person.firstName = "Kent" and person.surname = "Beck"

Jika Anda ingin menggabungkan filter melalui "atau", gunakan pola berikut:

query.from(person).where(person.firstName.eq("Kent").or(person.surname.eq("Beck")));

4. Pengurutan dan Agregasi di Querydsl

Sekarang mari kita lihat cara kerja pengurutan dan agregasi dalam pustaka Querydsl.

4.1. Memerintah

Kami akan mulai dengan mengurutkan hasil kami dalam urutan menurun menurut bidang nama belakang :

QPerson person = QPerson.person; List persons = query.from(person) .where(person.firstname.eq(firstname)) .orderBy(person.surname.desc()) .list(person);

4.2. Pengumpulan

Sekarang mari kita gunakan agregasi sederhana, karena kami memiliki beberapa yang tersedia (Jumlah, Rata-Rata, Maks, Min):

QPerson person = QPerson.person; int maxAge = query.from(person).list(person.age.max()).get(0);

4.3. Agregasi Dengan GroupBy

Kelas com.mysema.query.group.GroupBy menyediakan fungsionalitas agregasi yang dapat kita gunakan untuk menggabungkan hasil kueri dalam memori.

Berikut adalah contoh cepat di mana hasilnya dikembalikan sebagai Peta dengan nama depan sebagai kunci dan usia maksimal sebagai nilainya:

QPerson person = QPerson.person; Map results = query.from(person).transform( GroupBy.groupBy(person.firstname).as(GroupBy.max(person.age)));

5. Menguji Dengan Querydsl

Sekarang, mari kita tentukan implementasi DAO menggunakan Querydsl - dan mari kita tentukan operasi pencarian berikut:

public List findPersonsByFirstnameQuerydsl(String firstname) { JPAQuery query = new JPAQuery(em); QPerson person = QPerson.person; return query.from(person).where(person.firstname.eq(firstname)).list(person); }

Dan sekarang mari buat beberapa pengujian menggunakan DAO baru ini dan gunakan Querydsl untuk mencari objek Person yang baru dibuat (diimplementasikan di kelas PersonDao ) dan di agregasi pengujian lain menggunakan kelas GroupBy diuji:

@Autowired private PersonDao personDao; @Test public void givenExistingPersons_whenFindingPersonByFirstName_thenFound() { personDao.save(new Person("Erich", "Gamma")); Person person = new Person("Kent", "Beck"); personDao.save(person); personDao.save(new Person("Ralph", "Johnson")); Person personFromDb = personDao.findPersonsByFirstnameQuerydsl("Kent").get(0); Assert.assertEquals(person.getId(), personFromDb.getId()); } @Test public void givenExistingPersons_whenFindingMaxAgeByName_thenFound() { personDao.save(new Person("Kent", "Gamma", 20)); personDao.save(new Person("Ralph", "Johnson", 35)); personDao.save(new Person("Kent", "Zivago", 30)); Map maxAge = personDao.findMaxAgeByName(); Assert.assertTrue(maxAge.size() == 2); Assert.assertSame(35, maxAge.get("Ralph")); Assert.assertSame(30, maxAge.get("Kent")); }

6. Kesimpulan

Tutorial ini mengilustrasikan bagaimana membangun proyek JPA menggunakan Querydsl.

The implementasi penuh dari artikel ini dapat ditemukan dalam proyek github - ini adalah proyek maven berdasarkan Eclipse, sehingga harus mudah untuk impor dan berjalan seperti itu.

Catatan singkatnya di sini adalah - jalankan maven build sederhana (mvn clean install) untuk menghasilkan tipe ke dalam target / generated-sources - dan kemudian, jika Anda menggunakan Eclipse - sertakan folder tersebut sebagai folder sumber proyek.