Spring Data JPA

##1、Spring Data JPA的概述

1.1 Spring Data JPA概述

Spring Data JPA_第1张图片

Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!

Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦

1.2 Spring Data JPA的特性

Spring Data JPA_第2张图片

SpringData Jpa 极大简化了数据库访问层代码。 如何简化的呢? 使用了SpringDataJpa,我们的dao层中只需要写接口,就自动具有了增删改查、分页查询等方法。

1.3 Spring Data JPA 与 JPA和hibernate之间的关系

JPA是一套规范,内部是有接口和抽象类组成的。hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式,我们使用JPA的API编程,意味着站在更高的角度上看待问题(面向接口编程)

Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。

2、Spring Data JPA的快速入门

2.1需求说明

  • Spring Data JPA完成客户的基本CRUD操作

2.2搭建Spring Data JPA的开发环境

2.2.1 引入Spring Data JPA的坐标

使用Spring Data JPA,需要整合Spring与Spring Data JPA,并且需要提供JPA的服务提供者hibernate,所以需要导入spring相关坐标,hibernate坐标,数据库驱动坐标等


	
        5.0.2.RELEASE
        5.0.7.Final
        1.6.6
        1.2.12
        0.9.1.2
        5.1.18
    

    
        
        
            junit
            junit
            4.12
            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.2.2 整合Spring Data JPA与Spring





    

	 
    
        
        
        
        
    
    
    
    
        
        
        
        
        
        
            
        
        
        
            
				
                
                
                
                
                
            
        
        
        
            
        
    

    
    
        
    
    

    
    

    
    

  

2.2.3 使用 JPA 注解配置映射关系

import javax.persistence.*;

/**
 * 客户实体类
 */
@Entity
@Table(name="cst_customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="cust_id")
    private Long custId;

    @Column(name="cust_name")
    private String custName;

    @Column(name="cust_source")
    private String custSource;

    @Column(name="cust_level")
    private String custLevel;

    @Column(name="cust_industry")
    private String custIndustry;

    @Column(name="cust_address")
    private String custAddress;

    @Column(name="cust_phone")
    private String custPhone;

	// 省略 setter and getter 及 toString 方法

}

2.3 使用 Spring Data JPA 完成需求

2.3.1 编写符合 Spring Data JPA 规范的 Dao 层接口


import com.domain.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

/**
 * 创建符合SpringDataJpa规范的接口:  约定优于配置
 *      1、继承JpaRepository,并写上相应的泛型   : 增删改查
 *              *第一个泛型:我们要操作的实体类
 *              *第二个泛型:主键属性的数据类型
 *      2、继承JpaSpecificationExecutor,并写上相应的泛型   : 复杂查询,动态查询
 *              *只有一个泛型: 就是我们操作的实体类
 *
 *
 *  SpringDataJpa中的查询:
 *
 *  1、dao接口中定义的方法
                 save和delete
                 findAll();查询所有
                 findOne(id);查询一个对象:立即查询
				 
                 getOne(id); 查询一个对象:延迟加载
	                 @Transactional
						* 为了测试延迟加载,这个测试方法上需要加上一个事务注解:只是为了去掉no session异常
						* 调用的是EntityManager.getReference();
						
                 count();查询总记录数
				 
                 exists(id的值);查询对象是否存在,true存在,false不存在
						     * 判断一个实体是否存在: exists方法
							 *      1、发送根据id查询语句,如果查出来不为空,就代表存在,反之不存在
							 *              select * from cst_customer where cust_id = ?
							 *      2、发送统计查询语句,统计有几条,如果大于0,就代表存在这条数据,反之不存在
							 *              select count(*) from cst_customer where cust_id = ?
							 *
							 * SpringDataJpa用那种?看控制它发送的sql语句就可以了,我们测试发送,Spring用的是第二种
							 *      1、调用的是exists方法,传入的id主键值
							 *      2、返回的是布尔类型:
							 *              true: 存在
							 *              false:不存在

 2、JPQL查询
                 JPA Query Language : jpa查询语言
                 需要写JPQL:
                     1、把sql中的表名换成实体类的名称
                     2、把sql中的字段名换成实体类中属性的名称

                 SpringDataJpa中使用jpql查询注意点:
                     1、需要在我们的接口中编写方法
                     2、在这个方法上使用注解:@Query,此注解中的value属性出入的就是jpql语句
                     3、如果是【更新】操作:除了加入Query之外还需要一个@Modifying注解
                     4、测试更新的时候需要加入事务和回滚的注解,只是为了测试
                             @Transactional
                             @Rollback(false)
     *
								* 1、在测试更新的时候,需要用到一个注解:@Transactional : 加入这个注解只是为了让程序不报错
								* 2、加入了@Transactional注解后,程序不报错,但是数据没有更新
								* 3、默认的情况下,我们在service层使用到是声明式事务,可以正常去更新数据,但是现在我们没有service层,所以需要加入另外一个注解
								*         @Rollback : 默认情况下我们没有service的时候,执行完之后,会回滚
								*              value: true 回滚
								*              value: false 不回滚


 3、SQL查询【了解】
            @Query注解:
  *              value属性:写的sql语句
  *              nativeQuery:
  *                      true: sql查询
  *                      false: jpql查询【默认值】

 4、方法名规则查询
            1)编写dao中的方法,编写有规则的
            2)方法名以 findBy开头
            3)findBy后面跟上的是 对象的属性名称,首字母大写

 5、动态查询

 */
