添加依赖
<dependency> <groupId>com.querydslgroupId> <artifactId>querydsl-jpaartifactId> dependency> <dependency> <groupId>com.querydslgroupId> <artifactId>querydsl-aptartifactId> <scope>providedscope> dependency>
<plugin> <groupId>com.mysema.mavengroupId> <artifactId>apt-maven-pluginartifactId> <version>1.1.3version> <executions> <execution> <goals> <goal>processgoal> goals> <configuration> <outputDirectory>target/generated-sources/javaoutputDirectory> <processor>com.querydsl.apt.jpa.JPAAnnotationProcessorprocessor> configuration> execution> executions> plugin>
运行 mvn compile, 将生成Query实体。
单表查询
package com.chhliu.springboot.jpa.repository; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Component; import com.chhliu.springboot.jpa.entity.QUser; import com.chhliu.springboot.jpa.entity.User; import com.querydsl.core.types.Predicate; import com.querydsl.jpa.impl.JPAQueryFactory; /** * 描述:QueryDSL JPA * @author chhliu */ @Component @Transactional public class UserRepositoryManagerDsl { @Autowired private UserRepositoryDls repository; @Autowired @PersistenceContext private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct public void init() { queryFactory = new JPAQueryFactory(entityManager); } public User findUserByUserName(final String userName){ /** * 该例是使用spring data QueryDSL实现 */ QUser quser = QUser.user; Predicate predicate = quser.name.eq(userName); return repository.findOne(predicate); } /** * attention: * Details:查询user表中的所有记录 */ public ListfindAll(){ QUser quser = QUser.user; return queryFactory.selectFrom(quser) .fetch(); } /** * Details:单条件查询 */ public User findOneByUserName(final String userName){ QUser quser = QUser.user; return queryFactory.selectFrom(quser) .where(quser.name.eq(userName)) .fetchOne(); } /** * Details:单表多条件查询 */ public User findOneByUserNameAndAddress(final String userName, final String address){ QUser quser = QUser.user; return queryFactory.select(quser) .from(quser) // 上面两句代码等价与selectFrom .where(quser.name.eq(userName).and(quser.address.eq(address)))// 这句代码等同于where(quser.name.eq(userName), quser.address.eq(address)) .fetchOne(); } /** * Details:使用join查询 */ public List findUsersByJoin(){ QUser quser = QUser.user; QUser userName = new QUser("name"); return queryFactory.selectFrom(quser) .innerJoin(quser) .on(quser.id.intValue().eq(userName.id.intValue())) .fetch(); } /** * Details:将查询结果排序 */ public List findUserAndOrder(){ QUser quser = QUser.user; return queryFactory.selectFrom(quser) .orderBy(quser.id.desc()) .fetch(); } /** * Details:Group By使用 */ public List findUserByGroup(){ QUser quser = QUser.user; return queryFactory.select(quser.name) .from(quser) .groupBy(quser.name) .fetch(); } /** * Details:删除用户 */ public long deleteUser(String userName){ QUser quser = QUser.user; return queryFactory.delete(quser).where(quser.name.eq(userName)).execute(); } /** * Details:更新记录 */ public long updateUser(final User u, final String userName){ QUser quser = QUser.user; return queryFactory.update(quser).where(quser.name.eq(userName)) .set(quser.name, u.getName()) .set(quser.age, u.getAge()) .set(quser.address, u.getAddress()) .execute(); } /** * Details:使用原生Query */ public User findOneUserByOriginalSql(final String userName){ QUser quser = QUser.user; Query query = queryFactory.selectFrom(quser) .where(quser.name.eq(userName)).createQuery(); return (User) query.getSingleResult(); } /** * Details:分页查询单表 */ public Page findAllAndPager(final int offset, final int pageSize){ Predicate predicate = QUser.user.id.lt(10); Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "id")); PageRequest pr = new PageRequest(offset, pageSize, sort); return repository.findAll(predicate, pr); } }
多表操作示例(一对一)
package com.chhliu.springboot.jpa.repository; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.chhliu.springboot.jpa.dto.PersonIDCardDto; import com.chhliu.springboot.jpa.entity.QIDCard; import com.chhliu.springboot.jpa.entity.QPerson; import com.querydsl.core.QueryResults; import com.querydsl.core.Tuple; import com.querydsl.core.types.Predicate; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; @Component public class PersonAndIDCardManager { @Autowired @PersistenceContext private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct public void init() { queryFactory = new JPAQueryFactory(entityManager); } /** * Details:多表动态查询 */ public ListfindAllPersonAndIdCard(){ Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); JPAQuery jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name) .from(QIDCard.iDCard, QPerson.person) .where(predicate); return jpaQuery.fetch(); } /** * Details:将查询结果以DTO的方式输出 */ public List findByDTO(){ Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); JPAQuery jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name) .from(QIDCard.iDCard, QPerson.person) .where(predicate); List tuples = jpaQuery.fetch(); List dtos = new ArrayList (); if(null != tuples && !tuples.isEmpty()){ for(Tuple tuple:tuples){ String address = tuple.get(QPerson.person.address); String name = tuple.get(QPerson.person.name); String idCard = tuple.get(QIDCard.iDCard.idNo); PersonIDCardDto dto = new PersonIDCardDto(); dto.setAddress(address); dto.setIdNo(idCard); dto.setName(name); dtos.add(dto); } } return dtos; } /** * Details:多表动态查询,并分页 */ public QueryResults findByDtoAndPager(int offset, int pageSize){ Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name) .from(QIDCard.iDCard, QPerson.person) .where(predicate) .offset(offset) .limit(pageSize) .fetchResults(); } }
上面将查询结果以DTO的方式输出的示例中,在查询结束后,将查询结果手动的转换成了DTO对象,这种方式其实不太优雅,QueryDSL给我们提供了更好的方式,见下面的示例:
/** * Details:方式一:使用Bean投影 */ public ListfindByDTOUseBean(){ Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); return queryFactory.select( Projections.bean(PersonIDCardDto.class, QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)) .from(QIDCard.iDCard, QPerson.person) .where(predicate) .fetch(); } /** * Details:方式二:使用fields来代替setter */ public List findByDTOUseFields(){ Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); return queryFactory.select( Projections.fields(PersonIDCardDto.class, QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)) .from(QIDCard.iDCard, QPerson.person) .where(predicate) .fetch(); } /** * Details:方式三:使用构造方法,注意构造方法中属性的顺序必须和构造器中的顺序一致 */ public List findByDTOUseConstructor(){ Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue()); return queryFactory.select( Projections.constructor(PersonIDCardDto.class, QPerson.person.name, QPerson.person.address, QIDCard.iDCard.idNo)) .from(QIDCard.iDCard, QPerson.person) .where(predicate) .fetch(); }
上面只是提供了几种思路,当然,还可以使用@QueryProjection来实现,非常灵活。
一对多示例:
package com.chhliu.springboot.jpa.repository; import java.util.List; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.chhliu.springboot.jpa.entity.QOrder; import com.chhliu.springboot.jpa.entity.QOrderItem; import com.querydsl.core.Tuple; import com.querydsl.core.types.Predicate; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; @Component public class OrderAndOrderItemManager { @Autowired @PersistenceContext private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct public void init() { queryFactory = new JPAQueryFactory(entityManager); } /** * Details:一对多,条件查询 */ public ListfindOrderAndOrderItemByOrderName(String orderName){ //添加查询条件 Predicate predicate = QOrder.order.orderName.eq(orderName); JPAQuery jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem) .from(QOrder.order, QOrderItem.orderItem) .where(QOrderItem.orderItem.order.id.intValue().eq(QOrder.order.id.intValue()), predicate); //拿到结果 return jpaQuery.fetch(); } /** * Details:多表连接查询 */ public List findAllByOrderName(String orderName){ //添加查询条件 Predicate predicate = QOrder.order.orderName.eq(orderName); JPAQuery jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem) .from(QOrder.order, QOrderItem.orderItem) .rightJoin(QOrder.order) .on(QOrderItem.orderItem.order.id.intValue().eq(QOrder.order.id.intValue())); jpaQuery.where(predicate); //拿到结果 return jpaQuery.fetch(); } }
链接
Querydsl Reference Guide
使用QueryDSL
复杂查询的封装
spring boot-jpa整合QueryDSL来简化复杂操作
Spring Boot JPA - 使用 Querydsl 处理复杂的操作