`
sony-soft
  • 浏览: 1008104 次
文章分类
社区版块
存档分类
最新评论

在Java SE环境下使用JPA1.0(Java EE 5.0 中的主要组成部分,TopLink配置

 
阅读更多
Java Persistence API 1.0( EJB3 Entity Bean) 在Java EE5中, Entity Bean做为EJB规范中负责持久化的组件将逐渐成为一个历史名词了,作为J2EE 4规范中最为人所垢病的Entity Bean在Java EE5中被推到重来,取而代之的是java开发的通用持久化规范Java Persistence API 1.0。JPA作为java中负责关系数据持久化的组件已经完全独立出来成为一个单独的规范,而不再属于Enterprise Java Bean的范畴。

Java Persistence AP(JPA)可以说是java持久化技术的一个集大成者,它吸取了Hiberante,JDO,TopLink等优秀技术和框架,将这几年发展成熟起来的基于POJO模型的O/R Mapping技术标准化,成为在J2EE和J2SE环境中通用的java持久化API。值得注意的是Java Persistence API并不是J2EE环境专用,而是在java中的通用API。意味着我们可以在任何需要访问关系数据库的地方使用JPA,甚至包括swing开发的桌面应用。JPA也不要求一定在J2EE容器中才能运行,而是任何有JVM的环境都可以运用。这就使得我们可以很容易的把JPA作为一个持久化组件自由地和各种容器/框架(EJB3容器, Spring等等)组合。

下面是我做的一个JPA 在 Java SE 环境下的使用范例.

一、搭建环境

1) 搭建数据库环境

1、安装数据库(MySQL 5.0.24), 用户: root,密码: (空) 。
2、建库piscesdb。
3、建表address:
droptableaddress;

createtableaddress(
addressID
intnotnull,
city
varchar(55)notnull,
street
varchar(55)NOTNULL,
zip
varchar(8)NOTNULL,
PRIMARYKEY(addressID)
);

insertintoaddressvalues(1,"深圳","坂田市场","518001");
insertintoaddressvalues(2,"深圳","坂田路口","518002");
insertintoaddressvalues(3,"深圳","四季花城","518003");

4、建表userinfo:
droptableuserinfo;

createtableuserinfo(
userID
intnotnull,/**用户id*/
username
varchar(20)notnull,/**姓名*/
birthday
datetimenull,/**出生日期*/
sex
varchar(8)notnull,/**性别*/
addressID
intnotnull,/**地址id*/
PRIMARYKEY(userID)
);

insertintouserinfovalues(1,"张先生",null,"male",1);
insertintouserinfovalues(2,"李某某",null,"male",2);
insertintouserinfovalues(3,"王某某",'2006-08-10',"female",3);
insertintouserinfovalues(4,"陈某某",'2006-08-12',"male",3);



2) 获取额外的jar包

下载JPA的实现类, 去https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html下载GlassFish v1 FCS branch版本,
进行安装后得到toplink-essentials.jar,toplink-essentials-agent.jar 两个包,将这两个包和mysql的驱动包加入到项目的classpath路径中去。
编译toplink源码需要 javax.transaction、org.apache.tools.ant 两个包
项目工程路径不要含中文, 因为 toplink 暂时不支持。

3) 开发环境

JDK: jdk 6.0 beta2 (JDK 5.0 也可以)
IDE: NetBeans 5.0 中文版

二、开发

1) 创建实体Entity类

1、地址类 Address :
/*
*Address.java
*/

packageorg.pisces.persist;

importjava.io.Serializable;
importjavax.persistence.Column;
importjavax.persistence.Entity;
importjavax.persistence.Id;

/**
*
*
@authorkamhung
*/
@Entity
publicclassAddressimplementsSerializable{
//地址id,不能为空,必须唯一
@Id
@Column(name
="addressid",unique=true,nullable=false)
privateintaddressid;

//城市,不能为空
@Column(name="city",nullable=false)
privateStringcity;

//街道,不能为空
@Column(name="street",nullable=false)
privateStringstreet;

//邮政编码,不能为空
@Column(name="zip",nullable=false)
privateStringzip;

publicAddress(){
}

publicAddress(intaddressid){
this.setAddressid(addressid);
}

publicintgetAddressid(){
returnthis.addressid;
}

publicvoidsetAddressid(intaddressid){
this.addressid=addressid;
}

publicStringgetCity(){
returnthis.city;
}

publicvoidsetCity(Stringcity){
this.city=city;
}

publicStringgetStreet(){
returnstreet;
}

publicvoidsetStreet(Stringstreet){
this.street=street;
}

publicStringgetZip(){
returnthis.zip;
}

publicvoidsetZip(Stringzip){
this.zip=zip;
}

@Override
publicinthashCode(){
returnthis.addressid;
}

@Override
publicbooleanequals(Objectobject){
if(!(objectinstanceofAddress))returnfalse;
finalAddressother=(Address)object;
returnthis.addressid==other.addressid;
}

@Override
publicStringtoString(){
return"Address[addressid="+getAddressid()+",city='"+getCity()+"',street='"+getStreet()+"',zip='"+getZip()+"']";
}
}

2、用户类 UserInfo:
/*
*UserInfo2.java
*/

packageorg.pisces.persist;

importjava.io.Serializable;
importjava.sql.Timestamp;
importjavax.persistence.Column;
importjavax.persistence.Entity;
importjavax.persistence.Id;
importjavax.persistence.JoinColumn;
importjavax.persistence.OneToOne;
importstaticjavax.persistence.CascadeType.*;

/**
*
*
@authorkamhung
*/
@Entity
publicclassUserInfoimplementsSerializable{
//用户id,不能为空,必须唯一
@Id
@Column(name
="userid",unique=true,nullable=false)
privateintuserid;

//用户名,不能为空
@Column(name="userName",nullable=false)
privateStringuserName;

//性别,不能为空
@Column(name="sex",nullable=false)
privateStringsex;

//出生日期,可以为空
@Column(name="birthday")
privateTimestampbirthday;

//地址,不能为空
//PERSIST表示更新、新增UserInfo数据时会同时更新、新增Address的数据
//REMOVE表示从数据库删除UserInfo会同时删除Address表中对应的数据
@OneToOne(cascade={PERSIST,REMOVE})
@JoinColumn(name
="addressID",nullable=false)
privateAddressaddress;

publicUserInfo(){
}

publicUserInfo(intuserid){
this.setUserid(userid);
}

@Override
publicinthashCode(){
returnthis.getUserid();
}

@Override
publicbooleanequals(Objectobject){
if(!(objectinstanceofUserInfo))returnfalse;
finalUserInfoother=(UserInfo)object;
returnthis.userid==other.userid;
}

@Override
publicStringtoString(){
return"UserInfo[userid="+this.userid+",userName='"+userName+"',sex='"+sex
+"',birthday="+birthday+",address="+address+"]";
}

publicintgetUserid(){
returnuserid;
}

publicvoidsetUserid(intuserid){
this.userid=userid;
}

publicStringgetUserName(){
returnuserName;
}

publicvoidsetUserName(StringuserName){
this.userName=userName;
}

publicTimestampgetBirthday(){
returnbirthday;
}

publicvoidsetBirthday(Timestampbirthday){
this.birthday=birthday;
}

publicStringgetSex(){
returnsex;
}

publicvoidsetSex(Stringsex){
this.sex=sex;
}

publicAddressgetAddress(){
returnaddress;
}

publicvoidsetAddress(Addressaddress){
this.address=address;
}
}


2) 创建配置文件persistence.xml

在项目src文件夹下创建一个META-INF文件夹(有就不用创建了), META-INF文件夹下建一个persistence.xml文件, 内容为:

<?xmlversion="1.0"encoding="UTF-8"?>
<persistenceversion="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/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<!--transaction-type可选值有:JTA、RESOURCE_LOCAL;
在JavaEE环境下默认值为JTA,在JavaSE环境下默认值为RESOURCE_LOCAL;
如果值为JTA的话,则必须要指定<jta-data-source>的值
-->
<persistence-unitname="piscesPU"transaction-type="RESOURCE_LOCAL">
<description>这是piscesPU持久化单元的一个简单描述</description>
<!--指明javax.persistence.spi.PersistenceProvider的实现类,一般来说该节点可以省略-->
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<!--在JavaSE环境下必须定义所有的实体Entity类,也可以用<mapping-file>或<jar-file>节点代替-->
<class>org.pisces.persist.UserInfo</class>
<class>org.pisces.persist.Address</class>
<!--
//可以定义jndi资源代替properties节点中的数据库配置,
//但是在调用Persistence.createEntityManagerFactory方法前必须保证此资源已经注入程序中.
<jta-data-source>jdbc/persist</jta-data-source>
-->

<!--properties节点是用来定义各种JPA实现包所定义的属性配置-->
<!--下面列举的是toplink实现包中可以配置的部分属性-->
<properties>
<!--数据库连接配置,JDBC驱动-->
<propertyname="toplink.jdbc.driver"value="com.mysql.jdbc.Driver"/>
<!--数据库连接配置,URL-->
<propertyname="toplink.jdbc.url"value="jdbc:mysql://localhost:3306/piscesdb"/>
<!--数据库连接配置,用户名-->
<propertyname="toplink.jdbc.user"value="root"/>
<!--数据库连接配置,密码-->
<propertyname="toplink.jdbc.password"value=""/>

<!--数据库连接池配置,可写的连接池的最大连接数,默认为10-->
<propertyname="toplink.jdbc.write-connections.max"value="10"/>
<!--数据库连接池配置,可写的连接池的最大连接数,默认为5-->
<propertyname="toplink.jdbc.write-connections.min"value="5"/>
<!--数据库连接池配置,只读的连接池的最大连接数,默认为2-->
<propertyname="toplink.jdbc.read-connections.max"value="2"/>
<!--数据库连接池配置,只读的连接池的最大连接数,默认为2-->
<propertyname="toplink.jdbc.read-connections.min"value="2"/>
<!--数据库连接池配置,只读的连接池是否可以共享,默认为false-->
<propertyname="toplink.jdbc.read-connections.shared"value="false"/>
<!--是否绑定所有jdbc属性,默认为true-->
<propertyname="toplink.jdbc.bind-parameters"value="true"/>

<!--缓冲配置,以下三个属性值为默认设置;
可以 default改为entity名(@Entity注释中的name属性值)或者类名来指定该entity的缓冲配置,如:
<propertyname="toplink.cache.size.org.pisces.persist.UserInfo"value="2"/>
<propertyname="toplink.cache.type.org.pisces.persist.UserInfo"value="SoftWeak"/>
<propertyname="toplink.cache.shared.org.pisces.persist.UserInfo"value="true"/>
-->
<propertyname="toplink.cache.size.org.pisces.persist.UserInfo"value="2"/>
<!--缓冲配置,缓冲大小,默认为1000-->
<propertyname="toplink.cache.size.default"value="1000"/>
<!--缓冲配置,缓冲类型,可选值为{Weak、SoftWeak、HardWeak、Full、NONE},不区分大小,默认为SoftWeak-->
<propertyname="toplink.cache.type.default"value="SoftWeak"/>
<!--缓冲配置,是否共享缓冲,默认为false-->
<propertyname="toplink.cache.shared.default"value="false"/>

<!--日志配置,日志级别,默认值为java.util.logging.Level在系统中的值-->
<propertyname="toplink.logging.level"value="SEVERE"/>
<!--日志配置,日志是否记录当前时间,默认为true-->
<propertyname="toplink.logging.timestamp"value="true"/>
<!--日志配置,日志是否记录当前线程名,默认为true-->
<propertyname="toplink.logging.thread"value="true"/>
<!--日志配置,日志是否记录当前会话名,默认为true-->
<propertyname="toplink.logging.session"value="true"/>
<!--日志配置,日志是否记录异常堆栈,默认为true-->
<propertyname="toplink.logging.exceptions"value="true"/>

<!--目标数据库类型,截至目前为止可选值为{Auto、Oracle、Attunity、Cloudscape、Database、DB2、DB2Mainframe
、 DBase、Derby、HSQL、Informix、JavaDB、MySQL4、PostgreSQL、SQLAnyWhere、 SQLServer、Sybase、TimesTen},
不区分大小,默认为Auto,即 TopLink自动匹配对应的数据库类型
-->
<propertyname="toplink.target-database"value="Auto"/>

<!--指定会话名称,默认为系统自动产生唯一性名称-->
<propertyname="toplink.session-name"value="pisces_session_name"/>

<!--设置是否为weaving,默认为true-->
<propertyname="toplink.weaving"value="true"/>

<!--指定目标应用服务器类型,截至目前为止可选值为{None、OC4J_10_1_3、SunAS9}(以后可能会扩展其他值的),
在 JavaSE环境下值为None,不区分大小,默认为None
-->
<propertyname="toplink.target-server"value="None"/>

<!--指定实现oracle.toplink.essentials.tools.sessionconfiguration.DescriptorCustomizer的类名,
toplink.descriptor.customizer. 为前缀,后面跟entity名(@Entity注释中的name属性值)或者entity类名,
该类中的customize方法在执行 了所有的属性(除了toplink.session.customizer之外)后运行,如:
<propertyname="toplink.descriptor.customizer.org.pisces.persist.UserInfo"value="org.pisces.persist.SimpleDescriptorCustomizer"/>
<propertyname="toplink.descriptor.customizer.org.pisces.persist.Address"value="org.pisces.persist.SimpleDescriptorCustomizer"/>
-->
<!--指定实现oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer的类名,
该类中的customize方法在执行了所有的属性后运行,如:
<propertyname="toplink.session.customizer"value="org.pisces.persist.SimpleSessionCustomizer"/>
-->
</properties>
</persistence-unit>
</persistence>



3) 创建Entity的管理类

管理类SimpleManager是用来对实体Entity进行操作管理的.
/*
*SimpleManager.java
*/

packageorg.pisces.persist;

importjava.util.List;
importjavax.persistence.EntityManager;
importjavax.persistence.EntityManagerFactory;
importjavax.persistence.Persistence;

/**
*
*
@authorkamhung
*/
publicclassSimpleManager{

//一个持久单元对应一个EntityManagerFactory
privatestaticfinalEntityManagerFactoryemf=Persistence.createEntityManagerFactory("piscesPU");

privateSimpleManager(){
//donothing
}

/**
*删除用户id=6的数据
*/
publicstaticvoiddelete(){
finalEntityManagerem=emf.createEntityManager();
//找不到数据的话这里会抛异常
UserInfoinfo=em.find(UserInfo.class,6);
try{
em.getTransaction().begin();
em.remove(info);
em.getTransaction().commit();
}
finally{
em.close();
}
}

/**
*修改用户id=6的数据
*/
publicstaticvoidupdate(){
finalEntityManagerem=emf.createEntityManager();
//找不到数据的话这里会抛异常
UserInfoinfo=em.find(UserInfo.class,6);
info.setUserName(
"哈哈");
info.getAddress().setStreet(
"坂田2");
try{
em.getTransaction().begin();
//自动将info更新到数据库
em.getTransaction().commit();
}
finally{
em.close();
}
}

/**
*查询所有用户数据
*/
publicstaticvoidquery(){
longs=System.currentTimeMillis();
//数据库连接失败这里会抛出异常
finalEntityManagerem=emf.createEntityManager();
longe=System.currentTimeMillis();
System.out.println(
"连接数据库耗时:"+(e-s)+"毫秒");
//获取数据
@SuppressWarnings("unchecked")
List
<UserInfo>list=em.createQuery("SELECTaFROMUserInfoa").getResultList();
inti=0;
for(UserInfoinfo:list){
System.out.println(
""+(++i)+"个值为:"+info);
}
em.close();
}

/**
*创建用户id=6的一条数据,地址id=6
*/
publicstaticvoidcreate(){
finalEntityManagerem=emf.createEntityManager();

UserInfoinfo
=newUserInfo(6);
info.setSex(
"male");
info.setUserName(
"张某某");
info.setBirthday(
newjava.sql.Timestamp(System.currentTimeMillis()));
Addressnaddr
=newAddress(6);
naddr.setCity(
"深圳");
naddr.setStreet(
"坂田");
naddr.setZip(
"518000");
info.setAddress(naddr);

try{
em.getTransaction().begin();
em.persist(info);
em.getTransaction().commit();
}
finally{
em.close();
}
}
}


三、运行

1、 编写main函数:
/*
*Main.java
*/

packageorg.pisces;

importorg.pisces.persist.SimpleManager;

/**
*
*
@authorkamhung
*/
publicclassMain{

/**
*主函数
*/
publicstaticvoidmain(String[]args)throwsThrowable{
SimpleManager.query();
SimpleManager.create();
System.out.println(
" 新增一条数据后进行查询");
SimpleManager.query();
SimpleManager.update();
System.out.println(
" 修改一条数据后进行查询");
SimpleManager.query();
SimpleManager.delete();
System.out.println(
" 删除一条数据后进行查询");
SimpleManager.query();
}
}

2、 运行结果如下:
run:
连接数据库耗时:1000毫秒
第1个值为:UserInfo[userid
=1,userName='先生',sex='male',birthday=null,address=Address[addressid=1,city='深圳',street='坂田市场',zip='518001']]
第2个值为:UserInfo[userid
=2,userName='李某某',sex='male',birthday=null,address=Address[addressid=2,city='深圳',street='坂田路口',zip='518002']]
第3个值为:UserInfo[userid
=3,userName='王某某',sex='female',birthday=2006-08-1000:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
第4个值为:UserInfo[userid
=4,userName='陈某某',sex='male',birthday=2006-08-1200:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]

新增一条数据后进行查询
连接数据库耗时:0毫秒
第1个值为:UserInfo[userid
=1,userName='先生',sex='male',birthday=null,address=Address[addressid=1,city='深圳',street='坂田市场',zip='518001']]
第2个值为:UserInfo[userid
=2,userName='李某某',sex='male',birthday=null,address=Address[addressid=2,city='深圳',street='坂田路口',zip='518002']]
第3个值为:UserInfo[userid
=3,userName='王某某',sex='female',birthday=2006-08-1000:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
第4个值为:UserInfo[userid
=4,userName='陈某某',sex='male',birthday=2006-08-1200:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
第5个值为:UserInfo[userid
=6,userName='张某某',sex='male',birthday=2006-08-1421:45:08.187,address=Address[addressid=6,city='深圳',street='坂田',zip='518000']]

修改一条数据后进行查询
连接数据库耗时:0毫秒
第1个值为:UserInfo[userid
=1,userName='先生',sex='male',birthday=null,address=Address[addressid=1,city='深圳',street='坂田市场',zip='518001']]
第2个值为:UserInfo[userid
=2,userName='李某某',sex='male',birthday=null,address=Address[addressid=2,city='深圳',street='坂田路口',zip='518002']]
第3个值为:UserInfo[userid
=3,userName='王某某',sex='female',birthday=2006-08-1000:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
第4个值为:UserInfo[userid
=4,userName='陈某某',sex='male',birthday=2006-08-1200:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
第5个值为:UserInfo[userid
=6,userName='哈哈',sex='male',birthday=2006-08-1421:45:08.187,address=Address[addressid=6,city='深圳',street='坂田2',zip='518000']]

删除一条数据后进行查询
连接数据库耗时:0毫秒
第1个值为:UserInfo[userid
=1,userName='先生',sex='male',birthday=null,address=Address[addressid=1,city='深圳',street='坂田市场',zip='518001']]
第2个值为:UserInfo[userid
=2,userName='李某某',sex='male',birthday=null,address=Address[addressid=2,city='深圳',street='坂田路口',zip='518002']]
第3个值为:UserInfo[userid
=3,userName='王某某',sex='female',birthday=2006-08-1000:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
第4个值为:UserInfo[userid
=4,userName='陈某某',sex='male',birthday=2006-08-1200:00:00.0,address=Address[addressid=3,city='深圳',street='四季花城',zip='518003']]
生成成功(总时间:
2秒)


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics