|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
windows系统样,他们做了什么事或者留了一些后门程序,谁都不知道,二,java开发是跨平台,任何系统上都可以运行,对于保密型系统和大型系统开发这是必要的 JDO(JavaDataObject)是JCP中较早开辟出来并构成标准的JSR12,该标准对数据的耐久化存储举行了一系列标准,并已有浩瀚的贸易产物和开源项目是基于该标准。作为一种必要引发器重的手艺,研讨并切磋其企业使用可行性是非常主要的。
媒介
在企业级的使用开辟中,常必要有优秀的耐久化手艺来撑持数据存储。经由过程优秀的标准或API,将企业的范畴营业对象举行耐久化存储,年夜多接纳O/R映照手艺来举行形式化的数据转换及主动映照事情。
JDO(JavaDataObject)是JCP中较早开辟出来并构成标准的JSR12,该标准对数据的耐久化存储举行了一系列标准,并已有浩瀚的贸易产物和开源项目是基于该标准。作为一种必要引发器重的手艺,研讨并切磋其企业使用可行性是非常主要的。
以下次要对JDO(JDO1.0标准)的使用开辟手艺作简明先容,经由过程该文,能够由浅进深、并较为周全地懂得JDO,把握次要的手艺细节及历程,了解其运转机制,并对企业级使用有个整体的掌控,这将有助于企业使用软件的手艺选型、系统架构及剖析计划举动。
该文合适企业使用架构师、及体贴数据耐久层计划开辟职员。
JDO基础头脑及特性
企业信息体系的一个主要成绩是办理数据的存储,即耐久化。在软件开辟过程当中,剖析员剖析范畴营业,提掏出范畴营业模子,并对应计划出数据库中必要举行存储营业数据的数据库表及响应字段。
并依据营业流程,计划营业处置逻辑单位,举行数据的加工、处置及存储、查询等营业。个中一个较为繁烦、单调的事情,就是处置大批的数据耐久化代码。为懂得决数据从营业对象层向数据存储层之间的转换事情,JDO供应了响应的开辟标准及API,办理了由Java对象间接存储为数据库响应表的底层处置历程,有助于计划职员加倍专注于面向营业流程、面向营业对象等较高条理的使用。
因为接纳JDO的映照机制,能下降了营业体系与数据存储体系的耦合,使得营业体系相对干系数据库或对象型数据库,具有可移植性,同时,因为接纳面向对象(而非传统的面向纪录)的耐久化手艺,体系更加笨重、简便,加强了可保护性。
JDO使用示例及剖析
以下将经由过程一些示例,由浅及深地解说JDO手艺。
一时对象与耐久对象
这是一个一般的营业对象的代码。
packagebusiness.model;
publicclassBook{
privateStringisbn;
privateStringname;
privateDatepublishDate;
publicvoidsetISBN(Stringisbn){
this.isbn=isbn;
}
publicStringgetISBN(){
returnthis.isbn;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetName(){
returnthis.name;
}
publicvoidsetPublishDate(DatepubDate){
this.publishDate=pubDate;
}
publicDategetPublishDate(){
returnthis.publishDate;
}
}
如今将它作为一个JDO中对象保留到数据库中。代码以下:
Bookbook=newBook();
book.setISBN(“isbn-1234567”);
book.setName(“Java计划形式”);
PersistenceManagermanager=persistenceManagerFactory.getPersistenceManager();
manager.currentTransaction().begin();
manager.makePersistence(book);
manager.currentTransaction().commit();
Book类的实例book对JDO的API而言,就是一个耐久对象。类Book是可耐久类。那任何一个一般java类都是JDO的可耐久类吗?不是的。只要具有以下的前提,一个对象才能够被JDO耐久到数据库中。
它所属类应标志为可耐久的类,有以下两种办法:
显式:完成接口,javax.jdo.PersistenceCapable便可;
隐式:以Sun的JDO参考完成为例,Book.java类的不异路径下还须有Book.jdo文件。
<?xmlversion=“1.0”encoding=“UTF-8”?>
<!DOCTYPEjdoSYSTEM“jdo.dtd”>
<jdo>
<packagename=“business.model”>
<classname=“Book”/>
</package>
</jdo>
并经由过程字节码加强工具(本例接纳Sun的字节码加强工具)处置,
javacBook.java
javacom.sun.jdori.enhancer.MainBook.classBook.jdo。
经由过程上述两种办法,取得的Book.class才是一个可耐久的类。
字节码加强的有以下功效:当使用程序经由过程set办法修正某个字段1时,因为经由过程加强历程,在其外部拔出了某些代码,JDO会取得数据形态变更的信息,从而在耐久过程当中,举行有选择性的处置。
依照JDO标准,加强后的类能够在分歧的JDO完成上利用,而无需从头编译或加强。
并非一切Book对象都是耐久对象,只要当makePersistence后,该对象才是耐久对象,并会经由过程JDO完成存储到数据库中。经由过程JDO的供给商扩大标志符(vendor-extension),可具体形貌Book类的存储特征,如为该可耐久类指定命据库表和对应字段。
<P> 耐久对象查询
JDO查询次要有以下两种体例。
・利用Extend查询
Extend能够查询指定类及子类的耐久对象。
PersistenceManagermanager=persistenceManagerFactory.getPersistenceManager();
manager.currentTransaction().begin();
Extendextend=manager.getExtend(Book.class,true);//true标明同时查询子类
Iteratorit=extend.iterator();
while(it.hasNext()){
Bookbook=(Book)it.next();
System.out.println(book.getISBN());
}
extend.closeAll();
manager.currentTransaction().commit();
Extend查询办法,供应了一种基于类的查询路子,它能够与上面的Query组成更加壮大的查询。
・利用Query查询
Query能够指定过滤前提,是一种经常使用的查询体例。
下例是查找前提为“书名以‘Java计划形式’开首且出书日期小于明天”的书本。
Stringfilter=“((String)name).startsWith(”Java计划形式”)&&publishDate<today”;
Queryquery=pm.getQuery(Book.class,filter);
query.declareImports(“importjava.util.Date”);
query.declareParameters(“Datetoday);
Datetoday=newDate();
results=(Collection)query.execute(today);//传进参数值today
if(results.isEmpty()){
System.out.println(“Nodata!”);
}else{
Iteratorit=results.iterator();
while(it.hasNext()){
Bookbook=(Book)it.next();
System.out.println(“BookName:”+book.getName()+“,ISBN:”+book.getISBN());
}
}
注:该前提利用了一个变元‘today’,经由过程“declareParameters”来声明该变量,并在“execute”办法中传进该变量的实例。
这类带参数的查询,很相似于我们之前接纳JDBC的带?的查询体例。
个中startsWith(Strings)是JDO供应的尺度字符办法,相似的办法另有endsWith(Strings)。
JDOQL:上述利用的就是一个JDOQL样例,JDOQL是JDO标准一个构成部分。利用JDOQL可使用使用在分歧的JDO完成上运转。为懂得决JDOQL的某些不敷,JDO标准供应了撑持特定JDO供给商查询语句接口。
・查询排序
下例是将查询了局按“出书日期降序、书名升序”举行排序。
Queryquery=pm.newQuery(Book.class,filter);
StringorderStr=“publishDatedecending,nameascending”;
query.setOrdering(orderStr);
results=query.execute(today);
对象更新
当客户端对营业数据举行了更新后,必要经由过程营业历程将其更新到耐久层中。
这有两个历程,起首依据主键找到该实例,接着更新字段及提交。以下例,将指定书目编号的书籍的出书日期举行变动。
publicvoidupdateBookPublishDate(Stringisbn,DatenewDate){
PersistenceManagerpm=null;
try{
pm=pmf.getPersistenceManager();
Objectobj=pm.newObjectIdInstance(Book.class,isbn);
Bookbook=(Book)pm.getObjectById(obj,true);
book.setPublishDate(newDate);
}catch(Exceptione){
xxxContext.setRollbackOnly();
thrownewException(e);
}finally{
try{
if(pm!=null&&!pm.isClosed()){
pm.close();
}
}catch(Exceptionex){
System.out.println(ex);
}
}
注,在PersistenceManager利用newObjectIdInstance()办法时,JDO是怎样晓得经由过程书目编号ISBN来找到该对象呢?
实在在本可耐久类Book的jdo形貌文件中,还需供应以下信息:
<?xmlversion=“1.0”encoding=“UTF-8”?>
<!DOCTYPEjdoSYSTEM“jdo.dtd”>
<jdo>
<packagename=“business.model”>
<classname=“Book”identity-type=“application”objectid-class=“BookKey”>
<fieldname=“isbn”primary-key=“true”/>
</class>
</package>
</jdo>
个中“identity-type=“application””声明可耐久类Book接纳程序标识体例,即使用程序传进ID(字段isbn为“primary-key”)信息,JDO完成机关出指定的“objectid-class”的实例(即newObjectIdInstance历程),并由JDO来检索出指定的耐久化对象(即getObjectById)。
BookKey类源码以下:
packagebusinesss.model;
publicclassBookKeyimplementsjava.io.Serializable{
publicStringisbn;
publicBookKey(){}
publicBookKey(Stringoid){
isbn=oid;
}
publicStringtoString(){
returnisbn;
}
publicBooleanequals(Objectobj){
returnisbn.equals((BookKey)obj).isbn);
}
publicinthashCode(){
returnisbn.hashCode();
}
}
切合JDO的“objectid-class”类,如“BookKey”,须具有以下前提:
类声明为public,并完成java.io.Serializable;
带有一个私有且不带参数的机关办法;
当字段作为主键时,须有私有的,且称号和范例与耐久类的字段分歧,如:publicStringisbn;
equals和hashCode须利用全体(特指多字段的团结主键)的主键字段值;
类必需有一个机关办法,与toString办法的处置历程是逆向历程;行将toString的输入值,作为该机关办法的输出值,又能够从头天生该实例(如机关办法“publicBookKey(Stringoid)”)。
综上所述,假如Book由两个字段作为主键,如isbn和name,则大概的代码是pm.newObjectIdInstance(Book.class,isbn+“#”+name),且BookKey的机关办法作响应变动,并有两个私有字段“isbn”和“name”。
<P> 对象删除
对象删除接纳办法deletePersistence。示比方下:
pm.currentTransaction().begin();
Objectobj=pm.newObjectIdInstance(Book.class,isbn);
Bookbook=(Book)pm.getObjectById(obj,true);
pm.deletePersistence(book);
pm.currentTransaction().commit();
取得PersistenceManager实例
上述的一切操纵与必要PersistenceManager实例,它能够在两种情况办法下取得:非受管情况和受管情况。
・非受管情况
非受管情况是多指两层开辟形式,使用程序间接取得资本对象,举行营业操纵。一样平常事件办理、平安办理或资本办理都必要使用程序自行保护。
Propertiesproperties=newProperties();
properties.put(“javax.jdo.PersistenceManagerFactoryClass”,“com.xxx.jdo.xxxPMFClass”);
properties.put(“javax.jdo.option.ConnectionURL”,“xxx”);
properties.put(“javax.jdo.option.ConnectionUserName”,“xxx”);
properties.put(“javax.jdo.option.ConnectionPassword”,“xxx”);
PersistenceManagerFactorypmf=JDOHelper.getPersistenceManagerFactory(properties);
PersistenceManagerpm=pmf.getPersistenceManager();
与JDBC猎取相似。
・受管情况
受管情况通常为多层开辟形式,特别是处于J2EE使用情况中,程序经由过程容器取得资本对象,举行营业操纵,因为在容器情况下,事件、平安及资本办理都由容器举行一致会合办理,从而简化了代码布局。
以下是EJB(EntityBean、SessionBean、MessageDrivenBean)中的setXXXContext中的代码示例。
privatePersistenceManagerFactorypmf;
publicvoidsetXXXContext(XXXContextcontext){
try{
InitialContextctx=newInitialContext();
Objectobj=ctx.lookup(“java:compenvjdofactory”);
pmf=(PersistenceManagerFactory)PortableRemoteObject.narrow(o,PersistenceManagerFactory.class);
}catch(NamingExceptione){
thrownewException(e);
}
}
PMF是怎样绑定到J2EE情况下的JNDI上,有乐趣可参考JCA相干的手艺文档。
事件办理
事件办理及利用,次要有以下三种情况。
利用JDO事件的Bean办理情况
一样平常在非J2EE情况下,利用该事件办理形式。
PersistenceManagerpm=pmf.getPersistenceManager();
pm.currentTransaction().begin();
//dosomebusinesswithjdo
pm.currentTransaction().commit();
pm.close();
利用JTA事件的Bean办理情况
一样平常在J2EE情况下,接纳Bean办理的事件情况下,利用以下体例。
该体例可用在EJB的事件情况下。
xxxContext.getUserTransaction().begin();
PersistenceManagerpm=pmf.getPersistenceManager();
//dosomebusinesswithjdo
xxxContext.getUserTransaction().commit();
pm.close();
・利用JTA事件的容器办理情况
一样平常在J2EE情况下,接纳容器办理的事件情况下,利用以下体例。
以下是某个会话Bean的营业办法。
publicvoiddoBusiness(){
PersistenceManagerpm;
try{
pm=pmf.getPersistenceManager();
//dosomebusinesswithjdo
}catch(Exceptione){
xxxContext.setRollbackOnly();
System.out.println(e);
}finally{
try{
if(pm!=null&&!pm.isClosed())
pm.close();
}catch(Exceptionex){
System.out.println(ex);
}
}
}
综上,能够得出结论,JDO的操纵完整与JDBC的操纵相差无几。
<P> JDO初级使用
・庞大对象的耐久化
在实践的使用中,一个可耐久化类要远比Book类庞大良多。它大概会援用别的的Java范例、类、汇合或数组,及大概庞大的承继干系。
当这些对象的形态产生变更时,JDO是怎样感知及跟踪形态变更?
JDO供应了响应的API及标准来完成该功效。
・基础范例及援用
可耐久化类的字段能被JDO完成举行耐久化的准绳。
原始范例、java.util.Date等被撑持(别的较为庞大或可选特征,详见JDO标准);
假如援用是一个可耐久类,则JDO举行耐久化处置;
经由过程元数据(如jdo文件)声明的字段,通常为非可耐久化类的援用,JDO举行耐久化;
后面两种情况,当形态产生变更时,JDO会主动感知,但假如援用长短可耐久化类,则必要代码举行显式关照,不然JDO不会将变更举行存储。以下例:
publicclassBook{
……
privateObjectpicture;
publicvoidsetPicture(Objectpic){
picture=pic;
}
publicObjectgetPicture(){
Returnpicture;
}
}
该类字段picture必要耐久化,但java.lang.Object不是一个可耐久类,故声明以下:
<?xmlversion=“1.0”encoding=“UTF-8”?>
<!DOCTYPEjdoSYSTEM“jdo.dtd”>
<jdo>
<packagename=“business.model”>
<classname=“Book”>
<fieldname=“picture”persistence-modifier=“persistent”/>
</class>
</package>
</jdo>
假如别的模块经由过程getPicture取得对象,并在JDO不成感知的内部,修正对象,则变更不会存储,较好的举措是修正setPicture办法,以下:
publicvoidsetPicture(Objectpic){
JDOHelper.makeDirty(this,“picture”);
picture=pic;
}
并经由过程setPicture办法来更新数据。
JDO的“makeDirty”办法,次要卖力关照JDO完成,可耐久化类Book某个实例(this)的“picture”字段产生了变更。
・汇合
可耐久类的字段援用为汇合时,依照JDO标准,强迫撑持java.util.HashSet,对HashMap、HashTable、TreeMap、TreeSet、LinkedList、ArrayList及Vector的撑持对JDO完成而言是可选的,经由过程PersistenceManagerFactory的supportedOptions办法取得完成特征。
・数组
假如可耐久类的援用是数组范例,当数组单位产生变更时,必要挪用“makeDirty”来关照JDO完成,该实例的数组援用内容产生了变更。
与援用长短可耐久类实例分歧,不必要举行JDO的元数据声明。
・承继
假如利用可耐久性,一样平常承继的子类与父类都为可耐久类,以削减体系庞大性,这时候必要在子类的元数据中指出其可耐久超类,以下:
<classname=“TechBook”persistence-capable-superclass=“Book”/>
可为非耐久类扩大耐久类,或可为耐久类扩大非可耐久类;这两种情况JDO完成都将疏忽非可耐久类的字段部分,而不保留到数据库。
JDO的一些不敷的地方
JDO对数据的耐久化手艺比拟于成熟的SQL,另有不敷的地方,这些不敷在某些情形下将大概会影响数据处置部分的计划完成。
以以下举了经常使用数据会见的需要功效
・查询加强
如字符串不撑持通配符、巨细写对照;
不撑持聚合操纵,没法完成MIN、MAX、SUM和AVG;
不撑持投影操纵,JDO查询前往为对象,而不像SQL那样前往字段;
不撑持团结、交织(UNION/INTERSECT);
不撑持JOIN、IN和EXISTS;
企业使用探求
因为JDO接纳面向对象的耐久化处置手艺,从而为办理企业营业体系的耐久化成绩供应了一个新手艺办理计划。可是先辈的一定就最合用。在某些使用场景下,必要分离各类要素,接纳天真的战略。
・面向对象与面向纪录
如今年夜多营业体系都接纳面向对象剖析计划,这就必要每一个使用体系都自行完成将对象映照成纪录,并存储到数据库中,而有JDO如许的面向对象的耐久化手艺,在某种水平上束缚了这类转化计划的不标准性,进而取得绝对更优的体系布局;另外一方面,一个营业体系的数据耐久化,一样平常都有如许的历程:对象层->纪录层->物理层,JDO无疑使剖析计划职员从纪录层的苦海中摆脱出来,从而加倍专注于对象层,这对开辟职员无疑是一个使人兴高采烈的手艺。
・JDO其实不能完整取代JDBC。
依据典范的“8-2道理”,假如用JDO来办理80%的成绩,余下的20%由JDBC来完成,这类互相增补,各取所长的战略,是一个很无效的举措。
如许一方面能够取得较好的布局及提拔开辟质量,另外一方面办理了JDO的某些手艺不敷,并可依据今后的手艺变更,再做得当转化。
・功能成绩
JDO与JDBC事实谁的功能更优,今朝还没有一个威望、且使人中意的谜底。但关于一些JDO完成而言,经由过程接纳缓存机制,使得功能有了较年夜进步。
・跨数据库
利用JDO的体系能更好地举行数据库移植,乃至能够在对象数据库上运转;固然JDBC处置层假如完整遵守SQL-92尺度,也一样具有很好的跨数据库才能。
前些天,在CSDN上看到了一个消息,说是ASP.NETAJAX成功在Linux上运行,这一点对我触动很大,而且引发了我许多感叹,所以想写出来分享一下。 |
|