一、pom 依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.18.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.27</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
二、java
1.配置文件
新建配置文件 resources/META-INF/persistence.xml
<?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
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="myjpa">
<!-- jpa的实现产品 -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- 数据库连接配置 -->
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:5432/postgres"/>
<property name="javax.persistence.jdbc.user" value="postgres"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<!-- hibernate的配置 -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
2.实体类
1) @Entity:标注在实体类名上。标识为jpa实体类
2) @Table:标注在实体类名上。把该实体类映射到实际的表名,这个其实是非必需的,但一般实体类的名字和表名都不一样,所以认为就是必需的
@Setter
@Getter
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// @GeneratedValue(strategy = GenerationType.SEQUENCE)
// @GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
}
3.测试类
@Test
public void testPersist() {
/**
* 通过 Persistence 获取 EntityManagerFactory, 传入参数对应配置文件中持久化单元 persistence-unit的name
* 通过 EntityManagerFactory 创建 EntityManager 获取 EntityTransaction 开启事务
*/
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student stu = new Student(null, "stu1");
// 转换为托管状态
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
// PERSISTENT, TRANSIENT, DETACHED, DELETED
// TRANSIENT 到 PERSISTENT
entityManager.persist(stu);
stu.setName("stu2");
entityManager.persist(stu);
/**
* 提交事务 关闭entityManager 关闭entityManagerFactory
*/
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
@Test
public void testMerge1() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student stu = new Student(null, "stu1");
// 转换为托管状态
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
// 由于实体类状态不是托管状态,所以merge之后 改变实体类值并不会自动同步数据,但merge会返回一个托管状态的实体类
entityManager.merge(stu);
stu.setName("stu2");
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
@Test
public void testMerge2() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student stu = new Student(null, "stu1");
// 返回托管状态的实体类
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
// 由于实体类状态不是托管状态,所以merge之后 改变实体类值并不会自动同步数据,但merge会返回一个托管状态的实体类
Student newStudent = entityManager.merge(stu);
newStudent.setName("stu2");
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
@Test
public void testFind() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 返回托管状态的实体类
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
Student student = entityManager.find(Student.class, 1);
student.setName("stu2");
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
@Test
public void testDetach() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 返回托管状态的实体类
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
Student student = entityManager.find(Student.class, 1);
// 变成游离态
entityManager.detach(student);
// clear 也可以,是把整个上下文中托管态的都变成游离态,所以要慎用
// entityManager.clear();
student.setName("stu2");
// 能提交到数据库,但 student 依然是游离态
entityManager.merge(student);
// 无法自动更新数据
student.setName("stu3");;
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
@Test
public void testDetach1() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 返回托管状态的实体类
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
Student student = entityManager.find(Student.class, 1);
// 变为游离态
entityManager.detach(student);
// 游离态不能 persist
// javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: org.example.entity.Student
entityManager.persist(student);
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
@Test
public void testRemove() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 返回托管状态的实体类
// 只要事务不提交,数据库中的数据可以随时跟随托管状态实体类的值变化
Student student = entityManager.find(Student.class, 1);
// 通过 persist,删除态再次变为托管态,此时提交事务就不会删除了
entityManager.persist(student);
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
四、其他
瞬时态(Transient):指新创建的实体对象,没有被赋值 ID,也未与任何 EntityManager 关联
它的状态依然取决于它是否与持久化上下文(通过 EntityManager)关联。
瞬时态(Transient):如果你新创建了一个实体对象,并手动设置了其 ID 值,但在将其传递给 EntityManager 进行管理之前,这个对象仍然是瞬时态。这意味着该对象并未与数据库中的任何记录关联,JPA 不会认为它是数据库中已存在实体的一部分。