精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-04-04
最后修改:2012-04-08
接上节:跟我学OpenJPA之一(学习前准备----工欲善其事,必先利其器) 下节传送门:跟我学OpenJPA之三(更快、更高、更强)
Hello World、Hello Delphi、Hello ASP、Hello Java、Hello SSH,这些都是我经历过的Hello,今天大家陪我再一次经历Hello OpenJPA。。。。
一、新建一个普通的Java项目(不是WTP项目)
二、转换为Maven项目
增加一些库依赖,pom.xml代码如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>StrongOpenJPA</groupId> <artifactId>StrongOpenJPA</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.4</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa</artifactId> <version>2.1.1</version> <scope>compile</scope> </dependency> </dependencies> </project> 因为pom.xml中没有配置src的未知,所以默认转换为maven项目之后,build path中的source中会变为空,这个时候要吧src重新增加进去,最简单的方法就是直接加!
三、增加slf4j记录日志 在src中新建一个log4j.properties文件,修改内容如下: # This is the configuring for logging displayed in the Application Server log4j.rootCategory=INFO, stdout #stdout configure log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[%-d{HH:mm:ss}-%p]%m%n
四、转换为JPA项目 首先在Data Source Explorer中增加对应的数据库,Drivers没有请自己设置
然后右键项目,将其转换为JPA的项目 因为Eclipse没有直接支持OpenJPA,所以这里直接选择Generic2.0
完成后,Eclipse会自动在src中新建META-INF目录,在META-INF中新建persistence.xml文件,自动生成的大多不能用,结合OpenJPA的配置方法修改内容如下: <?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"> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <properties> <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" /> <!-- 日志的级别 --> <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=WARN, Tool=INFO, SQL=TRACE" /> <property name="openjpa.RemoteCommitProvider" value="sjvm" /> <!-- 启用缓存,并且设置缓存的容量为5000,并且禁用软引用容量 --> <property name="openjpa.DataCache" value="true(CacheSize=5000, SoftReferenceSize=100)" /> <!-- 启用查询结果缓存,缓存的容量为1000,并且软引用的容量为100 --> <property name="openjpa.QueryCache" value="true(CacheSize=5000, SoftReferenceSize=100)" /> <!-- 缓存的数据存储类型 --> <property name="openjpa.QueryCompilationCache" value="true" /> <!-- 数据库连接工厂时的属性 QueryTimeout:JDBC驱动执行查询超时的时间,以秒为单位。 PrettyPrint:是否格式化输出SQL语句。 PrettyPrintLineLength:SQL每行输出的最大长度。 --> <property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=100" /> <!-- 查询结果一次转化为对象的最多个数,相当于JDBC的结果集对象Statement.set FetchSize。默认为-1,表示所有的查询对象立即初始化;0表示使用JDBC驱动默认的数值 --> <property name="openjpa.FetchBatchSize" value="-1" /> </properties> </persistence-unit> </persistence> 这些配置的参数在OpenJPA的文档中都有,因为没有找到中文的文档,大家有需要的话直接去看官方文档吧。其中有一个地方需要解释 的,javax.persistence.jdbc.driver等等这些参数是JPA标准,OpenJPA中也有类似的参数,一般情况下建议大家还是直 接使用标准参数来配置
五、生成Entities From Tables 转换为JPA项目之后,Eclipse就能够使用JPA Tools进行JPA的管理,尤其是Entities From Tables非常好用(虽然我重来不用 ^_^)。 右键项目,选择JPA Tools进行操作,我们先把数据库中的t_xx表转换出来
剩下的操作,大家就按照步骤来吧,因为演示的t_xx没有任何外键,所以按照最简单的方式转出来就可以。有可能自动生成后这个class会报错,这个时因为Eclipse诶有把TXx定义到persistence.xml中,如果报错大家就手工添加进去,下载的源码包内我已经手工修改过。 但是自动化生成的东西并不非常合适,至少在以后的通过Entities生成Tables的时候就存在很多的问题,因此我一般都用自己的做的一个转换工具进行代码自动生成。 com.strong.module.txx.jpa.TXx package com.strong.module.txx.jpa; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; /** * TXx entity * * @author Simen 自动生成时间: 2011-10-02 08:31:29 */ @Entity @Table(name = "t_xx") public class TXx implements java.io.Serializable { /** * */ private static final long serialVersionUID = 1L; public static final String S_XXID = "xx_id"; // PRIMARY public static final String S_XXBZ = "xx_bz"; // 选项备注 public static final String S_XXDM = "xx_dm"; // 选项代码 public static final String S_XXLX = "xx_lx"; // 选项类型 public static final String S_XXMC = "xx_mc"; // 选项名称 public static final String S_XXXH = "xx_xh"; // 选项序号 在同一分类中的顺序号 public static final String S_XXBY1 = "xx_by1"; // 备用1 public static final String S_XXBY2 = "xx_by2"; // 备用2 public static final String S_XXBY3 = "xx_by3"; // 备用3 public static final String S_XXBY4 = "xx_by4"; // 备用4 public static final String S_XXBY5 = "xx_by5"; // 备用5 public static final String S_XXBY6 = "xx_by6"; // 备用6 public static final String S_XXBY7 = "xx_by7"; // 备用7 public static final String S_XXBY8 = "xx_by8"; // 备用8 // Fields private Integer xxId; // PRIMARY private String xxBz; // 选项备注 private String xxDm; // 选项代码 private String xxLx; // 选项类型 private String xxMc; // 选项名称 private Integer xxXh; // 选项序号 在同一分类中的顺序号 private String xxBy1; // 备用1 private String xxBy2; // 备用2 private String xxBy3; // 备用3 private Integer xxBy4; // 备用4 private Integer xxBy5; // 备用5 private Date xxBy6; // 备用6 private Date xxBy7; // 备用7 private Float xxBy8; // 备用8 public TXx() { } // Constructors @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "AuthorSeqXX") @SequenceGenerator(name = "AuthorSeqXX", allocationSize = 1) @Column(name = "xx_id", unique = true, nullable = false, insertable = true, updatable = true) public Integer getXxId() { return xxId; } public void setXxId(Integer xxId) { this.xxId = xxId; } @Column(name = "xx_bz", length = 255) public String getXxBz() { return xxBz; } public void setXxBz(String xxBz) { this.xxBz = xxBz; } @Column(name = "xx_dm", length = 255) public String getXxDm() { return xxDm; } public void setXxDm(String xxDm) { this.xxDm = xxDm; } @Column(name = "xx_lx", length = 255) public String getXxLx() { return xxLx; } public void setXxLx(String xxLx) { this.xxLx = xxLx; } @Column(name = "xx_mc", length = 255) public String getXxMc() { return xxMc; } public void setXxMc(String xxMc) { this.xxMc = xxMc; } @Column(name = "xx_xh", length = 10) public Integer getXxXh() { return xxXh; } public void setXxXh(Integer xxXh) { this.xxXh = xxXh; } @Column(name = "xx_by1", length = 255) public String getXxBy1() { return xxBy1; } public void setXxBy1(String xxBy1) { this.xxBy1 = xxBy1; } @Column(name = "xx_by2", length = 255) public String getXxBy2() { return xxBy2; } public void setXxBy2(String xxBy2) { this.xxBy2 = xxBy2; } @Column(name = "xx_by3", length = 255) public String getXxBy3() { return xxBy3; } public void setXxBy3(String xxBy3) { this.xxBy3 = xxBy3; } @Column(name = "xx_by4", length = 10) public Integer getXxBy4() { return xxBy4; } public void setXxBy4(Integer xxBy4) { this.xxBy4 = xxBy4; } @Column(name = "xx_by5", length = 10) public Integer getXxBy5() { return xxBy5; } public void setXxBy5(Integer xxBy5) { this.xxBy5 = xxBy5; } @Temporal(TemporalType.TIMESTAMP) @Column(name = "xx_by6", length = 19) public Date getXxBy6() { return xxBy6; } public void setXxBy6(Date xxBy6) { this.xxBy6 = xxBy6; } @Temporal(TemporalType.TIMESTAMP) @Column(name = "xx_by7", length = 19) public Date getXxBy7() { return xxBy7; } public void setXxBy7(Date xxBy7) { this.xxBy7 = xxBy7; } @Column(name = "xx_by8", length = 12) public Float getXxBy8() { return xxBy8; } public void setXxBy8(Float xxBy8) { this.xxBy8 = xxBy8; } }
com.strong.module.txx.jpa.TXx_ 这个类比较奇特,是JPA规范中定义个一个特殊类,主要的作用是构造查询,这个以后再说 package com.strong.module.txx.jpa; import java.util.Date; import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.StaticMetamodel; /** * TXx_ entity * * @author Simen 自动生成时间: 2011-10-02 08:31:29 */ @StaticMetamodel(TXx.class) public abstract class TXx_ { public static volatile SingularAttribute<TXx, Integer> xxId; public static volatile SingularAttribute<TXx, String> xxBz; public static volatile SingularAttribute<TXx, String> xxDm; public static volatile SingularAttribute<TXx, String> xxLx; public static volatile SingularAttribute<TXx, String> xxMc; public static volatile SingularAttribute<TXx, Integer> xxXh; public static volatile SingularAttribute<TXx, String> xxBy1; public static volatile SingularAttribute<TXx, String> xxBy2; public static volatile SingularAttribute<TXx, String> xxBy3; public static volatile SingularAttribute<TXx, Integer> xxBy4; public static volatile SingularAttribute<TXx, Integer> xxBy5; public static volatile SingularAttribute<TXx, Date> xxBy6; public static volatile SingularAttribute<TXx, Date> xxBy7; public static volatile SingularAttribute<TXx, Float> xxBy8; }
六、配置Spring 在src下新建applicationContext.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 注解扫描 --> <context:component-scan base-package="com.strong" /> <!--整合Spring和JPA --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="StrongOpenJPAPU" /> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> </property> </bean> <!--注入事务管理类 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!--允许使用注解方式配置事务 --> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
七、建立Junit测试单元 新建一个类:test.com.strong.StringOpenJPATest package test.com.strong; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext.xml" }) public class StringOpenJPATest { // 使用注解的方式注入,3.1以前版本使用JpaDaoSupport和JpaTemplate实现 @PersistenceContext private EntityManager entityManager; @Test public void doTest() { System.out.println("=====Hello OpenJPA " + entityManager + "======="); } } 这里和Spring3.1以前的版本有一些不同,具体内容请参见Spring3.1+ JpaDaoSupport被deprecated后的研究
执行测试获得结果如下: ...... =====Hello OpenJPA Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@6087e704]======= ....... 到这里,我们成功的运行起来Spring+OpenJPA,并获取了对应的EntityManager,下一步将在这个的基础之上其他的操作,因为我是按照最初始的步骤进行的,所以现在的配置文件正式运行可能定存在问题,下节将进行详细的介绍
本节资源下载
SQL文件:strongjpa.sql.tar.gz 项目文件:StrongOpenJPA.tar.gz
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-04-05
JPA 和 hibernate 一样,没什么用,只能做一些业务简单的项目,上不了台面。不建议学。
|
|
返回顶楼 | |
发表时间:2012-04-05
string2020 写道 JPA 和 hibernate 一样,没什么用,只能做一些业务简单的项目,上不了台面。不建议学。
我们从2010年改用OpenJPA以来,已经做了不少的项目,从目前运行的情况来都非常好。并且JPA毕竟是Java的标准,现在的JPA2已经尽可能地实现了解耦合,也就是说你从OpenJPA转换到EclipseLink或者Hibernate(JPA)是完全平滑的 |
|
返回顶楼 | |
发表时间:2012-04-05
期待楼主大作的更新,最近想学JPA但不得要领,靠楼主了
|
|
返回顶楼 | |
发表时间:2012-04-05
真的很不错。JPA是Java的标准,会得到各方各面的支持。顶楼主。
|
|
返回顶楼 | |
发表时间:2012-04-05
最后修改:2012-04-05
string2020 写道 JPA 和 hibernate 一样,没什么用,只能做一些业务简单的项目,上不了台面。不建议学。
那么你的复杂业务在持久化层用什么开发的呢?别告诉我用存储过程哈。 |
|
返回顶楼 | |
发表时间:2012-04-05
一:
用spring的jdbc模板,直接执行sql 二: 用ibatis 我们公司的sql语句,最少都是10张表关联,请问,用jpa,还不配死人啊。 |
|
返回顶楼 | |
发表时间:2012-04-06
小弟有个疑问啊.jpa相比其他的持久化框架的优势在哪里呢?
因为我主要用spring jdbc和ibatis,hibernate属于业余,就会简单的增删改查.open jpa在这方面有什么优势吗? |
|
返回顶楼 | |
发表时间:2012-04-06
string2020 写道 一:
用spring的jdbc模板,直接执行sql 二: 用ibatis 我们公司的sql语句,最少都是10张表关联,请问,用jpa,还不配死人啊。 我不认为JPA会配死人,也不相信这么大的公司没有自己的代码生成工具。 我们用自己做的JPA工具,再大的表也能完全自动生成,剩下的只是根据业务逻辑进行一些功能扩展而已 |
|
返回顶楼 | |
发表时间:2012-04-06
bitray 写道 小弟有个疑问啊.jpa相比其他的持久化框架的优势在哪里呢?
因为我主要用spring jdbc和ibatis,hibernate属于业余,就会简单的增删改查.open jpa在这方面有什么优势吗? JPA相对其他持久化框架来说,最大的优势就是“标准”,如果你用Hibernate,那么你写的所有代码完全耦合其中,如果有一天Hibernate出现重大BUG,至少短时间内项目很难作出大的调整。 而使用JPA的话,不在乎你使用的是OpenJPA、EclipseLink甚至Hibernate(JPA),除了JPA的配置文件,大部分的代码都与这些框架没有任何耦合。 |
|
返回顶楼 | |