public interface CustomerDao extends JpaRepository,JpaSpecificationExecutor{

//================== 2、JPQL查询 ==================================
    /**
     * 查询所有客户
     * @return
     */
    @Query("from Customer")
    public List findJPQL();


    /**
     * JPQL的条件查询:精确匹配
     */
    @Query("from Customer where custName = ?")
    public Customer findJPQL2(String n);

    /**
     * JPQL的条件查询:模糊查询
     */
    @Query("from Customer where custName like ?")
    public List findJPQL3(String n);

    /**
     * JPQL的多条件查询
     * 默认情况下: 方法中的参数有索引:从1开始,    占位符可以指定索引
     *    ?1  获取的是方法参数列表中的第一个参数
     *    ?2  获取的是方法参数列表中的第二个参数
     *
     */
    @Query("from Customer where custName like ?2 and custId = ?1")
    public List findJPQL4(Long id ,String n);


    /**
     * 需求:只修改客户的名称
     *
     * 使用JPQL来执行
     *      需要用到两个注解:
     *          @Query里面写入的是update的语句
     *          @Modifying 告诉框架我们进行的是一个修改操作
     */
    @Query("update Customer set custName = ?2 where custId = ?1")
    @Modifying
    public void updateCustomerName(Long id,String name);

//================== 3、SQL查询【了解】 ==================================
    /**
     * sql查询:
     *      @Query注解:
     *              value属性:写的sql语句
     *              nativeQuery:
     *                      true: sql查询
     *                      false: jpql查询【默认值】
     *
     */
    @Query(value="select * from cst_customer where cust_name like ?2 and cust_id = ?1",nativeQuery = true)
    public List findsql(Long id,String name);
	

//================== 4、方法名规则查询【推荐】==================================

    /**
     * 根据方法名查询:
     *          findByCustName : 根据客户名称精确查询
     */
    public List findByCustName(String name);

    /**
     * 根据方法名查询:
     *          findByCustName + Like  : 根据客户名称模糊查询
     */
    public List findByCustNameLike(String name);


    /**
     * 根据方法名查询:多条件
     *          findByCustName + Like  +  And | Or  + 对象的属性名称,首字母大写 + [Like ]
     */
    public List findByCustNameLikeAndCustId(String name,Long id);


}

SpringDataJpa原理分析

1、注入的dao的实现类:代理对象,JDKDynamicAopProxy
2、代理对象实现InvocationHandler接口,此接口中有invoke方法
3、此方法中调用具体dao的实现类:target = SimpleJpaRepository
4、底层完成的增删改查都是SimpleJpaRepository来完成
5、此类实现implements JpaRepository, JpaSpecificationExecutor接口
6、我们调用customerDao.findOne(1L);方法底层其实就是调用SimpleJpaRepository的findOne
7、findOne的方法中调用:em.find(domainType, id);
8、em到底是谁?
它就是jpa规范中的实体类管理器

SpringDataJpa其实就是JPA规范封装

补充资料:

实例详解Spring Data JPA的使用
https://blog.csdn.net/l1357852347/article/details/73718700#t6

你可能感兴趣的:(笔记)