SpringDataJPA入门及四种查询方式
发布日期:2021-06-29 11:14:40 浏览次数:3 分类:技术文章

本文共 6867 字,大约阅读时间需要 22 分钟。

SpringDataJPA 与 JPA 和 Hibernate 之间的关系

在说它们之间的关系之前,先说一说 JPA 和 Hibernate。JPA 是 SUN 公司推出的一套基于 ORM 的规范,内部由一系列的接口和抽象类构成。而 Hibernate 是实现了 JPA 规范的框架,它封装了 JDBC,可以对数据库进行操作。SpringDataJPA 是 对 JPA 规范的进一步封装,它并没有实现 JPA 的操作,而真正对数据的增删改查还是要依赖 Hibernate 等框架。下面这一张图诠释了它们之间的关系:

在这里插入图片描述
我们在代码中使用的是 SpringDataJPA 提供给我们的方法,SpringDataJPA 封装了 JPA,它的方法中还需要调用 JPA 规范中定义的方法,而 JPA 是一些接口和抽象类,所以最终还是需要依赖 Hibernate 等实现了 JPA 规范的框架来对数据库进行操作。

SpringDataJPA快速入门(与Spring的整合)

1)首先需要导入坐标

要整合 Spring 和 SpringDataJPA,并且还需要提供 JPA 的服务提供者 HIbernate,所以需要导入 Spring、SpringDataJPA 相关坐标,Hibernate 相关坐标和数据库驱动坐标等。

4.2.4.RELEASE
5.0.7.Final
1.6.6
1.2.12
0.9.1.2
5.1.6
junit
junit
4.9
test
org.aspectj
aspectjweaver
1.6.8
org.springframework
spring-aop
${
spring.version}
org.springframework
spring-context
${
spring.version}
org.springframework
spring-context-support
${
spring.version}
org.springframework
spring-orm
${
spring.version}
org.springframework
spring-beans
${
spring.version}
org.springframework
spring-core
${
spring.version}
org.hibernate
hibernate-core
${
hibernate.version}
org.hibernate
hibernate-entitymanager
${
hibernate.version}
org.hibernate
hibernate-validator
5.2.1.Final
c3p0
c3p0
${
c3p0.version}
log4j
log4j
${
log4j.version}
org.slf4j
slf4j-api
${
slf4j.version}
org.slf4j
slf4j-log4j12
${
slf4j.version}
mysql
mysql-connector-java
${
mysql.version}
org.springframework.data
spring-data-jpa
1.9.0.RELEASE
org.springframework
spring-test
${
spring.version}
javax.el
javax.el-api
2.2.4
org.glassfish.web
javax.el
2.2.4

2)SpringDataJPA 与 Spring 整合

Spring 整合其他框架最繁琐的就是配置文件,所以接下来要在配置文件中写一些关于 SpringDataJPA 的配置。

3)用注解建立实体和数据库表的映射关系

此步骤省略
4)编写符合 SpringDataJPA 规范的 Dao 层接口
符合 SpringDataJPA 规范,就是需要接口 实现 JpaRepository 和 JpaSpecificationExecutor 接口

public interface CustomerDao extends JpaRepository
, JpaSpecificationExecutor

5)完成以上步骤之后,就可以使用定义好的 Dao 层接口完成基本的 CRUD 操作

@Testpublic void testFindOne(){
Customer customer = customerDao.findOne(3L); System.out.println(customer);}

SpringDataJPA的内部原理分析

1)疑问

在使用 SpringDataJPA 时,一般实现 JpaRepository 和 JpaSpecificationExecutor 接口,这样就可以使用这些接口中定义的方法,但是这些方法都只是一些声明,没有具体的实现方式,那么在 SpringDataJPA 中它又是怎么实现的呢?

2)实现过程

