百木园-与人分享,
就是让自己快乐。

JPA 入门实战(2)--简单使用

本文主要介绍 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&amp;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、完整代码

JPA 入门实战(2)--简单使用JPA 入门实战(2)--简单使用

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&amp;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&amp;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&amp;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&amp;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
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » JPA 入门实战(2)--简单使用

相关推荐

  • 暂无文章