Spring Data JPA

本文介绍了Spring Data JPA,它是Spring提供的数据持久化解决方案,基于JPA规范。内容涵盖JPA环境搭建,实体类与表的映射,JPA操作步骤,如保存、更新、删除等。还探讨了Spring Data JPA的高级特性,包括Specifications动态查询,JpaSpecificationExecutor方法,以及多表关系分析和级联操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JPA概述

JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。JPA规范不干活,真正干活的是依托与它的实现方式(例:hibernate)。


搭建环境(需求:保存客户)

1.创建maven工程导入坐标


        <!-- hibernate对jpa的支持包 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
		</dependency>
		

2.需要配置jpa的核心配置文件
*位置:配置到类路径下的一个叫做 META-INF 的文件夹下
*命名:persistence.xml

   persistence.xml相关配置
   <!--需要配置persistence-unit节点
            持久化单元:
                name:持久化单元名称
                transaction-type:事务管理的方式
                       JTA:分布式事务管理
                       RESOURCE_LOCAL:本地事务管理
    
    -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!--Jpa实现方式-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <properties>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
        

        <!--配置jpa实现方(hibernate)的配置信息
                显示sql           :   false|true
                自动创建数据库表    :  hibernate.hbm2ddl.auto
                        create      : 程序运行时创建数据库表(如果有表,先删除表再创建)
                        update      :程序运行时创建表(如果有表,不会创建表)//常用
                        none        :不会创建表

            -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>

    </persistence-unit>

3.编写实体类,配置实体类和表,类中属性和表中字段的映射关系
注:使用注解完成实体类和表的映射关系,实体类中属性和表中字段的映射关系

/**
 *   1.实体类和表的映射关系
 *      @Entity:声明实体类
 *      @Table : 配置实体类和表的映射关系
 *          name属性 : 配置数据库表的名称
 *   2.实体类中属性和表中字段的映射关系
 *
 * @Id:声明主键的配置
 * @GeneratedValue:配置主键的生成策略
 *      strategy
 *          GenerationType.IDENTITY :自增,mysql
 *                 * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
 *          GenerationType.SEQUENCE : 序列,oracle
 *                  * 底层数据库必须支持序列
 * @Column:配置属性和字段的映射关系
 *      name:数据库表中字段的名称
 * 		unique:是否唯一  
 *      nullable:是否可以为空 
 */
@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_phone")
    private String custPhone;
    @Column(name = "cust_address")
    private String custAddress;
}

Jpa的操作步骤

EntityManager对象方法:实体类管理器
em.clear(): 把对象从缓存中清除出去
getTransaction : 获取事务对象
presist : 保存
merge : 更新
remove : 删除
find(立即加载)/常用getRefrence(延迟加载):根据id查询

        //1.加载配置文件创建工厂(实体管理器工厂)(线程安全的一个工厂对象,创建过程比较浪费资源,可以通过静态代码块进行创建)
        // 定义对象
		Customer c = new Customer();
		c.setCustName("旅行者");
		c.setCustIndustry("IT教育");
		EntityManagerFactory factory =  null;
		EntityManager em = null;
		EntityTransaction tx = null;
		try {
			// 获取实体管理对象
			factory = Persistence.createEntityManagerFactory("myJpa");
			//通过实体管理器工厂获取实体管理器
			em = factory.createEntityManager();
			// 获取事务对象
			tx = em.getTransaction();
			// 开启事务
			tx.begin();
			// 执行操作
			em.persist(c);
			// 提交事务
			tx.commit();
		} catch (Exception e) {
			// 回滚事务
			tx.rollback();
			e.printStackTrace();
		} finally {
			// 释放资源
			em.close();
			factory.close();
		}


Spring Data JPA概述

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

Spring Data JPA搭建环境
i.搭建环境
1.创建工程导入坐标
2.配置spring的配置文件(配置spring Data jpa的整合)
3.编写实体类(Customer),使用jpa注解配置映射关系


    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>1.9.0.RELEASE</version>
     </dependency>
     <!-- el beg 使用spring data jpa 必须引入 -->
     <dependency>  
          <groupId>javax.el</groupId>  
          <artifactId>javax.el-api</artifactId>  
          <version>2.2.4</version>  
      </dependency>  
          
      <dependency>  
          <groupId>org.glassfish.web</groupId>  
          <artifactId>javax.el</artifactId>  
          <version>2.2.4</version>  
      </dependency> 
      <!-- el end -->
      

ii.编写一个符合springDataJpa的dao层接口
* 只需要编写dao层接口,不需要编写dao层接口的实现类
dao层接口规范
1.需要继承两个接口(JpaRepository,JpaSpecificationExecutor)
2.需要提供响应的泛型

Spring Data JPA常用方法:
findOne(id) :根据id查询
save(customer):保存或者更新(依据:传递的实体类对象中,是否包含id属性)
delete(id) :根据id删除
findAll() : 查询全部

springDataJpa的 运行过程原理剖析
在这里插入图片描述

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

简单说就是SpringDataJpa根据动态代理帮我们创建了代理对象,代理对象调用Jpa的api,又因为Jpa不能完成对数据库的具体操作,底层由hibernate来完成对数据库的crud操作。
在这里插入图片描述

jpql查询:
sql:查询的是表和表中的字段
jpql:查询的是实体类和类中的属性

Specifications动态查询介绍

