一.导入JPA依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.hibernate.version>5.4.10.Final</project.hibernate.version>
</properties>
<dependencies>
<!-- hibernate对jpa的支持包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!--测试,日志 -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
二.编写JPA的核心配置文件
注意:配置文件的名要为persistence.xml,要放在src目录下的META-INF的文件夹下内.因为我们在创建实体管理器工厂时并没有写这个配置文件的名字或路径,我们使用的是持久化单元persistence-unit .JPA默认会到src/META-INF/persistence.xml中加载persistence-unit ,然后进行后续操作.我的配置文件位置如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="2.0">
<!--配置持久化单元
name:持久化单元名称
transaction-type:事务类型
RESOURCE_LOCAL:本地事务管理
JTA:分布式事务管理 .
jpa根据这个具有唯一标识的单元名称,即name属性值创建实体管理器工厂-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--配置JPA规范的实现提供商,也就是hibernate -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- 操作数据库的必须配置-->
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="123456" />
<!-- 低版本com.mysql.jdbc.Driver-->
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/db_springboot?characterEncoding=UTF-8" />
<!-- jpa规范实现者的hibernate的可选配置-->
<!-- 运行时打印sql-->
<property name="hibernate.show_sql" value="true"></property>
<!--配置运行时先删除表,还是在在原来表基础上操作
value:create,先删除原来的表再创建,再操作
value:update,在原来的表上操作,不删除表 -->
<property name="hibernate.hbm2ddl.auto" value="update"></property>
</properties>
</persistence-unit>
</persistence>
三.编写与数据库表相映射的实体类
import javax.persistence.*;
/**
* @author XiaoXin
* @date 2020/2/20 下午8:23
*/
@Entity//声明这是一个实体,相对应的数据库表名称为tb_employee
@Table(name = "tb_employee")
public class Employee {
@Id//声明主键,自增策略,同时指明数据表对应的字段为emp_id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private Integer id;
// 指明数据表对应的字段为emp_name
@Column(name = "emp_name")
private String name;
@Column(name = "emp_salary")
private Double salary;
public Employee() {
}
public Employee(String name, Double salary) {
this.name = name;
this.salary = salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
}
四.JPA的基本操作步骤
1.加载配置文件创建实体管理器工厂
Persisitence:静态方法(根据持久化单元名称创建实体管理器工厂)
createEntityMnagerFactory(持久化单元名称)
作用:创建实体管理器工厂
2.根据实体管理器工厂,创建实体管理器
EntityManagerFactory :获取EntityManager对象
方法:createEntityManager
* 内部维护的很多的内容
内部维护了数据库信息,
维护了缓存信息
维护了所有的实体管理器对象
再创建EntityManagerFactory的过程中会根据配置创建数据库表
* EntityManagerFactory的创建过程比较浪费资源
特点:线程安全的对象
多个线程访问同一个EntityManagerFactory不会有线程安全问题
* 如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
思路:创建一个公共的EntityManagerFactory的对象
* 静态代码块的形式创建EntityManagerFactory
3.创建事务对象,开启事务
EntityManager对象:实体类管理器
beginTransaction : 创建事务对象
presist : 保存
merge : 更新
remove : 删除
find/getRefrence : 根据id查询
Transaction 对象 : 事务
begin:开启事务
commit:提交事务
rollback:回滚
4.增删改查操作
5.提交事务
6.释放资源
当然,如果只是查询操作,就没有必要开启事务.
五.JPA的简易封装
注意,这里我把持久化单元的名称写死了,根据实际名称修改
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.EntityTransaction;
/**
* jpa工具类
* @author XiaoXin
* @date 2020/2/21 上午10:42
*/
public class JpaUtil {
private static final String JPAUnit = "myJpa";
public static EntityManagerFactory factory = null;
public static EntityManager manager = null;
public static EntityTransaction tx = null;
static {
factory = Persistence.createEntityManagerFactory(JPAUnit);
}
public static EntityManager getManager(){
manager = factory.createEntityManager();
return manager;
}
public static void close(EntityManager mg){
try {
if(mg!=null) mg.close();
if(factory!=null) factory.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
六.JPA的CRUD测试
import org.example.Employee;
import org.example.utils.JpaUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
/**
* JPA的简单增删该查测试
* @author XiaoXin
* @date 2020/2/21 上午10:45
*/
public class JPATest {
EntityManager manager = null;
EntityTransaction tx = null;
//初始化
@BeforeEach
public void init(){
manager= JpaUtil.getManager();
tx = manager.getTransaction();
}
//释放资源
@AfterEach
public void close(){
JpaUtil.close(manager);
}
@Test
public void testAdd(){
tx.begin();
Employee employee = new Employee("人生代代无穷已",123d);
manager.persist(employee);
tx.commit();
}
//测试删除
@Test
public void testDel(){
tx.begin();
//先查询再删除
Employee employee = manager.find(Employee.class,4);
manager.remove(employee);
tx.commit();
}
//测试修改
@Test
public void testUpdate(){
tx.begin();
//先查询再修改
Employee employee = manager.find(Employee.class,2);
//修改姓名
employee.setName("落霞与孤鹜齐飞,秋水共长天一色");
manager.merge(employee);
tx.commit();
}
//根据主键查询
@Test
public void testQuerySingle(){
//第一个参数为实体类,第一个参数为要查找的主键的值
Employee employee = manager.find(Employee.class,2);
System.out.println(employee);
}
}
七.部分运行结果截图
按id=2查询

修改后:

好了,jpa的简单操作就完成呢了
3985

被折叠的 条评论
为什么被折叠?



