本文主要介绍 JPA 的实际使用,相关的环境及软件信息如下:JPA 2.2(eclipselink 2.7.10、hibernate-entitymanager 5.6.10.Final、openjpa 3.2.2),JPA 3.0(eclipselink 3.0.2、hibernate-core-jakarta 5.6.10.Final)。
1、JPA 2.2 使用
工程目录结构如下:
1.1、引入依赖
这里使用 eclipselink 作为 JPA 的实现框架。
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.jpa</artifactId> <version>2.7.10</version> </dependency>
其他的依赖可自行引入,如数据库驱动、lombok 等。
1.2、创建实体类
1.2.1、Student.java
package com.abc.demojpa.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import javax.persistence.*; import java.time.LocalDateTime; @NoArgsConstructor @AllArgsConstructor @Data @Entity @Table(name = \"a_student\") @NamedQuery(name = \"queryAll\", query = \"select s from Student s\") public class Student { @Id @GeneratedValue private Long id; @Column(name = \"create_time\") private LocalDateTime createTime; @Column(name = \"modify_time\") private LocalDateTime modifyTime; private String name; private Integer age; @Column(name = \"home_address\") private String homeAddress; }
1.2.2、BaseEntity.java
package com.abc.demojpa.entity; import lombok.Data; import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import java.time.LocalDateTime; @Data //该类的属性都将映射到其子类的数据库字段中 @MappedSuperclass public class BaseEntity { @Id @GeneratedValue private Long id; @Column(name = \"create_time\") private LocalDateTime createTime; }
1.2.3、Teacher.java
Teacher 继承了 BaseEntity,主要为了测试属性的继承。
package com.abc.demojpa.entity; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; @NoArgsConstructor @Data @Entity @Table(name = \"a_teacher\") public class Teacher extends BaseEntity { private String name; private Integer age; }
1.3、编写 JPA 配置文件 (persistence.xml)
该配置文件需放在 META-INF 目录下。
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <persistence version=\"2.2\" xmlns=\"http://xmlns.jcp.org/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd\"> <persistence-unit name=\"myUnit\"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>com.abc.demojpa.entity.Student</class> <class>com.abc.demojpa.entity.Teacher</class> <properties> <property name=\"javax.persistence.jdbc.driver\" value=\"com.mysql.cj.jdbc.Driver\"/> <property name=\"javax.persistence.jdbc.url\" value=\"jdbc:mysql://10.49.196.10:3306/test?useUnicode=true&characterEncoding=UTF-8\"/> <property name=\"javax.persistence.jdbc.user\" value=\"root\"/> <property name=\"javax.persistence.jdbc.password\" value=\"123456\"/> <property name=\"eclipselink.logging.level\" value=\"INFO\" /> <property name=\"eclipselink.ddl-generation\" value=\"create-or-extend-tables\" /> </properties> </persistence-unit> </persistence>
eclipselink 开头的配置是 eclipselink 自带的扩展配置,用于实现功能的增强;详细的扩展配置说明可参考官网说明:https://www.eclipse.org/eclipselink/documentation/2.7/jpa/extensions/toc.htm。
1.4、使用例子
1.4.1、插入实体
@Test public void persist() { entityManager.getTransaction().begin(); Student student = new Student(); student.setName(\"小明\"); student.setCreateTime(LocalDateTime.now()); student.setModifyTime(LocalDateTime.now()); student.setAge(15); student.setHomeAddress(\"江苏\"); Student student2 = new Student(); student2.setName(\"小红\"); student2.setAge(18); student2.setHomeAddress(\"广东\"); Teacher teacher = new Teacher(); teacher.setCreateTime(LocalDateTime.now()); teacher.setName(\"张三\"); teacher.setAge(35); entityManager.persist(student); entityManager.persist(student2); entityManager.persist(teacher); entityManager.getTransaction().commit(); }
1.4.2、查询实体
@Test public void find() { Student student = entityManager.find(Student.class, 1501L); logger.info(\"student={}\", student); }
1.4.3、更新实体(先查再更新)
@Test public void modify() { entityManager.getTransaction().begin(); Student student = entityManager.find(Student.class, 1501L); student.setName(\"小明2\"); entityManager.getTransaction().commit(); }
1.4.4、更新实体(直接根据id更新)
@Test public void merge() { entityManager.getTransaction().begin(); Student student = new Student(); student.setId(1501L); student.setName(\"小明3\"); student.setAge(16); entityManager.merge(student); entityManager.getTransaction().commit(); }
1.4.5、删除实体
@Test public void remove() { entityManager.getTransaction().begin(); Student student = entityManager.find(Student.class, 1501L); entityManager.remove(student); entityManager.getTransaction().commit(); }
1.4.6、JPQL 查询
@Test public void select() { //查询一个字段 Query query = entityManager.createQuery(\"select s.name from Student s where s.age>10\", String.class); List<String> result = query.getResultList(); logger.info(\"result={}\", result); //查询多个字段 (?n 占位符:传统 ? 占位符的改良占位符,仅仅适应 JPQL 查询) query = entityManager.createQuery(\"select s.name,s.homeAddress from Student s where s.age>?1 and s.name like ?2\", Object[].class); query.setParameter(1, 10); query.setParameter(2, \"%小%\"); List<Object[]> result2 = query.getResultList(); for (Object[] arr : result2) { String s = \"\"; for (Object o : arr) { s += o.toString() + \",\"; } logger.info(s); } //查询对象 (:name 占位符:变量名形式的占位符,仅仅适应 JPQL 查询) query = entityManager.createQuery(\"select s.name,s.homeAddress from Student s where s.age between :min and :max and s.name like \'%小%\' order by s.id\", Student.class); query.setParameter(\"min\", 10); query.setParameter(\"max\", 40); //设置结果的开始位置,最大记录条数,可用来实现分页 query.setFirstResult(0); query.setMaxResults(10); List<Student> result3 = query.getResultList(); logger.info(\"result3={}\", result3); //聚合操作 query = entityManager.createQuery(\"select max(s.age) from Student s\"); Object result4 = query.getSingleResult(); logger.info(\"result4={}\", result4); //对应Student实体类中定义的静态查询”queryAll“ query = entityManager.createNamedQuery(\"queryAll\"); List<Student> result5 = query.getResultList(); logger.info(\"result5={}\", result5); }
1.4.7、JPQL 更新
@Test public void update() { entityManager.getTransaction().begin(); Query query = entityManager.createQuery( \"update Student SET age=16 where name=\'小明\'\"); query.executeUpdate(); entityManager.getTransaction().commit(); }
1.4.8、JPQL 删除
@Test public void delete() { entityManager.getTransaction().begin(); Query query = entityManager.createQuery( \"delete from Student where id=1501\"); query.executeUpdate(); entityManager.getTransaction().commit(); }
1.4.9、JPQL 本地查询,直接 SQL 语句查询数据
@Test public void nativeSelect() { Query query = entityManager.createNativeQuery(\"select s.* from a_student s where s.age>?\", Student.class); query.setParameter(1, 10); List<Student> result = query.getResultList(); logger.info(\"result={}\", result); }
1.4.10、JPA 标准 API 使用一
类似 SQL:select name from student where name=\'小明\'
@Test public void criteria() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<String> criteriaQuery = criteriaBuilder.createQuery(String.class); Root<Student> root = criteriaQuery.from(Student.class); criteriaQuery.select(root.get(\"name\")); criteriaQuery.where(criteriaBuilder.equal(root.get(\"name\"), \"小明\")); TypedQuery<String> query = entityManager.createQuery(criteriaQuery); List<String> list = query.getResultList(); logger.info(list.toString()); }
1.4.11、JPA 标准 API 使用二
类似 SQL:select id,name,age from student where age>=10 order by age,name desc
@Test public void criteria2() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Student> criteriaQuery = criteriaBuilder.createQuery(Student.class); Root<Student> root = criteriaQuery.from(Student.class); //Student 实体类需要有对应的构造方法 criteriaQuery.multiselect(root.get(\"id\"), root.get(\"name\"), root.get(\"age\"), root.get(\"homeAddress\")); criteriaQuery.where(criteriaBuilder.ge(root.get(\"age\"), 10)); criteriaQuery.orderBy(criteriaBuilder.asc(root.get(\"age\"))).orderBy(criteriaBuilder.desc(root.get(\"name\"))); TypedQuery<Student> query = entityManager.createQuery(criteriaQuery); List<Student> list = query.getResultList(); logger.info(list.toString()); }
1.4.12、JPA 标准 API 使用三
类似 SQL:select age,count(*) from student group by age having age<40
@Test public void criteria3() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Object[]> criteriaQuery = criteriaBuilder.createQuery(Object[].class); Root<Student> root = criteriaQuery.from(Student.class); //Student 实体类需要有对应的构造方法 criteriaQuery.multiselect(root.get(\"age\"), criteriaBuilder.count(root)); criteriaQuery.groupBy(root.get(\"age\")).having(criteriaBuilder.lessThan(root.get(\"age\"), 40)); TypedQuery<Object[]> query = entityManager.createQuery(criteriaQuery); List<Object[]> list = query.getResultList(); for (Object o : list) { logger.info(\"o={}\", o); } }
1.5、完整代码
package com.abc.demojpa; import com.abc.demojpa.entity.Student; import com.abc.demojpa.entity.Teacher; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.persistence.*; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import java.time.LocalDateTime; import java.util.List; public class JpaCase { protected static final Logger logger = LoggerFactory.getLogger(JpaCase.class); private EntityManagerFactory entityManagerFactory; private EntityManager entityManager; @Before public void before() { entityManagerFactory = Persistence.createEntityManagerFactory(\"myUnit\"); entityManager = entityManagerFactory.createEntityManager(); } @After public void after() { entityManager.close(); entityManagerFactory.close(); } //插入实体 @Test public void persist() { entityManager.getTransaction().begin(); Student student = new Student(); student.setName(\"小明\"); student.setCreateTime(LocalDateTime.now()); student.setModifyTime(LocalDateTime.now()); student.setAge(15); student.setHomeAddress(\"江苏\"); Student student2 = new Student(); student2.setName(\"小红\"); student2.setAge(18); student2.setHomeAddress(\"广东\"); Teacher teacher = new Teacher(); teacher.setCreateTime(LocalDateTime.now()); teacher.setName(\"张三\"); teacher.setAge(35); entityManager.persist(student); entityManager.persist(student2); entityManager.persist(teacher); entityManager.getTransaction().commit(); } //查询实体 @Test public void find() { Student student = entityManager.find(Student.class, 1501L); logger.info(\"student={}\", student); } //更新实体(先查再更新) @Test public void modify() { entityManager.getTransaction().begin(); Student student = entityManager.find(Student.class, 1501L); student.setName(\"小明2\"); entityManager.getTransaction().commit(); } //更新实体(直接根据id更新) @Test public void merge() { entityManager.getTransaction().begin(); Student student = new Student(); student.setId(1501L); student.setName(\"小明3\"); student.setAge(16); entityManager.merge(student); entityManager.getTransaction().commit(); } //删除实体 @Test public void remove() { entityManager.getTransaction().begin(); Student student = entityManager.find(Student.class, 1501L); entityManager.remove(student); entityManager.getTransaction().commit(); } //JPQL 查询 @Test public void select() { //查询一个字段 Query query = entityManager.createQuery(\"select s.name from Student s where s.age>10\", String.class); List<String> result = query.getResultList(); logger.info(\"result={}\", result); //查询多个字段 (?n 占位符:传统 ? 占位符的改良占位符,仅仅适应 JPQL 查询) query = entityManager.createQuery(\"select s.name,s.homeAddress from Student s where s.age>?1 and s.name like ?2\", Object[].class); query.setParameter(1, 10); query.setParameter(2, \"%小%\"); List<Object[]> result2 = query.getResultList(); for (Object[] arr : result2) { String s = \"\"; for (Object o : arr) { s += o.toString() + \",\"; } logger.info(s); } //查询对象 (:name 占位符:变量名形式的占位符,仅仅适应 JPQL 查询) query = entityManager.createQuery(\"select s.name,s.homeAddress from Student s where s.age between :min and :max and s.name like \'%小%\' order by s.id\", Student.class); query.setParameter(\"min\", 10); query.setParameter(\"max\", 40); //设置结果的开始位置,最大记录条数,可用来实现分页 query.setFirstResult(0); query.setMaxResults(10); List<Student> result3 = query.getResultList(); logger.info(\"result3={}\", result3); //聚合操作 query = entityManager.createQuery(\"select max(s.age) from Student s\"); Object result4 = query.getSingleResult(); logger.info(\"result4={}\", result4); //对应Student实体类中定义的静态查询”queryAll“ query = entityManager.createNamedQuery(\"queryAll\"); List<Student> result5 = query.getResultList(); logger.info(\"result5={}\", result5); } //JPQL 更新 @Test public void update() { entityManager.getTransaction().begin(); Query query = entityManager.createQuery( \"update Student SET age=16 where name=\'小明\'\"); query.executeUpdate(); entityManager.getTransaction().commit(); } //JPQL 删除 @Test public void delete() { entityManager.getTransaction().begin(); Query query = entityManager.createQuery( \"delete from Student where id=1501\"); query.executeUpdate(); entityManager.getTransaction().commit(); } //本地查询,直接 SQL 语句查询数据 @Test public void nativeSelect() { Query query = entityManager.createNativeQuery(\"select s.* from a_student s where s.age>?\", Student.class); query.setParameter(1, 10); List<Student> result = query.getResultList(); logger.info(\"result={}\", result); } /** * Criteria API * select name from student where name=\'小明\' */ @Test public void criteria() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<String> criteriaQuery = criteriaBuilder.createQuery(String.class); Root<Student> root = criteriaQuery.from(Student.class); criteriaQuery.select(root.get(\"name\")); criteriaQuery.where(criteriaBuilder.equal(root.get(\"name\"), \"小明\")); TypedQuery<String> query = entityManager.createQuery(criteriaQuery); List<String> list = query.getResultList(); logger.info(list.toString()); } /** * Criteria API * select id,name,age from student where age>=10 order by age,name desc */ @Test public void criteria2() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Student> criteriaQuery = criteriaBuilder.createQuery(Student.class); Root<Student> root = criteriaQuery.from(Student.class); //Student 实体类需要有对应的构造方法 criteriaQuery.multiselect(root.get(\"id\"), root.get(\"name\"), root.get(\"age\"), root.get(\"homeAddress\")); criteriaQuery.where(criteriaBuilder.ge(root.get(\"age\"), 10)); criteriaQuery.orderBy(criteriaBuilder.asc(root.get(\"age\"))).orderBy(criteriaBuilder.desc(root.get(\"name\"))); TypedQuery<Student> query = entityManager.createQuery(criteriaQuery); List<Student> list = query.getResultList(); logger.info(list.toString()); } /** * Criteria API * select age,count(*) from student group by age having age<40 */ @Test public void criteria3() { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Object[]> criteriaQuery = criteriaBuilder.createQuery(Object[].class); Root<Student> root = criteriaQuery.from(Student.class); //Student 实体类需要有对应的构造方法 criteriaQuery.multiselect(root.get(\"age\"), criteriaBuilder.count(root)); criteriaQuery.groupBy(root.get(\"age\")).having(criteriaBuilder.lessThan(root.get(\"age\"), 40)); TypedQuery<Object[]> query = entityManager.createQuery(criteriaQuery); List<Object[]> list = query.getResultList(); for (Object o : list) { logger.info(\"o={}\", o); } } }
JpaCase.java
2、使用 hibernate 作为 JPA 实现框架
只需修改引入的依赖及 JPA 配置文件(persistence.xml)。
2.1、引入依赖
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.6.10.Final</version> </dependency>
2.2、增强注解
hibernate 提供一些增强注解使得 JPA 的使用更加方便。@CreationTimestamp 用于自动生成插入时间,@UpdateTimestamp 用于自动生成修改时间。修改实体类如下:
package com.abc.demojpa.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import javax.persistence.*; import java.time.LocalDateTime; @NoArgsConstructor @AllArgsConstructor @Data @Entity @Table(name = \"a_student\") @NamedQuery(name = \"queryAll\", query = \"select s from Student s\") public class Student { @Id @GeneratedValue private Long id; @CreationTimestamp @Column(name = \"create_time\") private LocalDateTime createTime; @UpdateTimestamp @Column(name = \"modify_time\") private LocalDateTime modifyTime; private String name; private Integer age; @Column(name = \"home_address\") private String homeAddress; }
这样就可以不用手动设置 createTime,modifyTime 了。
2.3、persistence.xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <persistence version=\"2.2\" xmlns=\"http://xmlns.jcp.org/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd\"> <persistence-unit name=\"myUnit\"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name=\"javax.persistence.jdbc.driver\" value=\"com.mysql.cj.jdbc.Driver\"/> <property name=\"javax.persistence.jdbc.url\" value=\"jdbc:mysql://10.49.196.10:3306/test?useUnicode=true&characterEncoding=UTF-8\"/> <property name=\"javax.persistence.jdbc.user\" value=\"root\"/> <property name=\"javax.persistence.jdbc.password\" value=\"123456\"/> <property name=\"hibernate.hbm2ddl.auto\" value=\"update\"/> </properties> </persistence-unit> </persistence>
hibernatee 开头的配置是 hibernate 自带的扩展配置,用于实现功能的增强;详细的配置说明可参考官网说明:https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#configurations。
3、使用 OpenJPA 作为 JPA 实现框架
只需修改引入的依赖及 JPA 配置文件(persistence.xml)。
2.1、引入依赖
<dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa-all</artifactId> <version>3.2.2</version> </dependency>
2.2、persistence.xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <persistence version=\"2.2\" xmlns=\"http://xmlns.jcp.org/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd\"> <persistence-unit name=\"myUnit\"> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <class>com.abc.demojpa.entity.Student</class> <class>com.abc.demojpa.entity.BaseEntity</class> <class>com.abc.demojpa.entity.Teacher</class> <properties> <property name=\"javax.persistence.jdbc.driver\" value=\"com.mysql.cj.jdbc.Driver\"/> <property name=\"javax.persistence.jdbc.url\" value=\"jdbc:mysql://10.49.196.10:3306/cqt?useUnicode=true&characterEncoding=UTF-8\"/> <property name=\"javax.persistence.jdbc.user\" value=\"root\"/> <property name=\"javax.persistence.jdbc.password\" value=\"123456\"/> <property name=\"openjpa.jdbc.SynchronizeMappings\" value=\"buildSchema(ForeignKeys=true)\"/> <property name=\"openjpa.ClassLoadEnhancement\" value=\"true\" /> <property name=\"openjpa.DynamicEnhancementAgent\" value=\"true\" /> <property name=\"openjpa.RuntimeUnenhancedClasses\" value=\"supported\" /> </properties> </persistence-unit> </persistence>
openjpa 开头的配置是 openjpa 自带的扩展配置,用于实现功能的增强;详细的配置说明可参考官网说明:https://openjpa.apache.org/builds/3.2.2/apache-openjpa/docs/manual.html#ref_guide_conf。
4、JPA 3.0 使用
JavaEE 8 之后,Oracle 已将其捐献给 Eclipse 基金会运作,名字也改为 Jakarta EE。JPA 3.0 作为 Jakarta EE 9 的一部分,主要变化是包名的变化及 xml 配置文件命名空间的变化,功能上与 JPA 2.2 基本一致。
4.1、Eclipselink 作为实现框架
4.1.1、引入依赖
<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.jpa</artifactId> <version>3.0.2</version> </dependency>
4.1.2、persistence.xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <persistence xmlns=\"https://jakarta.ee/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"3.0\" xsi:schemaLocation=\"https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd\"> <persistence-unit name=\"myUnit\"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>com.abc.demojpa.entity.Student</class> <class>com.abc.demojpa.entity.Teacher</class> <properties> <property name=\"jakarta.persistence.jdbc.driver\" value=\"com.mysql.cj.jdbc.Driver\"/> <property name=\"jakarta.persistence.jdbc.url\" value=\"jdbc:mysql://10.49.1196.10:3306/cqt?useUnicode=true&characterEncoding=UTF-8\"/> <property name=\"jakarta.persistence.jdbc.user\" value=\"root\"/> <property name=\"jakarta.persistence.jdbc.password\" value=\"123456\"/> <property name=\"eclipselink.logging.level\" value=\"INFO\" /> <property name=\"eclipselink.ddl-generation\" value=\"create-or-extend-tables\" /> </properties> </persistence-unit> </persistence>
4.1.3、创建实体类
package com.abc.demojpa.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor @Data @Entity @Table(name = \"a_student\") @NamedQuery(name = \"queryAll\", query = \"select s from Student s\") public class Student { @Id @GeneratedValue private Long id; private String name; private Integer age; @Column(name = \"home_address\") private String homeAddress; }
4.1.4、使用
package com.abc.deomjpa; import com.abc.demojpa.entity.Student; import jakarta.persistence.*; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JpaCase { protected static final Logger logger = LoggerFactory.getLogger(JpaCase.class); private EntityManagerFactory entityManagerFactory; private EntityManager entityManager; @Before public void before() { entityManagerFactory = Persistence.createEntityManagerFactory(\"myUnit\"); entityManager = entityManagerFactory.createEntityManager(); } @After public void after() { entityManager.close(); entityManagerFactory.close(); } //查询实体 @Test public void find() { Student student = entityManager.find(Student.class, 1501L); logger.info(\"student={}\", student); } }
4.2、Hibernate 作为实现框架
主要修改依赖及 JPA 配置文件即可。
4.2.1、引入依赖
<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>jakarta.transaction</groupId> <artifactId>jakarta.transaction-api</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core-jakarta</artifactId> <version>5.6.10.Final</version> </dependency>
4.2.2、persistence.xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <persistence xmlns=\"https://jakarta.ee/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"3.0\" xsi:schemaLocation=\"https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd\"> <persistence-unit name=\"myUnit\"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name=\"jakarta.persistence.jdbc.driver\" value=\"com.mysql.cj.jdbc.Driver\"/> <property name=\"jakarta.persistence.jdbc.url\" value=\"jdbc:mysql://10.49.196.10:3306/cqt?useUnicode=true&characterEncoding=UTF-8\"/> <property name=\"jakarta.persistence.jdbc.user\" value=\"root\"/> <property name=\"jakarta.persistence.jdbc.password\" value=\"123456\"/> <property name=\"hibernate.show_sql\" value=\"true\"/> <property name=\"hibernate.hbm2ddl.auto\" value=\"update\"/> </properties> </persistence-unit> </persistence>
如何从 JPA 2.1 迁移到 JPA 3.0 可参考这篇文章:https://thorben-janssen.com/migrating-jpa-2-x-to-3-0。
JPA 2.1 和 JPA 3.0 配置文件差异说明可参考这篇文章:https://thorben-janssen.com/jpa-persistence-xml。
来源:https://www.cnblogs.com/wuyongyin/p/16516717.html
本站部分图文来源于网络,如有侵权请联系删除。