1.简介:
本篇文章记录在使用Querydsl-JPA过程中遇到一些问题,坑,大家在以后使用过程中再遇到这些问题时可少浪费一些时间.
2.问题:
2.1:分页问题:spring-data-jpa与query-dsl-jpa的分页区别:
2.1.1: 在使用spring-data-jpa处理分页时我们可以这么写:通过spring-data提供的PageRequest分页类处理,此处我们无需进行计算,提供查询页码以及分页的数量即可完成。
public void getUserListByPageSpringData() {
int pageNum = 1;
int pageSize = 2;
User user = new User();
user.setAge(10);
Example<User> of = Example.of(user);
Page<User> all = userDao.findAll(of, PageRequest.of(pageNum - 1, pageSize));
List<User> content = all.getContent();
long totalElements = all.getTotalElements();
String contentStr = JSON.toJSONString(content);
System.out.println("spring-data-jpa 分页查询年龄为10的结果:"+contentStr);
}
查看源码PageRequest继承的抽象类AbstractPageRequest为我们进行了计算:

2.1.2: 在使用query-dsl-jpa处理分页时,jpaQueryFactory分别提供了offset和 limit方法:此处需要我们进行计算处理。
public void getUserListByPage() {
int pageNo = 1;
int pageSize = 10;
int pageNumber = (pageNo-1)*pageSize;
QUser user = QUser.user;
QueryResults<User> userQueryResults =
jpaQueryFactory.selectFrom(user).offset(pageNumber).limit(pageSize).fetchResults();
String userQueryResultsStr = JSON.toJSONString(userQueryResults);
System.out.println("单表分页的结果集:"+userQueryResultsStr);
}
2.2. 查询扩展字段时怎么处理(该扩展字段一直属性)?
import com.querydsl.core.types.dsl.Expressions;
String infoId = "filed01";
StringPath field = Expressions.stringPath(qArBillExpense, infoId);
List<ArBillExpense> expenses = jpaQueryFactory.selectFrom(qArBillExpense).leftJoin(qArBill).on(qArBill.id.eq(qArBillExpense.billId))
.where(field.eq(identityCode), qArBill.isIncomeHistory.eq(ArConstant.YES), qArBill.billType.eq("EXP_INCOMETAX"), qArBillExpense.expenseType.eq("LABOR_OTHER"))
.fetch();
2.3. queryDsl 两个表关联,关联的字段类型不一样,编译不通过怎么办?
import com.querydsl.core.types.dsl.Expressions;
Expression sourceCode = qArSysDataSource.sourceCode;
NumberExpression numberExpression = Expressions.asNumber(sourceCode);
jpaQueryFactory.selectFrom(qArBill).leftJoin(qArSysDataSource).on(qArBill.billStatus.eq(numberExpression))
2.4. 对条件里的的字段做字符拼接怎么处理?
如下这张图,用Querydsl-JPA实现下面的条件字段的字符串拼接:(我的场景是判断用户输入的号码是否在数据库存在,用户输入的格式为:No111,No222,数据库存的也是该格式,但是我要检验No111是否存在?)
拼接的时候会出现编译不通过,类型不匹配。
可以折中处理,使用模糊查询的方式:代码如下:
import com.querydsl.core.BooleanBuilder;
QArBill qArBill = QArBill.arBill;
QArBillExpense qArBillExpense = QArBillExpense.arBillExpense;
BooleanBuilder booleanBuilder = new BooleanBuilder();
booleanBuilder.and(qArBillExpense.invoiceNo.isNotNull());
BooleanBuilder invoiceNoBuilder = new BooleanBuilder();
for (String invoiceNo : invoiceNos) {
invoiceNoBuilder.or(qArBillExpense.invoiceNo.startsWith(invoiceNo.concat(",")));
invoiceNoBuilder.or(qArBillExpense.invoiceNo.contains((",").concat(invoiceNo).concat(",")));
invoiceNoBuilder.or(qArBillExpense.invoiceNo.endsWith((",").concat(invoiceNo)));
invoiceNoBuilder.or(qArBillExpense.invoiceNo.eq(invoiceNo));
}
booleanBuilder.and(invoiceNoBuilder);
List<ArBillInvoiceCheckVo> arBillList = jpaQueryFactory.select(Projections.bean(ArBillInvoiceCheckVo.class,
qArBill.inputor.as("inputor"), qArBill.billNo.as("billNo"), qArBillExpense.invoiceNo.as("invoiceNo"))).from(qArBill).join(qArBillExpense)
.on(qArBill.id.eq(qArBillExpense.billId))
.where(booleanBuilder).fetch();
装载后的sql语句如下图:


