美文网首页
QueryDsl使用

QueryDsl使用

作者: 伟_4649 | 来源:发表于2020-03-17 16:22 被阅读0次
使用jpa的一些困扰
  • 一对多,多对一,多对多的关系要不要建立?
  • 返回类型Object[]数组,至于每一个下标对应哪个字段,没法直观的看到,例如object[11]是什么类型?字段名是什么?这个就无法直观得知.
  • jpql/native sql中复杂的关系导致不可维护,每一个接手的人都要研究sql半天
  • 该种动态拼接条件方法导致类似的代码会大量重复,所以IDEA打开的时候黄了半边天
  • 该查询为分页查询,这样写的话,还要再copy一个count查询才能拿到总数,无疑又是代码重复
  • JPA这种框架目的就是少些原生sql语句,大量这样的操作的话,还不如使用dbUtil这样的工具类查询
QueryDsl简介

QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。
Querydsl可以通过一组通用的查询API为用户构建出适合不同类型ORM框架或者是SQL的查询语句,也就是说QueryDSL是基于各种ORM框架以及SQL之上的一个通用的查询框架。
借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建查询。目前QueryDSL支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
官网地址 : 点击进入

配置到项目

pom.xml 引入依赖 加入插件,用于生成查询实例Q类

<dependencies>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
        </dependency>
</dependencies>
<plugins>
        <plugin> <!--因为QueryDsl是类型安全的,所以还需要加上Maven APT plugin,使用 APT 自动生成Q类:-->
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
</plugins>

实体Bean配置了@Entity被检测到之后,就会在target的子目录中自动生成一个Q+实体名称的类,这个类对我们使用QueryDSL非常重要,正是因为它,我们才使得QueryDSL能够构建类型安全的查询。

修改代码
  • 在启动类中添加如下代码
    /**
     * 让Spring管理JPAQueryFactory
     */
    @Bean
    public JPAQueryFactory jpaQueryFactory(EntityManager entityManager){
        return new JPAQueryFactory(entityManager);
    }
  • 修改Repository类
@Repository
public interface CustomerRepository extends JpaRepository<Customer, String>, QuerydslPredicateExecutor<Customer>
QueryDsl大于等于,小于等于

大于等于 :goe,小于等于:loe

predicate = StringUtils.isEmpty(param.getParam().get("start")) ? predicate : ExpressionUtils.and(predicate, qMonthcheckplan.start.goe(DateUtils.str2day(param.getParam().get("start").toString())));
predicate = StringUtils.isEmpty(param.getParam().get("end")) ? predicate : ExpressionUtils.and(predicate, qMonthcheckplan.end.loe(DateUtils.str2day(param.getParam().get("end").toString())));
查询并分页
  • 简单分页
Pageable pageable = PageRequest.of(query.getPage() - 1, query.getSize());
Predicate predicate = customer.isNotNull().or(customer.isNull());
predicate = query.getBirthdayBegin() == null ? predicate : ExpressionUtils.and(predicate, customer.birthday.goe(query.getBirthdayBegin()));
predicate = query.getBirthdayEnd() == null ? predicate : ExpressionUtils.and(predicate, customer.birthday.loe(query.getBirthdayEnd()));
Page<Customer> pageData = customerRepository.findAll(predicate, pageable);
List<CustomerVO> customers = new ArrayList<>();
pageData.getContent().forEach(x -> {
    CustomerVO customerVO = CustomerVO.builder().build();
    BeanUtils.copyProperties(x, customerVO);
    customers.add(customerVO);
});
return Result.ok(customers, pageData.getTotalElements());
  • 条件分页
    QCustomer QCustomerOrder:是编译出来的实体
    jpaQuery :根据条件查询出来的集合
    customers :根据前台传来的进行分页操作
    .fetch():相当于.get() 可看出返回类型
QCustomer customer = QCustomer.customer;
QCustomerOrder order = QCustomerOrder.customerOrder;

Pageable pageable = PageRequest.of(query.getPage() - 1, query.getSize());

//组合搜索客户的条件,初始化组装条件(类似where 1=1)
Predicate predicate = customer.isNotNull().or(customer.isNull());
predicate = StrUtil.isBlank(query.getCustomerName()) ? predicate : ExpressionUtils.and(predicate, customer.name.like(FnaUtils.parseLike(query.getCustomerName())));
predicate = StrUtil.isBlank(query.getGender()) ? predicate : ExpressionUtils.and(predicate, customer.gender.eq(query.getGender()));
predicate = query.getBirthdayBegin() == null ? predicate : ExpressionUtils.and(predicate, customer.birthday.goe(query.getBirthdayBegin()));
predicate = query.getBirthdayEnd() == null ? predicate : ExpressionUtils.and(predicate, customer.birthday.loe(query.getBirthdayEnd()));
predicate = StrUtil.isBlank(query.getIdType()) ? predicate : ExpressionUtils.and(predicate, customer.idType.eq(query.getIdType()));
predicate = StrUtil.isBlank(query.getIdNo()) ? predicate : ExpressionUtils.and(predicate, customer.idNo.like(FnaUtils.parseLike(query.getIdNo())));

//组合搜索客户订单的条件,初始化组装条件(类似where 1=1)
Predicate predicate2 = order.isNotNull().or(order.isNull());
predicate2 = StrUtil.isBlank(query.getOrderNo()) ? predicate2 : ExpressionUtils.and(predicate2, order.orderNo.like(FnaUtils.parseLike(query.getOrderNo())));
predicate2 = StrUtil.isBlank(query.getAddress()) ? predicate2 : ExpressionUtils.and(predicate2, order.address.like(FnaUtils.parseLike(query.getAddress())));

JPAQuery<Customer> jpaQuery = jpaQueryFactory.selectFrom(customer).where(predicate);
if (StrUtil.isNotBlank(query.getOrderNo()) || StrUtil.isNotBlank(query.getAddress())) {
    jpaQuery.where(customer.customerId.in(
            jpaQueryFactory.select(order.customerId).from(order).where(predicate2))
    );
}
List<CustomerVO> customers = jpaQuery.offset(pageable.getOffset()).limit(pageable.getPageSize()).fetch().stream().map(x -> {
    CustomerVO customerVO = CustomerVO.builder().build();
    BeanUtils.copyProperties(x, customerVO);
    return customerVO;
}).collect(Collectors.toList());
long count = jpaQuery.fetchCount();
return Result.ok(customers, count);

相关文章

网友评论

      本文标题:QueryDsl使用

      本文链接:https://www.haomeiwen.com/subject/vkwtyhtx.html