Spring data jpa@query使用原生SQl,需要注意的坑

原文地址: https://blog.csdn.net/weixin_38608626/article/details/83183556

根据代码来解说:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Query(value = "select bill.id_ as id, bill.created_date as date, bill.no, lawyer_case .case_no as caseNo, " +
"lawyer_case .case_name as caseName, customer.no as customerNo, customer.cn_name as customerName, " +
"bill.total_expense_after_tax, bill.collected_money, bill.book_ticket_amount, bill.version " +
"e1.name as creator, bill.status" +
"from bill " +
"left join lawyer_case on lawyer_case .case_no=bill.case_no " +
"left join customer on customer.no=bill.customer_no " +
"left join employee e1 on e1.id_=bill.creator " +
"where IF (?1!='', customer_no=?1, 1=1) " +
"and IF (?2!='', case_no=?2, 1=1) " +
"and IF (?3!='', status=?3, 1=1) " +
"and IF (?4!='', creator'%',?4,'%')), 1=1) " +
"and create_by=?5 " +
"ORDER BY ?#{#pageable} ",
countQuery = "select count(*) " +
"from bill " +
"left join lawyer_case on lawyer_case .case_no=bill.case_no " +
"left join customer on customer.no=bill.customer_no " +
"left join employee e1 on e1.id_=bill.creator " +
"where IF (?1!='', customer_no=?1, 1=1) " +
"and IF (?2!='', case_no=?2, 1=1) " +
"and IF (?3!='', status=?3, 1=1) " +
"and IF (?4!='', creator'%',?4,'%')), 1=1) " +
"and create_by=?5 "+
"ORDER BY ?#{#pageable} ",
nativeQuery = true)
Page<Object[]> findAllBill(String customerNo, String caseNo, Integer status, String creator,
String createBy, Pageable pageable);

需要注意的方法有以下几点:

1
2
3
4
5
6
7
8
1. From 不支持重命名.
2. 返回的是一个page<Object[]>,数组中只保存了数据,没有对应的key,只能根据返回数据的顺序,依次注入到DTO中。
3. 对于使用分页,需要:“ORDER BY ?#{#pageable}”,可以直接传入一个pageable对象,会自动解析。
4. 注意格式问题,很多时候就是换行的时候,没有空格。
5. 仔细对应数据库中表字段,很多时候报某个字段找不到,就是因为字段名写错,和数据库中对应不上。
6. 这是解决使用微服务,大量的数据都需要远程调用,会降低程序的性能。
7. 使用Pageabel作为参数的时候,去进行分页。刚开始的时候,觉得还是一个可行的办法,但是得注意的时候,当需要排序的时候,是无法加入sort字段的。 会一直报错left*。
8. 针对7的解决方案,把原生SQL的数据查询和countQuery分成两个查询方法。得到count,然后进行判断,若是等于0,则直接返回空集合;反之,则取获取数据。 需要自己进行分页计算,传入正确的pageNumber和pageSize。 大部分系统都是按照修改时间进行降序排序。 所以,order by可以写死。然后pageNumber和pageSize动态传入。 pageNumber的算法= (pageNumber - 1) * pageSize, 前提是PageNumber是从1开始,若0,则pageNumber=pageNumber * PageSize; 这样就可以保证数据的正确。
1
2
3
4
5
6
7
8
9
/**
* pageInfos: 转换之后的数据。
* pageable:传入的pageable.
* totalPage: 第一条SQL算好的返回值。
* 这样就可以统一的返回各种pageDTO。
*/
private Page<T> convertForPage(List<T> pageInfos, Pageable pageable, Integer totalPage) {
return new PageImpl<>(pageInfos, pageable, totalPage);
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2023 高行行
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信