目录
ORM 思想
JPA 规范
JPA 的基本操作(入门案例)
JPAUtils 工具类
测试 增删改查
Spring DATA JPA 概述
ORM 关系映射
操作实体类,就像是在操作数据库表
简历两个映射关系
实体类和表的映射关系
实体类中属性和表中字段的映射关系
实现了ORM思想的框架:MyBatis 、Hibernate
JPA 基于ORM 思想的规范 本身是不干活 是底下的一些实现方式(Hibernate。。。)去去干活
JPA和hibernate的关系 就像是 JDBC 与 JDBC 驱动的关系
1、搭建环境
(1)创建maven工程
<dependencies> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- hibernate对jpa的支持包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.4.10.Final</version> </dependency> <!-- c3p0 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.4.2.Final</version> </dependency> <!-- log日志 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.12.1</version> </dependency> <!-- Mysql and MariaDB --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> </dependencies>(2) 配置JPA的核心配置文件
使用命名空间的话 我们需要一个总配置文件persistence.xml存储框架需要的信息 (注意,文件名不要写错,而且必须放在classpath/META-INF文件夹里面)
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <!--需要配置persistence-unit节点 持久化单元: name:持久化单元名称 transaction-type:事务管理的方式 JTA:分布式事务管理 RESOURCE_LOCAL:本地事务管理 --> <persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL"> <!--jpa的实现方式--> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <!--可选配置:配置jpa实现方式的配置信息--> <properties> <!-- 数据库信息 用户名,javax.persistence.jdbc.user 密码, javax.persistence.jdbc.password 驱动, javax.persistence.jdbc.driver 数据库地址 javax.persistence.jdbc.url --> <property name="javax.persistence.jdbc.user" value="root"/> <property name="javax.persistence.jdbc.password" value="xmyabc"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/> <!--配置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> </persistence>hibernate.hbm2ddl.auto 的 参数如下
create : 程序运行时创建数据库表 如果有表删除表
update : 程序运行时创建表 如果有表不会创建表
none : 不会创建表
2、创建实体类
3、实体类搭建好过后 要实现 操作实体类就像是操作数据库中的表
实现映射关系
实体类和数据库中的表的映射关系
表中的属性和数据库中字段的映射关系
package com.xmy.entity; import javax.persistence.*; /** * @author pangxie * @data 2020/10/8 11:38 * 客户的实体类 * 1、实体类和表的映射关系 * @Entity 声明这个实体类是一个实体 * @Table name 数据库表的名称 * * 2、实体类中属性和表中字段的映射关系 */ @Entity @Table(name = "customer") public class Customer { /** * @Id 声明主键的注解 * @GeneratedValue(strategy = GenerationType.IDENTITY) 声明主键生成策略(自动生成) * @Column(name = "custId") 配置属性和字段名称的映射 name 字段名称 */ @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; public Long getCustId() { return custId; } public void setCustId(Long custId) { this.custId = custId; } public String getCustName() { return custName; } public void setCustName(String custName) { this.custName = custName; } public String getCustSource() { return custSource; } public void setCustSource(String custSource) { this.custSource = custSource; } @Override public String toString() { return "Customer{" + "custId=" + custId + ", custName='" + custName + '\'' + ", custSource='" + custSource + '\'' + '}'; } }在测试类中测试
JPA 的操作步骤
1、加载配置文件创建工厂(实体管理类工厂)对象
2、通过实体管理类工厂获取实体管理器
3、开启事务
4、完成操作
5、提交事务
6、释放资源
package com.jpa.test; import com.xmy.entity.Customer; import org.junit.Test; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; /** * @author pangxie * @data 2020/10/8 11:51 */ public class Test01 { /** * 测试JPA 的保存 */ @Test public void testSave(){ //1、加载配置文件创建工厂 EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJPA"); //2、通过实体管理器工厂获取实体管理器 EntityManager manager = factory.createEntityManager(); //3、获取事务对象 开启事务 EntityTransaction tx = manager.getTransaction(); tx.begin();//开启事务 //4、操作 Customer customer = new Customer(); customer.setCustName("小向"); customer.setCustSource("莫名的地方"); //保存 manager.persist(customer); //5、提交事务 tx.commit(); //6、释放资源 manager.close(); factory.close(); } }测试成功
数据库截图
为了减少实体管理器工厂浪费资源
package com.xmy.util; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; /** * @author pangxie * @data 2020/10/8 15:56 * * 解决 实体管理器工厂浪费资源 * 通过静态代码块的形式 当程序第一次访问此工具类时 创建一个公共的实体管理器工厂对象 * * 第一次访问getEntityManager方法 经过静态代码块创建一个 factory 对象 在调用方法创建一个EntityManager对象 * 第二次访问getEntityManager方法 直接通过一个已经创建好的factory对象 创建EntityManager对象 */ public final class JPAUtil { //JPA 的实体管理器工厂 private static EntityManagerFactory em; //使用静态代码块赋值 static { //参数名字必须要和 persistence-unit 中的 name 属性一致 em = Persistence.createEntityManagerFactory("myJPA"); } //使用管理器工厂生产一个管理器对象 public static EntityManager getEntityManager(){ return em.createEntityManager(); } }根据 id 查询用户还有一个 getReference 方法 和 find 方法非常类似
@Test public void testReference(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); /** * class 查询数据的结果需要包装的实体类类型的字节码 * id 查询主键的取值 */ Customer customer = manager.getReference(Customer.class,1l); System.out.println(customer); tx.commit(); manager.close(); }两个方法的区别:
find 方法 :1、查询的对象就是当前客户对象本身 2、在调用find方法的时候就会发送sql语句
getReference 方法: 1、获取的对象是一个动态代理对象 2、当调用查询结果对象的时候,才会发送sql语句。什么时候用什么时候才能用。
删除
/** * 删除 */ @Test public void testRemove(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); /** * 根据id查询客户 * 调用remove方法完成删除操作 */ Customer customer = manager.find(Customer.class,3l); manager.remove(customer); tx.commit(); manager.close(); }更新
/** * 更新 */ @Test public void testUpdate(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); /** * 查询客户 * 更新客户 */ Customer customer = manager.find(Customer.class,1l); customer.setCustSource("石头缝"); manager.merge(customer); tx.commit(); manager.close(); }使用 JPQL 查询
JPQL(Java持久性查询语言)是一种面向对象的查询语言,用于对持久实体执行数据库操作。 JPQL不使用数据库表,而是使用实体对象模型来操作SQL查询。
查询全部
/** * 查询全部 */ @Test public void testFindAll(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); /** * 查询全部 */ String jpql = "from Customer "; Query query = manager.createQuery(jpql); //创建Query对象 query对象才是执行jpql的对象 //发送查询 并封装结果集 List list = query.getResultList(); for (Object obj: list) { System.out.println(obj); } tx.commit(); manager.close(); }排序查询(倒序查询)
/** * 倒序查询 * SQL select * from cust order by cust_id DESC * JPQL from Customer order by custId desc */ @Test public void testOrders(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); /** * 查询全部 */ String jpql = "from Customer order by custId desc"; Query query = manager.createQuery(jpql); //创建Query对象 query对象才是执行jpql的对象 //发送查询 并封装结果集 List list = query.getResultList(); for (Object obj: list) { System.out.println(obj); } tx.commit(); manager.close(); }倒序查询结果
查询总共的数量
/** * 查询总共 * SQL select count(cust_id) from customer * JPQL select count(custId) from Customer */ @Test public void testCount(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); String jpql = "select count(custId) from Customer"; Query query = manager.createQuery(jpql); //创建Query对象 query对象才是执行jpql的对象 //发送查询 并封装结果集 getResultList 直接将查询结果封装为List // List list = query.getResultList(); // for (Object obj: list) { // System.out.println(obj); // } Object result = query.getSingleResult(); System.out.println(result); tx.commit(); manager.close(); }分页查询
/** * 分页查询 * SQL select * from customer limit .. * JPQL from Customer */ @Test public void testPage(){ EntityManager manager = JpaUtil.getEntityManager(); EntityTransaction tx = manager.getTransaction(); tx.begin(); String jpql = "from Customer"; Query query = manager.createQuery(jpql); //创建Query对象 query对象才是执行jpql的对象 //对参数赋值 //起始索引 query.setFirstResult(0); //每页查询的条数 query.setMaxResults(2); //发送查询 并封装结果集 getResultList 直接将查询结果封装为List List list = query.getResultList(); for (Object obj: list) { System.out.println(obj); } tx.commit(); manager.close(); }分页查询两条数据
是Spring 基于 ORM框架、JPA规范基础上的一套JPA应用框架 封装JPA的一套框架
