OpenJPA 入门实例

前面章节介绍了 JPA、OpenJPA 基础知识,以及准备 OpenJPA 学习环境。本章节将通过一个简单的入门实例介绍怎样使用 OpenJPA 去操作数据库。

入门 OpenJPA 实例的项目结构如下图:

上图中,persistence.xml 文件为 OpenJPA 的配置文件,指定 JPA 提供者、数据库配置、实体配置等。User 为实体类,OpenJpaHello 是一个可以直接运行的 Java 类(拥有 main 方法)。

persistence.xml 配置

下面配置了一个持久化单元名为“openJPA”的实例。配置信息如下:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">

    <persistence-unit name="openJPA" transaction-type="RESOURCE_LOCAL">
        <!-- JPA提供者 -->
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

        <!-- 声明实体类 -->
        <class>com.huangx.openjpa.hello.entity.User</class>

        <!-- 配置JPA数据库属性 -->
        <properties>
            <property name="openjpa.ConnectionURL"
                      value="jdbc:mysql://localhost:3306/openjpa_learn?useSSL=false&amp;
                      serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
            <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
            <property name="openjpa.ConnectionUserName" value="root"/>
            <property name="openjpa.ConnectionPassword" value="aaaaaa"/>

            <!-- 自动生成表 -->
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

            <!-- 不使用加载时强化和编译时强化,使用运行时Unenhanced -->
            <property name="openjpa.ClassLoadEnhancement" value="false" />
            <property name="openjpa.DynamicEnhancementAgent" value="false" />
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
        </properties>
    </persistence-unit>

</persistence>

由于 OpenJPA 的增强器(Enhancer)能够在运行时对系统性能进行优化,并且提高惰性加载的灵活性,是 OpenJPA 与 Hibernate 最大不同之处。增强器能够自动为持久化的类添加一些代码,这些代码能够帮助二进制的类实现持久化类所必需的一些特性。上面配置中,通过如下配置禁用加载时强化和编译时强化:

<!-- 不使用加载时强化和编译时强化,使用运行时Unenhanced -->
<property name="openjpa.ClassLoadEnhancement" value="false" />
<property name="openjpa.DynamicEnhancementAgent" value="false" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />

如果不禁用加载时强化和编译时强化,运行程序将抛出如下错误信息:

Exception in thread "main" <openjpa-2.4.2-r422266:1777108 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "com.huangx.openjpa.hello.entity.User".

注意:在开发或者学习OpenJPA时可以禁用 OpenJPA 增强,在生成环境推荐开启增强功能,提供程序性能。

User 实体

使用 @Entity(标记该类为一个实体)、@Table(指定实体映射的数据表名称)、@Id(声明一个ID字段)、@Column(声明一个数据表列)和 @GeneratedValue(指定主键自动生成策略)注解声明一个简单的实体类,实现和数据库表(users)进行 ORM 映射。代码如下:

import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column
    private String name;

    @Column
    private Integer age;

    // 忽略 get 和 set 方法

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

OpenJPA客户端

下面将简单的介绍怎样使用 OpenJPA API 保存数据到数据库表。代码如下:

import com.huangx.openjpa.hello.entity.User;
import com.huangx.openjpa.utils.DateUtils;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class OpenJpaHello {

    public static void main(String[] args) {
        // 创建 EntityManagerFactory
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("openJPA");

        // 创建 EntityManager
        EntityManager em = emf.createEntityManager();

        // 创建实例类
        User user = new User();
        user.setName("Helen-" + DateUtils.getDate());
        user.setAge(28);

        // 开启事务,写入数据到数据库
        em.getTransaction().begin();
        em.persist(user);
        em.getTransaction().commit();

        // 关闭资源
        em.close();
        emf.close();

        System.out.println("success!!!");
    }

}

运行客户端程序,输出结果如下:

54  openJPA  WARN   [main] openjpa.Runtime - The configuration property named "openjpa.ClassLoadEnhancement" was not recognized and will be ignored, although the name closely matches a valid property called "openjpa.PostLoadOnMerge".
137  openJPA  INFO   [main] openjpa.Runtime - Starting OpenJPA 2.4.2
255  openJPA  INFO   [main] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjpa.jdbc.sql.MySQLDictionary".
1010  openJPA  INFO   [main] openjpa.jdbc.JDBC - Connected to MySQL version 5.5 using JDBC driver MySQL Connector Java version mysql-connector-java-5.1.46 ( Revision: 9cc87a48e75c2d2e87c1a293b2862ce651cb256e ). 
1349  openJPA  WARN   [main] openjpa.Enhance - Creating subclass for "[class com.huangx.openjpa.hello.entity.User]". This means that your application will be less efficient and will consume more memory than it would if you ran the OpenJPA enhancer. Additionally, lazy loading will not be available for one-to-one and many-to-one persistent attributes in types using field access; they will be loaded eagerly instead.
success!!!

查看数据库 users 表,数据被写入到了数据库。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号