Ръководство за Querydsl с JPA

1. Общ преглед

Querydsl е обширна Java рамка, която помага при създаването и изпълнението на безопасни за тип заявки на специфичен за домейн език, подобен на SQL .

В тази статия ще изследваме Querydsl с API за устойчивост на Java.

Бърза странична бележка тук е, че HQL за Hibernate е първият целеви език за Querydsl, но в наши дни той поддържа JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections и RDFBean като backends.

2. Подготовка

Нека първо добавим необходимите зависимости в нашия проект Maven:

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

А сега нека конфигурираме приставката Maven APT:

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

В JPAAnnotationProcessor ще намерите видове домейни анотирани с javax.persistence.Entity анотация и генерира типовете заявки за тях.

3. Заявки с Querydsl

Заявките се изграждат въз основа на генерирани типове заявки, които отразяват свойствата на вашите типове домейни. Също така извикванията на функции / методи се конструират по напълно безопасен за типа начин.

Пътищата на заявките и операциите са еднакви във всички реализации, а също така интерфейсите на заявките имат общ основен интерфейс.

3.1. Обект и тип заявка Querydsl

Нека първо дефинираме прост обект, който ще използваме, докато разглеждаме примери:

@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 ще генерира тип заявка с простото име QPerson в същия пакет като Person . QPerson може да се използва като статично въведена променлива в Querydsl заявки като представител за типа Person .

Първо - QPerson има променлива по подразбиране по подразбиране, която може да бъде достъпна като статично поле:

QPerson person = QPerson.person;

Като алтернатива можете да дефинирате свои собствени променливи Person по следния начин:

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

3.2. Изграждане на заявка с помощта на JPAQuery

Вече можем да използваме екземпляри JPAQuery за нашите заявки:

JPAQuery query = new JPAQuery(entityManager);

Обърнете внимание, че entityManager е JPA EntityManager .

Нека сега извлечем всички хора с първото име „ Кент “ като бърз пример:

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

Най от повикване дефинира източника на заявката и проекцията, за когато е част определя филтъра и списък разказва Querydsl да върне всички съвпадащи елементи.

Можем да използваме и множество филтри:

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

Или:

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

В родната форма на JPQL заявката ще бъде написана по следния начин:

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

Ако искате да комбинирате филтрите чрез „или“, използвайте следния модел:

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

4. Подреждане и агрегиране в Querydsl

Нека сега разгледаме как работят подреждането и агрегирането в библиотеката Querydsl.

4.1. Поръчка

Ще започнем с подреждането на резултатите ни в низходящ ред от полето за фамилия :

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

4.2. Агрегация

Нека сега използваме просто обобщаване, тъй като имаме няколко налични (Сума, Ср., Макс., Мин.):

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

4.3. Агрегация с GroupBy

Класът com.mysema.query.group.GroupBy предоставя обобщаваща функционалност, която можем да използваме за обединяване на резултатите от заявката в паметта.

Ето един бърз пример, в който резултатът се връща като карта с FirstName като ключ и макс възраст като стойността:

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

5. Тестване с Querydsl

Сега, нека дефинираме реализация на DAO с помощта на Querydsl - и нека дефинираме следната операция за търсене:

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); }

И сега нека изградим няколко теста, използвайки този нов DAO и нека използваме Querydsl за търсене на новосъздадени Person обекти (внедрени в клас PersonDao ), а в друго тестово агрегиране се използва клас GroupBy :

@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. Заключение

Този урок илюстрира как да се изгради JPA проект с помощта на Querydsl.

Най- пълното прилагане на тази статия може да се намери в проекта GitHub - това е Maven проекта Eclipse базирани, така че трябва да бъде лесен за внос и работи като такъв.

Една бърза бележка тук е - стартирайте проста компилация на maven (mvn clean install), за да генерирате типовете в target / generated- source - и след това, ако използвате Eclipse - включете папката като папка източник на проекта.