spring-data-jpa原生sql查询

随着技术的发展,持久层框架也愈来愈趋于成熟,从Mybatis到JPA,新的技术都是使咱们使用起来更加方便简单.就拿 JPA来讲,因为JPA自带的方法能够知足大部分平常开发中的crud,因此深得程序员们的喜好,可是,有利就有弊.html

近日我在开发中就遇到了一个关于查询效率缓慢的问题.java

问题描述:

1.在开发环境有个业务,列表页加搜索框功能,而后列表中数据是使用JPA的findAll()方法查询2万数据,居然整整须要7s,JPA虽然好用简便,可是findall至关因而 SELECT * FROM tb where a,b,c,这种全表扫描效率低是确定的,并且是把表中全部字段都查了一遍,分页后依旧不是很快,可是业务中只须要几个字段而已,这其实就是极大的耗费资源.mysql

2.自定义sql语句下where条件该如何拼接而且判空,相似于mybatis的if null.程序员

3.自定义sql语句下如何进行分页.spring

解决方案:

1.此刻加索引确定是不行的,where条件并不固定(全部搜索框为空时是全查),因此就想到了利用JPA的@Query功能,将select * 替换为具体须要的字段,select a,b,c from tb,就是写原生sql语句,此时效率瞬间提升了很多,大概耗时1.2s,因此select * from tb 能不用则不用吧.性能问题解决了.sql

2.where条件的判空,就是当条件不为null时进行查询,结合google加实践我弄出了这个方法:mybatis

@Query(value = " select name,age,sex where if(?1!= '',name = ?1,1=1) and if(?2!= null,age = ?2,1=1)", nativeQuery = true)
 List<Object[]> countCase(String name, Integer age, String sex)
复制代码

if(?1 !='',name=?1,1=1) 表明传入的参数name若是不为""(String类型空是""而不是null)将参数传入name,若是为空时显示1=1 表明参数为真,对查询结果不产生做用,所传参数顺序有要求.框架

3.查看文档以后决定直接用JpaRepository 的 Pageable 来直接实现:性能

参考文档(Example 51. Declare native count queries for pagination at the query method using [@Query])google

(docs.spring.io/spring-data…)

@Query(value = " select name,age,sex where if(?1!= '',name = ?1,1=1) and if(?2!= null,age = ?2,1=1) /*#pageable*/",countQuery = "select count(*) where if(?1!= '',name = ?1,1=1) and if(?2!= null,age = ?2,1=1)",nativeQuery = true)
 Page<Object[]> countCase(String name, Integer age, String sex,Pageable pageable)
复制代码

countQuery用来获取总条数.

**/#pageable/**在此处时必须添加,推测是JPA可能须要pageable字符来使工程正常启动,若是不加则会启动发生异常.

以上仅限于mysql

相关文章
相关标签/搜索