SpringBoot Data JPA
第一章
第一 orm思想
主要目的:操作实体类就相当于操作数据库
建立两个映射关系:
实体类和表中的映射关系
实体类中属性和表中字段映射关系
不在重点关注:sql语句
实现ORM思想的框架:mybatis,hibernate
第二 Hibernate
Hibernate是一个开放源码代码的对象代码的对象关系映射框架,它对JDBC进行了轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架
第三 JPA规范
jpa规范,实现jpa规范,内部是由接口和抽象类组成
第四 JPA的基本操作
案例:是客户的相关操作
客户:就是一家公司
客户表:
jpa的操作步骤:
- 加载配置文件创建实体管理器工厂
Persisitence:静态方法(根据持久化单元名称创建实体管理器工厂)
createEntutyManagerFactory(持久化单元名称)
作用:创建实体管理器工厂
- 根据实体管理器工厂,创建实体管理器
EntityManagerFactory:获取EntityManager对象
方法:createEntityManager
*内部维护的很多的内容
内部维护了数据库信息
维护了缓存信息
维护了所有实体管理器对象
再创建EntityManagerFactory的过程中会根据配置创建数据库表
*EntityManagerFactory的创建过程比较浪费资源
特点:线程安全的对象
多个线程访问同一个EntityManagerFactory不会有线程安全问题
*如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
思路:创建一个公共的EntityManagerFactory的对象
*静态代码块的形式创建EntityManagerFactory
- 创建事务对象,开启事务
EntityManager对象:实体类管理器
beginTransaction:创建事务对象
presist:保存
merge:更新
remove:删除
find/getRefrence:根据id查询
Transcation对象:事务
begin:开启事务
commit:提交事务
rollback:回滚事务
- 增删改查操作
- 提交事务
- 释放资源
i.搭建环境的过程
- 创建maven工程导入坐标
- 需要配置jpa的核心配置文件
*位置:配置到类路径下的一个叫做META-INF的文件夹下
*命名:persistence.xml
- 编写客户实体类
- 配置实体类和表,类中属性和表中字段的映射关系
- 保存客户到数据库中
ii.完成基本CRUD案例
presist:保存
merge:更新
remove:删除
find/getRefrence:根据id查询
iii.jpql查询
jpql全称Java Persisitence Query Language
基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询与语言(JPQL)是一种可移植的查询语言,旨在以面向对象表达语言的表达式,将SQL语法和简单查询语义绑在一起,使用这种语言编写的查询是可移植的,可以被编译成所有主流数据库服务器上的SQL。
其特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。
sql:查询的是表与表中的字段
jpql:查询的是实体类和类中的属性
*jpql和sql语句的语法相似
- 查询全部
/** * 查询全部: * jpql:from cn.itcast.domain.Customer * sql:SELECT * FROM 表名 */ @Test public void testFindAll(){ //获取EntityManager对象 EntityManager manager = JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction = manager.getTransaction(); transaction.begin(); //查询全部 String jpql="from cn.itcast.domain.Customer"; Query query = manager.createQuery(jpql); //发送查询,封装结果集 List list= query.getResultList(); for (Object obj:list){ System.out.println(obj); } //提交事务 transaction.commit(); //释放资源 manager.close(); }
- 分页查询
/** * 分页查询 * sql:select * from 表名 limit ?,? * jpql:from Customer */ @Test public void testPage(){ //获取EntityManager对象 EntityManager manager = JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction = manager.getTransaction(); transaction.begin(); //查询全部 //i.根据jpql语句创建Query查询对象 String jpql="from Customer "; Query query = manager.createQuery(jpql); //ii.对参数赋值——分页参数 //起始索引 query.setFirstResult(0); //每页查询条数 query.setMaxResults(2); //iii.发送查询,封装结果 /** * getResultList:直接将查询结果封装成list集合 * getSingleResult:得到唯一的结果集 */ Object result = query.getSingleResult(); System.out.println(result); //提交事务 transaction.commit(); //释放资源 manager.close(); }
- 统计查询
/** * 使用jpql查询,统计客户的总数 * sql:SELECT COUNT(cust_id)FROM 表名 * jpql:select count(id) from Customer */ @Test public void testCount(){ //获取EntityManager对象 EntityManager manager = JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction = manager.getTransaction(); transaction.begin(); //查询全部 //i.根据jpql语句创建Query查询对象 String jpql="select count(custId) from Customer "; Query query = manager.createQuery(jpql); //ii.对参数赋值 //iii.发送查询,封装结果 /** * getResultList:直接将查询结果封装成list集合 * getSingleResult:得到唯一的结果集 */ Object result = query.getSingleResult(); System.out.println(result); //提交事务 transaction.commit(); //释放资源 manager.close(); }
- 条件查询
/** * 条件查询 * 案例:查询客户名称以‘条件’开头的客户 * slq:SELECT * FROM 表名 WHERE 字段 LIKE ? * jpql:from Customer where custName like ? */ @Test public void testCondition(){ //获取EntityManager对象 EntityManager manager = JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction = manager.getTransaction(); transaction.begin(); //查询全部 //i.根据jpql语句创建Query查询对象 String jpql="from Customer where custName like ?"; Query query = manager.createQuery(jpql); //ii.对参数赋值——占位符参数 //第一个参数:占位符索引位置(从1开始),第二个参数:取值 query.setParameter(1,"条件%"); //iii.发送查询,封装结果 /** * getResultList:直接将查询结果封装成list集合 * getSingleResult:得到唯一的结果集 */ Object result = query.getSingleResult(); System.out.println(result); //提交事务 transaction.commit(); //释放资源 manager.close(); }
- 排序
/** * 排序查询:倒序查询全部客户(根据id倒序) * sql:SELECT * FROM 表名 ORDER BY id DESC * jpql:Customer order by * jpql查询: * 1.创建query对象 * 2.对参数进行复制 * 3.查询,并返回结果 */ @Test public void testOrder(){ //获取EntityManager对象 EntityManager manager = JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction = manager.getTransaction(); transaction.begin(); //查询全部 String jpql="from Customer order by custId desc "; //创建Query查询对象,query对象才是jpql的对象 Query query = manager.createQuery(jpql); //发送查询,封装结果集 List list= query.getResultList(); for (Object obj:list){ System.out.println(obj); } //提交事务 transaction.commit(); //释放资源 manager.close(); }
延迟加载与立即加载:
/** * 根据id查询客户 * 使用find方法查询: * 1.查询的对象就是当前客户对象本身 * 2.在调用find方法的时候,就会发送sql语句查询数据库 */ @Test public void testFind(){ //通过工具类获取entityManager EntityManager entityManager=JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction= entityManager.getTransaction(); transaction.begin(); //增删改查 /** * find:根据id查询数据 * class:查询数据的结果需要包装的实体类类型的字节码 * id:查询主键的取值 * 立即加载 */ Customer customer=entityManager.find(Customer.class,1l); System.out.println(customer); //提交事务 transaction.commit(); //释放资源 entityManager.close(); }
/** * 根据id查询客户 * getReference方法: * 1.获取对象是一个动态代理对象 * 2.调用getReference方法不会立即发送sql语句查询数据库 * *当调用查询结果对象的时候,才会发送查询的sql语句:什么时候用,什么时候发送sql语句查询数据库 */ @Test public void testReference(){ //通过工具类获取entityManager EntityManager entityManager=JpaUtils.getEntityManager(); //开启事务 EntityTransaction transaction= entityManager.getTransaction(); transaction.begin(); //增删改查 /** * getReference:根据id查询数据 * class:查询数据的结果需要包装的实体类类型的字节码 * id:查询主键的取值 * 延迟加载(懒加载) * *得到的是一个动态代理对象 * *什么时候用,什么时候才会查询 */ Customer customer=entityManager.getReference(Customer.class,1l); System.out.println(customer); //提交事务 transaction.commit(); //释放资源 entityManager.close(); }
第二章
第一 springDateJpa的概述
第二 springDateJpa的入门操作
案例:客户基本CRUD
i.搭建环境
创建工程导入坐标
配置spring的配置文件(配置springtatajpa的整合)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>untitled1</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <spring.version>5.2.12.RELEASE</spring.version> <hibernate.version>5.2.16.Final</hibernate.version> <log4j.version>1.2.17</log4j.version> <slf4j.version>1.7.30</slf4j.version> </properties> <dependencies> <!-- junit单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <!-- spring beg--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- spring对orm框架的支持包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <!-- spring-end--> <!-- hibernate beg--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.1.Final</version> </dependency> <!-- hibernate end--> <!-- c3p0 beg--> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!-- c3p0 end--> <!-- log end--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <!-- log end--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.9.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.2</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> </dependencies> </project>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> </beans>
编写实体类(customer),使用jpa注解配置映射关系
ii.编写一个符合springDataJpa的dao层接口
*只需要编写dao层接口,不需要编写dao层接口的实现类
*dao层接口实现规范
1.需要继承两个接口(JpaRepository,JpaSpecificationExecutor)
2. 需要提供响应的泛型
findOne(id):根据id查询
save(Customer):保存或者更新(依据:传递实体类对象中,是否包含id属性)
delete(id):根据id删除
findAll():查询全部
第三 springDateJpa
1.通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
2.SimpleJpaRepository当中封装了JPA的操作(借助JPA的api完成数据库的CRUD)
3.通过hibernate完成数据库操作(封装了jdbc)
第四 复杂查询
i.借助接口中定义好的方法完成查询
findOne(id):根据id查询
ii.jpql的查询方式
jpql:jpql query language
特点:语法或关键字和sql语句类似
查询的是类和类中的属性
*需要将JPQL语句配置到接口方法上
1.特有查询:需要在dao接口配置方法
2.在新添加的方法上:使用注解的形式配置jpql查询语句
3.注解:@Query
iii.sql语句的查询
1.特有的查询:需要在dao接口上配置方法
2.在新添加的方法上,使用注解的形式配置sql查询语句
3.注解:@Query
value:jpql语句 | sql语句
nativeQuery:false(使用jpql查询)| true(使用本地查询) 是否使用本地查询
iiii.方法名称规则查询
*是对jpql查询,更加深入的一层封装,
*我们只需要按照SpringDataJpa提供的方法名称规则定义方法,不需要再配置jpql语句,完成查询
*
findBy:代表查询
对象中属性的名称(首字母大写)
*含义:根据属性名称进行查询
第三章 Specifications动态查询
第一 Specifications动态查询
JpaSpecificationExecutor方法列表:
T findOne(Specification var1); //查询大哥对象 List<T> findAll(Specification<T> var1); //查询列表 //查询全部,分页 //Pageable:分页参数 //返回值:分页pageBean(page:是springDataJpa提供) Page<T> findAll(Specification<T> var1, Pageable var2); //查询列表 //Sort:排序参数 List<T> findAll(Specification<T> var1, Sort var2); long count(Specification<T> var1);//统计查询
*Specification:查询条件
自定义我们自己的Specification实现类
实现
//Root:查询的根对象(查询的任何属性都可以从根对象中获取) //CriteriaQuery:顶层查询对象,自定义查询方式(了解:一般不用) //CriteriaBuilder:查询的构造器,封装了很多的查询条件 Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);//封装查询条件
第二 多表之间的关系和操作多表的操作步骤/
表关系
一对一
一对多:
一的一方:主表
多的一方:从表
外键:需要再从新表上新建一列作为外键,他的取值来源于主表的主键
多对多:
中间表:中间表最少应该有两个字段组成,这两个字段作为外键指向两张表的主键,又组成了联合主键
讲师对学员:一对多关系
实体类中的关系
包含关系:可以通过实体类中的包含关系描述表关系
继承关系
分析步骤:
1.明确表关系
2.确定表关系:(描述 外键|中间表)
3.编写实体类,在实体类中描述表关系(包含关系)
4.配置映射关系
第三 完成多表操作
i.一对多操作
分析步骤:
1.明确表关系
2.确定表关系:(描述 外键|中间表)
3.编写实体类,在实体类中描述表关系(包含关系)
4.配置映射关系
*使用jpa注解配置一对多映射关系
级联:
操作一个对象的同时操作他的关联对象
级联操作:
1.需要区分操作主体
2.需要操作主体的实体类上,添加级联属性(需要添加到多表映射关系的注释上)
3.cascade(配置级联)
级联添加,
案例:当我保存一个客户的同时保存联系人
级联删除
案例:当我删除一个客户同时删除此客户的所有联系人
ii.多对多操作
案例:用户和角色(多对多关系)
用户:
角色:
分析步骤:
1.明确表关系
多对多关系
2.确定表关系:(描述 外键|中间表)
中间表
3.编写实体类,在实体类中描述表关系(包含关系)
用户:包含角色的集合
角色:包含用户的集合
4.配置映射关系
iii.多表的查询
1.对象导航查询
查询一个对象的同时,通过此对象查询他的关联对象
从一方查询多方
*默认延迟加载
从多方查询一方
*默认使用立即加载