我们以debug断点调试的方式,通过分析 SpringDataJPA 的源码来分析程序的执行过程,以上述的findOne方法为例进行分析

  • 代理子类的实现过程
    在这里插入图片描述
    断点执行到方法上时,我们可以发现注入的 customerDao 对象,本质上是通过 JdkDynamicAopProxy 生成的一个代理对象
  • 代理对象中方法调用的分析
    当程序执行的时候,会通过 JdkDynamicAopProxy 的 invoke 方法,对 customerDao 对象生成动态代理对象。根据对 SpringDataJPA 介绍而知,要想进行findOne查询方法,最终还是会出现JPA规范的API完成操作,那么这些底层代码存在于何处呢?答案很简单,都隐藏在通过 JdkDynamicAopProxy 生成的动态代理对象当中,而这个动态代理对象就是 SimpleJpaRepository
    在这里插入图片描述
    通过SimpleJpaRepository的源码分析,定位到了findOne方法,在此方法中,返回em.find()的返回结果,那么em又是什么呢?
    在这里插入图片描述
    带着问题继续查找 em 对象,我们发现 em 就是 EntityManager 对象,而他是 JPA 原生的实现方式,所以我们得到结论 SpringDataJPA 只是对标准 JPA 操作进行了进一步封装,简化了 Dao 层代码的开发

3)总结

SpringDataJPA 的执行过程是基于 JDK 的动态代理,1.通过 JdkDynamicAopProxy 的 invoke 方法创建了一个动态代理对象 SimpleJpaRepository;2.SimpleJpaRepository 当中封装了JPA的操作(借助JPA的api完成数据库的CRUD);3.通过 hibernate 完成数据库操作(封装了jdbc)

SpringDataJPA 的四种查询方式

1)使用 SpringDataJPA 中接口定义的方法进行查询

在继承了 JpaRepository 和 JpaRepository 接口后,我们就可以使用接口中定义的方法进行查询

  • save(customer):保存或者更新(依据传递的实体类对象中,是否包含id属性。如果不包含则保存;如果包含则更新【实际上更新之前先查询,只有查询到有数据,才会更新】)
  • delete(id):根据id删除
  • findAll():查询全部
  • findOne(id):根据id查询(调用的是 entityManager 的 find() 方法,是立即加载)
  • getOne(id):根据id查询(调用的是 entityManager 的 getRefrence() 方法,是延迟加载)

2)使用JPQL的方式查询

使用 SpringDataJPA 提供的查询方法已经可以解决大部分的应用场景,但是对于某些业务来说,我们还需要灵活的构造查询条件,这时就可以使用 @Query 注解,结合 JPQL 的语句方式完成查询
@Query 注解的使用非常简单,只需在方法上面标注该注解,同时提供一个JPQL查询语句即可

public interface CustomerDao extends JpaRepository
,JpaSpecificationExecutor
{
//@Query 使用jpql的方式查询。 @Query(value="from Customer") public List
findAllCustomer(); //@Query 使用jpql的方式查询。?1代表参数的占位符,其中1对应方法中的参数索引 @Query(value="from Customer where custName = ?1") public Customer findCustomer(String custName);}

此外,也可以通过使用 @Query 来执行一个更新操作,为此,我们需要在使用 @Query 的同时,用 @Modifying 来将该操作标识为修改查询,这样框架最终会生成一个更新的操作,而非查询

@Query(value="update Customer set custName = ?1 where custId = ?2")@Modifyingpublic void updateCustomer(String custName,Long custId);

3)使用 SQL 语句查询

Spring Data JPA同样也支持sql语句的查询,如下:

/** * nativeQuery : 使用本地sql的方式查询 */@Query(value="select * from cst_customer",nativeQuery=true)public void findSql();

4)使用 SpringDataJPA 提供的方法命名规则查询

顾名思义,方法命名规则查询就是根据方法的名字,就能创建查询。只需要按照Spring Data JPA提供的方法命名规则定义方法的名称,就可以完成查询工作。Spring Data JPA在程序执行的时候会根据方法名称进行解析,并自动生成查询语句进行查询。

按照Spring Data JPA 定义的规则,查询方法以findBy开头,涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。

//方法命名方式查询,不需要加 @Query 注解(根据客户名称查询客户)public Customer findByCustName(String custName);

具体的关键字,使用方法和生产成SQL如下表所示

在这里插入图片描述

转载地址:https://blog.csdn.net/zwj_jyzl/article/details/103945625 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:微服务鉴权之JWT
下一篇:Zookeeper集群

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月22日 20时16分26秒