架构小白到砖家-08-【数据存储问题】-JpaSpecificationExecutor解决单表动态查询

接着上一篇的疑问,难道jpa真的就能无敌到能解决所有sql查询的情况吗?这次终于有否定的答案了,还是不行的。让我们在看看jpa怎么实现自动查询的。

	User findByRealName(String realName);
	User findByUsernameOrEmail(String username,String email);

可以看到我们是在接口中声明的方法,是的,也就是说这些查询条件在应用运行过程中,没法做到动态控制使用哪些查询条件。我们可以理解为jpa的这种查询只能应用在查询条件事先就确定并固定的场景中,另外查询条件不能太多。想象一下,如果有10个或者20个查询条件,查询方法的名称得有多长?

所以jpa还是提供了另外两种查询解决方案,第一个是JPQL,一种类似hibernate的HQL的查询语句;第二个是Specification,一种对象查询条件方式。

JPQL用法跟传统的SQL查询没什么区别,只是语法不一样而已,我们就在jpa的方法声明时,通过@Query就可以指定JQPL,不用jpa自动生成,并且还能有占位符的概念。我们就来看一个例子。

UserRepository文件中添加
在这里插入图片描述
在这里插入图片描述

这样就可以完成JPQL的简单使用。
我们还是重点来看看Specification的方式,那么先看看Specification是什么?打开源码,发现是一个接口。就一个toPredicate方法,返回的Predicate对象。
在这里插入图片描述

那么什么地方可以使用这个接口呢?通过源码发现SimpleJpaRepository就有方法。但是这两个方法是JpaSpecificationExecutor接口定义的,跟JpaRepository是两回事。
在这里插入图片描述
在这里插入图片描述

所以咱们UserRepository想要使用Specification的方法还需要继承JpaSpecificationExecutor,这样就可以直接使用了,那我们就来通过单元测试进行动态查询吧。

UserRepository 继承JpaSpecificationExecutor

public interface UserRepository extends JpaRepository<User, Long> ,JpaSpecificationExecutor<User>

单元测试添加
在这里插入图片描述
在这里插入图片描述

Specification接口使用匿名类的方式,实现了动态查询条件封装的工作,加上jpa默认自带的查询方法,能够轻松的解决动态查询的需求。这种方式从操作方式上,确实也是面向对象的思想,咱们不用直接跟SQL打交道。至少jpa真的能在日常开发工作中,让我们不用太多关心数据库知识,就能解决绝大多数的需求开发工作。

但是数据库的使用场景是非常多的,可能很多实践经验丰富的同学,已经细心的发现了,我们一直在讨论JPA对于单表的数据库操作。实际工作中,业务复杂度很高,业务模型需要进行数据分类,也是出于数据库效率因素考虑,常常需要多表操作。那么如何解决多表查询的问题呢?咱们也放到下一篇再进行讨论。

回顾总结,jpa在接口中声明查询方法的方式(JpaRepository),只能解决查询条件数量少并且固定的场景,没法根据实际需要,进行动态查询条件组合的场景。要解决动态查询问题,jpa提供了Specification的方案,咱们的接口需要继承JpaSpecificationExecutor,也是使用面向对象的操作方式封装查询条件。还有一种JPQL的方案,跟传统SQL其实没什么区别,当然它还是具备跨数据库的优点,但是如果真的使用到了JPQL,还不如直接使用原生SQL,免得增加大家的学习成本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值