`
simen_net
  • 浏览: 306253 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

跟我学OpenJPA之四(与其他JPA实现的互换与对比---实践是检验真理的唯一标准)

 
阅读更多

 

感谢jinnianshilongnian和kjj的建议,我已经修改了文章的标题,以后会多多注意细节

 

上节,我们已经成功的把OpenJPA的实体对象增强,那么问题出现了。为什么我们要花费如此的代价,去修改实体类的字节码。这些修改能在实际的应用中体现出优化吗?在写这篇文章之前,我也没有针对这个做过完整的测试,实践是检验真理的唯一标准,那么让我们用实际行动来检验之。

 

本来想专门开一节讲解如何快速的将项目从OpenJPA转换到其他的JPA实现,但是由于确实太简单,单独一章介绍似乎有赚稿费的嫌疑(^_^) ,那么就在这里把项目转换到Hibernate和EclipseLink的JPA实现,同时也好与他们做个简单的性能比较。

 

================介绍完毕的分割线====================

 

在上节的测试中,我们发现entityManager.persist(entity)并没有把数据持久化保存到数据库,显然是因为没有启用事务的原因。在测试开始之前,我们先修改一下之前的代码。

 

1、建立DAO类

接口:StrongDAO.java

public abstract interface StrongDAO<E, PK extends Serializable> {

  /**
   * 执行SQL
   * 
   * @param strSQL
   * @return
   */
  public int executeSQL(final String strSQL);

  /**
   * 保存实体到数据库
   * 
   * @param entity
   */
  public void save(final E entity);
} 

实现:StrongDAOImpl.java

public abstract class StrongDAOImpl<E, PK extends Serializable> implements StrongDAO<E, PK> {

  @PersistenceContext
  private EntityManager entityManager;

  public EntityManager getEntityManager() {
    return this.entityManager;
  }

  public void setEntityManager(EntityManager entityManager) {
    this.entityManager = entityManager;
  }

  @Override
  public int executeSQL(String strSQL) {
    // TODO Auto-generated method stub
    return entityManager.createNativeQuery(strSQL).executeUpdate();
  }

  @Override
  public void save(E entity) {
    entityManager.persist(entity);
  }
}

 

2、为便于事务管理,建立Service类

接口:TXxService.java

@Transactional
public interface TXxService {

  /**
   * 单事务循环插入1000
   */
  public void doDanSHiWuXunHuan1000();

  /**
   * 单事务循环插入2000
   */
  public void doDanSHiWuXunHuan2000();

  /**
   * 单事务循环插入8000
   */
  public void doDanSHiWuXunHuan8000();

  /**
   * 单事务循环插入20000
   */
  public void doDanSHiWuXunHuan20000();

  /**
   * 使用事务添加单条记录
   */
  public void doShiWuTianJia(TXx txx);

  /**
   * 直接执行SQL清空记录
   */
  public void doQingKong();
}

实现:TXxServiceImpl.java

@Service
public class TXxServiceImpl implements TXxService {

  @Autowired
  public TXxDAO txxDAO;

  private void doDanSHiWuXunHuan(int intCiShu) {
    for (int i = 0; i < intCiShu; i++) {
      TXx txx = new TXx();
      txx.setXxMc("第一选项" + i);
      txxDAO.save(txx);
    }
  }

  @Override
  public void doDanSHiWuXunHuan1000() {
    doDanSHiWuXunHuan(1000);
  }

  @Override
  public void doDanSHiWuXunHuan2000() {
    doDanSHiWuXunHuan(2000);
  }

  @Override
  public void doDanSHiWuXunHuan8000() {
    doDanSHiWuXunHuan(8000);
  }

  @Override
  public void doDanSHiWuXunHuan20000() {
    doDanSHiWuXunHuan(20000);
  }

  @Override
  public void doShiWuTianJia(TXx txx) {
    txxDAO.save(txx);
  }

  @Override
  public void doQingKong() {
    System.out.println(txxDAO.executeSQL("delete from t_xx where xx_id > 22"));
  }
}

 

4、修改pom.xml,导入Hibernate的JPA实现包和EclipseLink的包,增加如下:

    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>eclipselink</artifactId>
      <version>2.3.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>4.1.0.Final</version>
    </dependency>

 

5、修改persistence.xml便于随时转换为其他的JPA实现

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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_1_0.xsd">
  <persistence-unit name="StrongOpenJPAPU" transaction-type="RESOURCE_LOCAL">
    <!-- 使用OpenJPA -->
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <!-- 使用Hibernate-JPA 
    <provider>org.hibernate.ejb.HibernatePersistence</provider>-->
    <!-- 使用EclipseLink
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> -->
    <class>com.strong.module.txx.jpa.TXx</class>
    <properties>
      <!-- JPA标准配置 使用OpenJPA和EclipseLink时使用 -->
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/strongjpa" />
      <property name="javax.persistence.jdbc.user" value="root" />
      <property name="javax.persistence.jdbc.password" value="root" />
      
      <!-- OpenJPA不增强 -->
      <property name="openjpa.ClassLoadEnhancement" value="false" />
      <property name="openjpa.DynamicEnhancementAgent" value="false" />
      <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
      
      <!-- Hibernate配置  使用Hibernate的JPA实现时使用
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
      <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/strongjpa" />
      <property name="hibernate.connection.username" value="root" />
      <property name="hibernate.connection.password" value="root" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />-->

    </properties>
  </persistence-unit>
</persistence>

两点需要注意:

1、由于Hibernate的顽固,不兼容标准的javax.persistence.jdbc.driver等参数,所以这里只能使用Hibernate自己的配置参数。

2、从增强OpenJPA转换到非增强OpenJPA的时候,首先要把上节中增加的Ant Builder禁用,然后要修改一次TXx类,以便Eclipse重新编译他,否则运行的时候使用的依然是增强过的实体对象。

3、EclipseLink运行的时候,必须给VM增加参数:-javaagent:****/spring-instrument-****.jar,否则会报错。使用的方法请参见上节中的介绍或参见Spring3(MVC)+OpenJPA2构建及发布

 

通过以上修改,大家很容易就发现:有了JPA的接口,我们可以非常方便地转换其他的实现,在Spring3.1之前,仍然使用回调的方式实现DAO,这样还会与JPA的具体实现有部分耦合,Spring3.1之后的注入方式彻底实现了解耦合。所以这里强烈大家升级到3.1以上并修改之前的耦合部分。

 

6、修改测试单元

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class StringOpenJPATest {

  @Autowired
  public TXxService txxService;

  private void doDuoShiWuXunHuan(int intCiShu) {
    for (int i = 0; i < intCiShu; i++) {
      TXx txx = new TXx();
      txx.setXxMc("第一选项" + i);
      txxService.doShiWuTianJia(txx);
    }
  }

  @Test
  public void doCeShiDuoShiWuXunHuan100() {
    doDuoShiWuXunHuan(100);
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDuoShiWuXunHuan200() {
    doDuoShiWuXunHuan(200);
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDuoShiWuXunHuan800() {
    doDuoShiWuXunHuan(800);
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDuoShiWuXunHuan2000() {
    doDuoShiWuXunHuan(2000);
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDanSHiWuXunHuan1000() {
    txxService.doDanSHiWuXunHuan1000();
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDanSHiWuXunHuan2000() {
    txxService.doDanSHiWuXunHuan2000();
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDanSHiWuXunHuan8000() {
    txxService.doDanSHiWuXunHuan8000();
    txxService.doQingKong();
  }

  @Test
  public void doCeShiDanSHiWuXunHuan20000() {
    txxService.doDanSHiWuXunHuan20000();
    txxService.doQingKong();
  }
}

测试顺序是先执行循环多次事务,每次事务插入一条记录(数量分别为100,200,800,2000);然后执行一次事务插入多条记录(数量分别为1000,2000,8000,20000),下面是测试的对比图

 



 

结论:

      分析结果我们发现,OpenJPA使用增强后的实体对象相较未增强时有明显性能提升,对比其他的JPA实现,OpenJPA的性能也没有太大的差别,尤其是在单事务多操作时其性能相较其他两种也有一定的优势。奇怪的时OpenJPA在连续执行多个简单事务时性能明显滞后。

      OpenJPA的官方文档中说实体对象增强后在“延迟加载”、“脏检查”等方面性能有一定的优化,由于时间和精力有限这里就不对这两项进行测试,把这个任务留给大家吧^_^

 

 

      最后,希望通过本节能让大家接受JPA,认可OpenJPA。从之前三篇文章的情况来看,感兴趣的朋友还是不多。顺便介绍一个OpenJPA入门和学习非常好课程:使用 Apache OpenJPA 开发 EJB 3.0 应用系列 有兴趣的朋友请传送过去学习。

      之前有人问我为什么不写写OpenJPA的基础概念和研究,其实主要是对比这个系列我觉得我的能力和协作的水平确实有限,并且也没有必要重复他人的工作。

 

本节资源:

本节的源码:StrongOpenJPA.tar.gz

Ant Builder需要的openjpa-all的jar包:openjpa_libs.tar.gz

 

  • 大小: 34.9 KB
  • 大小: 35.7 KB
分享到:
评论
1 楼 zn.share 2012-07-12  
实事求是的情深很好

相关推荐

    openjpa-manual

    ### OpenJPA-Manual 关键知识点解析 #### 一、OpenJPA介绍 **1.1 关于本文档** 本文档旨在提供一个全面且深入的指南,帮助开发人员理解和掌握Java Persistence API(JPA)的核心概念及其在Apache OpenJPA中的实现...

    Spring和openJPA集成

    OpenJPA 是基于 JPA 规范的实现,它提供了一种标准的方式来处理数据库操作,将对象模型与关系型数据库模型进行映射。通过注解或XML配置,开发者可以定义实体类,OpenJPA 将自动处理SQL查询、持久化、事务等细节。 ...

    jsf、openJpa学习

    **OpenJPA**(Open Java Persistence API)是Apache软件基金会的一个开源项目,它是Java持久层规范JPA(Java Persistence API)的实现,用于处理对象关系映射(ORM)。OpenJPA提供了一个框架,使得Java对象可以直接...

    apache-openjpa-2.2.1-source

    OpenJPA 是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大...OpenJPA 可以作为独立的持久层框架发挥作用,也可以轻松的与其它 Java EE 应用框架或者符合 EJB 3.0 标准的容器集成。

    OpenJPA 2.2.1 API (CHM格式)

    OpenJPA 可以作为独立的持久层框架发挥作用,也可以轻松的与其它 Java EE 应用框架或者符合 EJB 3.0 标准的容器集成。  除了对 JPA 标准的支持之外,OpenJPA 还提供了非常多的特性和工具支持让企业应用开发变得更加...

    openjpa 写的一个例子

    OpenJPA,全称Open Java Persistence API,是Java平台上的一个开源对象关系映射(ORM)框架,它实现了Java Persistence API(JPA),用于管理Java应用程序中的持久化数据。在这个"openjpademo"示例中,我们将会探讨...

    openjpa 源码 下载 帮助开发人员调试

    OpenJPA,全称Open Java Persistence API,是Apache软件基金会的一个开源项目,它实现了Java持久化API(Java Persistence API,JPA),为Java开发者提供了一种标准的方式来管理和持久化应用程序中的对象。...

    Spring中使用OpenJPA

    OpenJPA(Java Persistence API)则是Java平台上的一个ORM(对象关系映射)工具,它实现了JSR-317规范,使得开发者可以方便地在Java应用程序中操作数据库。本篇将详细讲解如何在Spring项目中集成并使用OpenJPA。 ...

    openJPA官方手册

    ### OpenJPA官方手册知识点概览 #### 一、引言 - **OpenJPA**:作为Apache项目的一部分,OpenJPA是一个开源的Java持久化框架(Java Persistence Framework),它支持Java Persistence API (JPA) 的规范。OpenJPA...

    Apache OpenJPA 2.1 User's Guide

    ### Apache OpenJPA 2.1 用户指南:Java Persistence API 的深入解析 #### 一、简介 Apache OpenJPA 2.1 是基于 Sun Microsystems 的 Java Persistence 2.0 API (JSR-317 JPA 2.0) 规范实现的一种透明持久化 Java ...

    Open JPA2 employee 简单例子

    OpenJPA2是一个开源的对象关系映射(ORM)框架,它是Java Persistence API(JPA)规范的实现。在这个“Open JPA2 employee简单例子”中,我们将深入理解如何使用OpenJPA2来处理数据库中的员工数据。这个示例将帮助...

    openjpa范例及实例工程

    默认情况下,当应用程序第一次获取实体标识时,OpenJPA 框架从数据库中一次性获取 50 个连续的实体标识缓存起来,当下一次应用程序需要获取实体标识时,OpenJPA 将首先检测缓存中是否存在实体标识,如果存在,Open...

    apache-openjpa-2.2.1-binary

    Apache OpenJPA(Java Persistence API)是Apache软件基金会的一个开源项目,主要目标是提供一个符合JSR-317标准的持久化框架。OpenJPA是用于管理Java对象到数据库映射的一种工具,它允许开发者将数据库操作抽象化,...

    openJpa的应用,感觉还可以

    OpenJPA(Open Java Persistence API)是Apache软件基金会下的一个开源项目,它是Java持久层标准JPA(Java Persistence API)的一个实现。JPA是Java EE平台中的一个重要组件,用于管理和处理应用程序中的对象-关系...

    apache-openjpa-2.2.0-source.zip

    Apache OpenJPA是Apache软件基金会开发的一个开源Java持久化项目,它实现了Java Persistence API (JPA),这是一个用于管理和持久化Java对象到关系数据库的标准API。OpenJPA 2.2.0是该项目的一个版本,提供了对Java ...

    openjpa jar

    OpenJPA,全称为Open Java Persistence API,是Apache软件基金会下的一个开源项目,主要目标是实现Java持久化规范,即JPA(Java Persistence API)。JPA是Java EE平台中的一个核心组件,它提供了一种标准的方式来...

    apache-openjpa-3.1.0-binary.zip

    JPA规范要求对实体对象进行某种类型的监视,但是该规范并未定义如何实现此监视。一些JPA提供程序动态生成在用户的Entity对象前面的新子类或代理对象,而其他JPA提供程序使用字节码编织技术来增强实际的Entity类对象...

    通过 WebSphere Application Server V6.1 利用 OpenJPA

    OpenJPA是一个开源的Java持久层框架,它实现了Java Persistence API(JPA),为开发人员提供了一种在Java应用中管理和存储对象到关系数据库的方法。 首先,我们需要了解JPA。Java Persistence API是Java平台上的一...

    Spring MVC+OpenJPA框架

    OpenJPA是Apache软件基金会的一个项目,它实现了JPA规范,为Java应用提供了一种标准的方式来访问和操作数据库。OpenJPA的主要功能有: 1. **实体管理(Entity Manager)**:负责创建、保存、更新和删除实体对象,...

Global site tag (gtag.js) - Google Analytics