A. orm思想和hibernate以及jpa的概述和jpa的基本操作
B. SpringDataJPA 的运行原理以及基本操作
C. 多表操作,复杂查询
1.orm思想
- 主要目的:操作实体类就相当于操作数据库表
- 建立两个映射关系:
- 实体类和表的映射关系
- 实体类中属性和表中字段的映射类型 - 不再重点关注:sql语句
- 实现了ORM思想的框架:mybatis,hibernate
2.Hibernate框架介绍
Hibernate是一个开放源代码的对象关系映射框架。
- 它对JDBC进行了非常轻量级的对象封装。
- 它将POJO与数据库表建立映射关系,是一个全自动的orm框架。
3.JPA规范
JPA规范,实现jpa规范,内部是由接口和抽象类组成
4.jpa的基本操作
- 案例:对客户的相关操作(增删改查)
客户:就是一家公司 - 客户表:
jpa操作的操作步骤:- 加载配置文件创建实体管理器工厂
Persistence:静态方法(根据持久化单元名称创建实体管理器工厂)
作用:创建实体管理器工厂 - 根据实体管理器工厂,创建实体管理器
EntityManagerFactory:获取EntityManager对象
方法:createEntityManager
* 内部维护了很多的内容
内部维护了数据库信息,
维护了缓存信息,
维护了所有的实体管理器对象,
在创建EntityManagerFactory的过程中会根据配置创建数据库表
* EntityManagerFactory的创建过程比较浪费资源
特点:线程安全的对象
多个线程访问同一个EntityManagerFactory不会有线程安全问题
* 如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
思路:创建一个公共的EntityManagerFactory的对象
* 静态代码块的形式创建EntityManagerFactory - 创建事务对象,开启事务
EntityManagerFactory对象:实体类管理器
beginTransaction:创建事务对象
presist:保存
merge:更新
remove:删除
find/getRefrence:根据id查询
Transaction对象:事务
begin:开启事务
commit:提交事务
rollback:回滚 - 增删改查操作
- 提交事务
- 释放资源
- 加载配置文件创建实体管理器工厂
- 搭建环境的过程
- 创建maven工程导入坐标
- 需要配置jpa的核心配置文件
*位置:配置到类路径下的一个叫做META-INF的文件夹下
*命名:persistence.xml - 编写客户的实体类
- 配置实体类和表,类中属性和表中字段的映射关系
- 保存客户到数据库中
- 完成基本CRUD案例
- persist:保存
- merge:更新
- remove:删除
- find/getRefrence:根据id查询
- JPQL查询
sql:查询的是表和表中的字段
jpql:查询的是实体类和类中的属性- 查询全部
- 分页查询
- 统计查询
- 条件查询
5.SpringDataJPA的入门操作
- 案例:客户的基本CRUD
- 搭建环境
- 创建工程导入坐标
- 配置spring的配置文件(配置springDataJpa的整合)
- 编写实体类(Customer),使用jpa注解配置映射关系
- 编写一个符合springDataJpa的dao层接口
- 只需要编写dao层接口,不需要编写dao层接口的实现类
- dao层接口规范
- 需要继承两个接口
(JpaRepository<操作的实体类类型,实体类中主键的类型>,JpaSpecificationExecutor<操作的实体类类型>)
第一个接口:封装了基本的CRUD操作
第二个接口:封装了复杂查询(分页)
- 需要提供相应的泛型 - findOne(id):根据id查询
save(customer):保存或者更新(依据:传递的实体类型对象中,是否包含id属性)
delete(id):根据id删除
findAll():查询全部
6.SpringDataJPA的运行过程和原理剖析
- 通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
- SimpleJpaRepository当中封装了JPA的操作(借助JPA的api完成数据库的CRUD)
- 通过Hibernate完成数据库操作(封装了jdbc)
7.复杂查询
- 借助接口中的定义好的方法完成查询
findOne(id):根据id查询 - jpql的查询方式
- jpql:jpa query language() (jpa查询语言)
- 特点:语法或关键字和sql语句类似
查询的是类和类中的属性 - 需要将JPQL语句配置到接口方法上
- 特有的查询:需要在dao接口上配置方法
- 在新添加的方法上,使用注解的形式配置jpql查询语句
- 注解:@Query
- sql语句的查询
- 特有的查询:需要在dao接口上配置方法
- 在新添加的方法上,使用注解的形式配置sql查询语句
- 注解:@Query
- value:jpql语句 | sql语句
- nativeQuery:false(使用jpql查询) | true(使用本地查询:sql查询)
- 方法名称规则查询
- 对jpql查询,更加深入的一层封装。
- 我们只需要按照SpringDataJpa提供的方法名称规则定义方法,不需要再去配置jpql语句,完成查询。
8.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); - List<T> findAll(Specification<T> spec,Sort sort); //查询列表 sort:排序参数
- long count(Specification<T> spec,); //统计查询
- Specification:查询条件
- 自定义我们自己的Specification实现类
实现
//root:查询的根对象(查询的任何属性都可以从根对象中获取)
//CriteriaQuery:顶层查询对象,自定义查询方式(了解:一般不用)
//CriteriaBuilder:查询的构造器,封装了许多的查询条件
Predicate toPredicate(Root<T> root,CriteriaQuery query,CriteriaBuilder cb); //封装查询条件
- 自定义我们自己的Specification实现类
9.多表之间的关系和操作多表的操作步骤
- 表关系
- 一对一
- 一对多
- 一的一方:主表
- 多的一方:从表
- 外键:需要在从表上新建一列作为外键,他的取值来源于主表的主键 - 多对多
- 中间表:中间表中最少应该由两个字段组成,这两个字段作为外键指向两张表的主键,又组成了联合主键。
- 实体类中的关系
- 包含关系
- 继承关系
- 分析步骤
- 明确表关系
- 确定表关系(描述 外键 | 中间表)
- 编写实体类,在实体类中描述表关系(包含关系)
- 配置映射关系
10.完成多表操作
- 一对多操作
- 案例:客户和联系人的案例
客户:一家公司
联系人:这家公司的员工
一个客户可以具有多个联系人
一个联系人从属于一家公司 - 分析步骤
- 明确表关系
一对多的关系 - 确定表关系(描述 外键 | 中间表)
主表:客户表
从表:联系人表 - 编写实体类,在实体类中描述表关系(包含关系)
客户:在客户的实体类中包含一个联系人的集合
联系人:在联系人的实体类中包含一个客户的对象 - 配置映射关系
使用jpa注解配置一对多映射关系
- 明确表关系
- 级联
- 操作一个对象的同时操作他的关联对象
- 级联操作:
需要区分操作主体
需要在操作主体的实体类上,添加级联属性(需要添加到多表映射的注解上)
cascade(配置级联) - 级联添加:
案例:当我保存一个客户的同时保存联系人 - 级联删除:
案例:当我删除一个客户的同时删除此客户的所有联系人
- 案例:客户和联系人的案例
- 多对多操作
- 案例:用户和角色(多对多关系)
用户:
角色: - 分析步骤
- 明确表关系
多对多的关系 - 确定表关系(描述 外键 | 中间表)
中间表 - 编写实体类,在实体类中描述表关系(包含关系)
用户:包含角色的集合
角色:包含用户的集合 - 配置映射关系
- 明确表关系
- 案例:用户和角色(多对多关系)
- 多表的查询
- 对象导航查询
查询一个对象的同时,通过此对象查询他的关联对象
案例:客户和联系人
从一方查询多方
默认:使用延迟加载
从多方查询一方
默认:使用立即加载
- 对象导航查询