Spring Data JPA

 

一、JPA概述及基本操作

1、ORM思想

  • ORM(Object-Relational Mapping) 表示对象关系映射。
  • 目的:通过操作实体类就可以对数据库表进行操作
  • 建立两个映射:
    • 实体类和表的映射
    • 实体类属性和表中字段的映射
  • 实现ORM思想的框架:Hibernate、mybatis

2、JPA的介绍

  • Hibernate封装jdbc,是一个orm关系对象映射框架,可以自动生成sql语句自动执行
  • JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范

 

 

 

 

 

 3、CRUD入门案例

  • 步骤
    • 坐标 
    • 配置文件resources/META-INF/persistence.xml
      • showsql/hbm2ddl.auto
    • 编写实体类
    • 配置映射关系
      • @GeneratedValue
      • @Id
      • @Column
    • 编写测试类,通过EntityManager实现保存

4、常用操作

  • 主键生成策略:IDENTITY(MySQL自增长,只需要这一种就可以)
  • JpaUtils工具类:静态代码块加载配置文件,提供方法直接获取实体管理器
  • 立即加载find与延迟加载getReference
  • 更新:先查询再merge,CRUD均需要创建事务对象

5、jpql查询

  • JPQL全称Java Persistence Query Language,查询的是实体类和类中属性
  • 实现操作:查询全部、分页查询、统计、条件查询(em.setParameter设置对应位置的参数)、排序
  • 调用em.createQuery(sql)得到Query对象调用getResultList/getSingleResult方法得到结果

二、Spring Data JPA

1、概述

  • 基于ORM框架&JPA规范封装的框架,dao中只需要写接口 
  • 与Hibernate的关系:底层调用了hibernate

 

 

 2、快速入门

  • 步骤
    • 搭建环境(配置文件、实体类注解配置映射)
    • 编写dao接口,实现JpaRepository,JpaSpecificationExecutor接口
  • 原理:创建动态代理对象、借助jpa完成操作、hibernate完成数据库操作

3、Spring Data JPA查询

  • 复杂查询:定义好的接口方法(findOne立即加载<em.find>、getOne<em.getReference>懒加载)、jpql查询使用Query注解配置到接口的方法上(占位符?1)、sql使用注解配置到dao的方法上(nativeQuery = true)、方法命名规则查询
  • 命名规则查询
    • 模糊匹配:Likes
    • 多条件查询:and/or

三、动态查询与多表操作

1、Specification动态查询

  • findOne/findAll/count的参数,用于设置查询条件
  • 查询单个对象、查询列表 List、分页查询返回Page对象
  • Specification匿名内部类实现toPredicate方法返回Predict对象
Specification<Customer> spec = new Specification<Customer>() {
   @Override
   public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
      return null;
   }};  
  • Predicate toPredicate(Root<T> var1【获取属性Path】, CriteriaQuery<?> var2【自定义查询对象,了解】, CriteriaBuilder var3【查询构造器】);
//多条件查询                
Predicate p1 = criteriaBuilder.equal(custName, "传智播客");
Predicate p2 = criteriaBuilder.equal(custIndustry, "IT教育");
Predicate and = criteriaBuilder.and(p1, p2); 
//以与的形式拼接多个查询条件

//模糊匹配
Path<Object> custName = root.get("custName");
//查询方式:模糊匹配
Predicate like = criteriaBuilder.like(custName.as(String.class), "传智播客%");

//排序
Sort sort = new Sort(Sort.Direction.DESC,"custId");
List<Customer> all = customerDao.findAll(spec,sort);

//分页
Pageable pageable = new PageRequest(0,2);
Page<Customer> page = customerDao.findAll(null, pageable);
System.out.println(page.getContent()); //得到数据集合列表
System.out.println(page.getTotalElements()); //得到总条数
System.out.println(page.getTotalPages()); //得到总页数

2、多表操作

  • 一(主表)对多(从表),多对多(中间表,联合主键) 
  • 分析步骤
    • 明确表关系
    • 确定表关系
    • 编写实体类,描述表关系
    • 配置映射关系

3、一对多操作(客户与联系人)

  • 新建List集合,设置OneToMany和JoinColumn注解
  • 配置文件注入Hibernate配置信息(hibernate.hbm2ddl.auto为create或update)
  • 保存时需要对多的一方list.add:customer.getLinkMans().add(linkMan);
  • 放弃外键维护:@OneToMany(mappedBy = "customer")
  • 级联操作(主体配置)
@OneToMany(mappedBy = "customer",cascade = CascadeType.ALL)
    private Set<LinkMan> linkMans = new HashSet<>();

4、多对多操作(用户和角色)

  • 设置联合主键
@ManyToMany(targetEntity = Role.class)
    @JoinTable(name = "sys_role_user",
            //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<>();
  • 另一方放弃维护权
@ManyToMany(mappedBy = "roles") //对方配置的属性名称
    private Set<User> users = new HashSet<>();

5、对象导航查询

  • 查询一个对象时,可以通过此对象查询其关联对象
  • Set<LinkMan> linkMans = customer.getLinkMans();
  • 延迟加载:Customer customer = customerDao.findOne(1L);
  • 关联对象加载设置(不推荐)
     /* fetch配置关联对象的加载方式
     *      EAGER:立即加载
     *      LAZY:延迟加载
     */
    @OneToMany(mappedBy = "customer",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    private Set<LinkMan> linkMans = new HashSet<>();
  • 总结:
    • 一查多,默认延迟加载
    • 多查一,默认立即加载
posted @ 2021-04-06 23:13  哥们要飞  阅读(56)  评论(0编辑  收藏  举报