JpaSpecificationExecutor 方法列表

        T findOne(Specification<T> spec);  //查询单个对象

		List<T> findAll(Specification<T> spec);  //查询列表

		//查询全部,分页
		//pageable:分页参数
		//返回值:分页pageBean(page:是springdatajpa提供的)
		Page<T> findAll(Specification<T> spec, Pageable pageable);

		//查询列表
		//Sort:排序参数
		List<T> findAll(Specification<T> spec, Sort sort);

		long count(Specification<T> spec);//统计查询
		
	* Specification :查询条件
		自定义我们自己的Specification实现类
			实现
				//root:查询的根对象(查询的任何属性都可以从根对象中获取)
				//CriteriaQuery:顶层查询对象,自定义查询方式(了解:一般不用)
				//CriteriaBuilder:查询的构造器,封装了很多的查询条件
				Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); //封装查询条件

表关系的分析步骤

第一步:首先确定两张表之间的关系。
第二步:在数据库中实现两张表的关系
第三步:在实体类中描述出两个实体的关系
第四步:配置出实体类和数据库表的关系映射(重点)

多表操作中常用的注解:

@OneToMany:
   	作用:建立一对多的关系映射
    属性:
    	targetEntityClass:指定多的多方的类的字节码
    	mappedBy:指定从表实体类中引用主表对象的名称。
    	cascade:指定要使用的级联操作
    	fetch:指定是否采用延迟加载
    	orphanRemoval:是否使用孤儿删除

@ManyToOne
    作用:建立多对一的关系
    属性:
    	targetEntityClass:指定一的一方实体类字节码
    	cascade:指定要使用的级联操作
    	fetch:指定是否采用延迟加载
    	optional:关联是否可选。如果设置为false,则必须始终存在非空关系。

@JoinColumn
     作用:用于定义主键字段和外键字段的对应关系。
     属性:
    	name:指定外键字段的名称
    	referencedColumnName:指定引用主表的主键字段名称
    	unique:是否唯一。默认值不唯一
    	nullable:是否允许为空。默认值允许。
    	insertable:是否允许插入。默认值允许。
    	updatable:是否允许更新。默认值允许。
    	columnDefinition:列的定义信息。
@ManyToMany
	作用:用于映射多对多关系
	属性:
		cascade:配置级联操作。
		fetch:配置是否采用延迟加载。
    	targetEntity:配置目标的实体类。映射多对多的时候不用写。

@JoinTable
    作用:针对中间表的配置
    属性:
    	nam:配置中间表的名称
    	joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段			  			
    	inverseJoinColumn:中间表的外键字段关联对方表的主键字段
    	
@JoinColumn
    作用:用于定义主键字段和外键字段的对应关系。
    属性:
    	name:指定外键字段的名称
    	referencedColumnName:指定引用主表的主键字段名称
    	unique:是否唯一。默认值不唯一
    	nullable:是否允许为空。默认值允许。
    	insertable:是否允许插入。默认值允许。
    	updatable:是否允许更新。默认值允许。
    	columnDefinition:列的定义信息。

级联:
操作一个对象的同时操作他的关联对象
级联操作:
1.需要区分操作主体
2.需要在操作主体的实体类上,添加级联属性(需要添加到多表映射关系的注解上)
3.cascade(配置级联)

在一对多中,主表实体类应包含一个从表实体的集合引用,从表实体类中应包含主表实体的一个对象引用。
主表实体类:
 /**
     * 使用注解的形式配置多表关系
     *      1.声明关系
     *          @OneToMany : 配置一对多关系
     *              targetEntity :对方对象的字节码对象
     *      2.配置外键(中间表)
     *              @JoinColumn : 配置外键
     *                  name:外键字段名称
     *                  referencedColumnName:参照的主表的主键字段名称
     * 放弃外键维护权
     *      mappedBy:对方配置关系的属性名称\
     * cascade : 配置级联(可以配置到设置多表的映射关系的注解上)
     *      CascadeType.all         : 所有
     *                  MERGE       :更新
     *                  PERSIST     :保存
     *                  REMOVE      :删除
     *
     * fetch : 配置关联对象的加载方式
     *          EAGER   :立即加载
     *          LAZY    :延迟加载

     */
    /*@OneToMany(targetEntity = LinkMan.class)
    @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")*/
    @OneToMany(mappedBy = "customer",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
从表实体类:
 /**
     * 配置联系人到客户的多对一关系
     *     使用注解的形式配置多对一关系
     *      1.配置表关系
     *          @ManyToOne : 配置多对一关系
     *              targetEntity:对方的实体类字节码
     *      2.配置外键(中间表)
     */
    @ManyToOne(targetEntity = Customer.class)
    @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
    private Customer customer;


在多对多中,双方实体类中应包含对方的一个实体类的集合引用。
/**
     * 配置用户到角色的多对多关系
     *      配置多对多的映射关系
     *          1.声明表关系的配置
     *              @ManyToMany(targetEntity = Role.class)  //多对多
     *                  targetEntity:代表对方的实体类字节码
     *          2.配置中间表(包含两个外键)
     *                @JoinTable
     *                  name : 中间表的名称
     *                  joinColumns:配置当前对象在中间表的外键
     *                      @JoinColumn的数组
     *                          name:外键名
     *                          referencedColumnName:参照的主表的主键名
     *                  inverseJoinColumns:配置对方对象在中间表的外键
     */
    @ManyToMany(targetEntity = Role.class,cascade = CascadeType.ALL)
    @JoinTable(name = "sys_user_role",
            //joinColumns,当前对象在中间表中的外键
            joinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "user_id")},
            //inverseJoinColumns,对方对象在中间表的外键
            inverseJoinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")}
    )
    private Set<Role> roles = new HashSet<Role>();


/*@ManyToMany(targetEntity = User.class)
    @JoinTable(name = "sys_user_role",
            //joinColumns,当前对象在中间表中的外键
            joinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")},
            //inverseJoinColumns,对方对象在中间表的外键
            inverseJoinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "user_id")}
    )*/
    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<User>();
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值