Inside Liberator JDO & JDO2

类别:Java 点击:0 评论:0 推荐:

 

1.       Liberator JDO采用编译期bytecode生成的方法来增强POJO。我们知道POJO( Plain Old Java Object)就是一个简单的java bean,不做特殊的处理是无法自行实现O/R Mapping的各种操作的。因此需要对java bean进行所谓的增强。增强其实很简单,就是为java bean添加状态管理,比如每个getter/setter增加状态判断,如果getter所对应的field还没有被从数据加载,就发起sql去加载这个field。这些新增加的操作需要以某种方式添加到POJO中。添加的方式主要有三种:自动增添源代码,通过动态byteCode生成在runtime实现状态处理的interface,在buildtime在bytecode中插入状态处理代码。

 

自动添加源代码由于由于潜在的被错误改动的危险和维护工作增多,很少被o/r mapping工具采用。通过动态byteCode是一个很理想的添加状态处理过程的方法,被著名的开源O/R Mapping工具Hiberante采用(通过开源的CGLIB)。动态byteCode生成的好处是简单,增强过程对开发人员完全不可以见。缺点是启动时间长(由于要在第一次加载POJO Class到VM的时候要做动态产生bytecode)和内存占用较多(由于要缓存产生的bytecode)。

 

Liberator JDO采用的则是第三种编译期bytecode生成,这种方式的优点是静态增强的启动效率高和占用内存少,缺点是对于习惯使用debugger来调试的开发人员需要在编译期多一个步骤可能不习惯,但对习惯测试驱动开发的开发人员则不会有不习惯的问题。

 

JDO1.0规范采用编译期bytecode生成的原因主要是利于规范实现厂商的bytecode增强,保证增强后代码的可移植性。另外,由于JDO不仅仅是O/R Mapping框架,更多的是企业数据访问框架,考虑到有需要尽可能小memory footprint的JDO实现情况,比如可以用于PDA开发的基于xml或flash memory的JDO实现,这样的JDO实现就需要尽可能小的memory footpring,采用动态byteCode生成就不适用。综合考虑这些因素,JDO选择了编译期bytecode生成。

 

最新的CGLIB2则为JDO风格的 bytecode增强添加了一个code transformation API,可以利用该API容易地实现编译期或者动态bytecode两种方式的JDO Enhancer。红工厂将在明年一季度实现EJB3.0的过程增加动态bytecode生成的增强方式,用户可以根据自己的需要选择。

 

2.Liberaot JDO采用两层缓存设计。第一层缓存是PersistenceManager(PM)的可读写缓存,该缓存只缓存一个PM生命周期中所操作的对象。可读写缓存除了减少对数据库的读操作,更主要的是推迟了事务中的所有的写操作(Insert, Update, Delete)到事物提交的时候才实际执行,这样就可以通过批量操作(Batch Update)来达到减少与数据库之间的网络通讯负担。

 

第二层缓存是只读缓存,只读缓存的功能有两个:

1.  提供跨PM的对象缓存。

2.  提供分布式的对象缓存。

 

只读缓存可以极大的提高应用的性能(特别读操作为主的应用)。当缓存的对象被执行写操作时,只读缓存中的对象立刻会被做废,则下一次加载就需要从数据库从读取。只读缓存最大的优势是很容易实现分布式支持,简单可靠,不需要考虑分布式环境中的多个缓存中同一个对象的数据同步问题。

 

3.  LiberatorJDO的平面Flush设计。

在JDO中,有两个主要的对象PersistenceManagerImpl和StoreManager。StoreManger负责具体的数据库操作。由于JDO需要支持Persistence Reachablity,意味着当我们保存Object Graph的时候需要做递归的图的遍历,在什么时候做这个遍历对JDO实现的架构有极大的影响。一个明显的标志就是当PersisteceMangaer提交事物的时候,交给StoreManager的一堆PO在StoreManger眼里是否有关系。如果有,意味着需要在StoreManager的数据库操作过程中进行递归,如果没有,则是在PersistenceManager内实现递归,对StoreManger来说,所有需要保存的所有PO是没有关系,这就好像在PersistenceManager和StoreManager之间有一个平面清晰的切割两者之间的关系。Sun的JDO RI采用了前者的设计,基于JDO RI的开源TJDO也采用相同的设计。这样的设计容易导致PersistenceManager和StoreManager中的逻辑相关,排错困难并产生冗余代码。后者的设计则层次清晰。Liberator JDO采用了后者的架构,从JDO1到JDO2的转变整个架构都没有改变,证明Liberator JDO的架构设计优良。

 

4.  Liberato中的Detach/Attach。Detach/Attach在j2ee的多层架构中有着巨大的优越性。Detach/Attach本是JDO2学习自Hibernate的一个重要特性。但由于JDO本身支持Persistence By Reachablity,JDO2得以将这个特性发扬光大。由于Hiberante不支持默认的Persistence by Reachbility,在更新脱离Session的多个关联对象时需要显式地update每个对象:

 

// in the first session

Cat cat = (Cat) firstSession.load(Cat.class, catId);

Cat potentialMate = new Cat();

firstSession.save(potentialMate);

 

// in a higher tier of the application

cat.setMate(potentialMate);

 

// later, in a new session

secondSession.update(cat);  // update cat

secondSession.update(mate); // update mate

 

 

In JDO

/

Cat cat = (Cat) firstPM.getObjectById(Cat.class, catId);

Cat potentialMate = new Cat();

firstPM.makePersistent(potentialMate);

 

cat.setMate(potentialMate);

 

 

secondPM.attach(cat);  // update cat and potentialMate

 

 

 

 

Persistence By Reachabilty在稍微复杂的关系中,不论是Persist, Dettach还是Attach都可以很大程度减少程序员的工作量和编程的复杂度。

 

5.  JDO2不但学习了Hiberante的很多优点,更学习了象Ibatas这样的SQL Mapping的优点,可以说有点集大成者的味道。在JDO2中也提供了和ibatis非常类似的sql mapping功能。用户可以在映射文件中直接定义sql和映射结果对象(Projection).JDO2 不但可以做静态的sql mapping,也可以做动态的sql mapping,即在代码中写入sql和映射对象。

 

Query query = pm.newQuery( “javax.jdo.query.SQL”,“select id, name from person where id=2” );

query.setClass( Person.class );

 

这样DBA可以对某些特别需要优化的sql(可以是很复杂的SQL),并直接在JDO 中执行这样的SQL(而不是JDOQL),同时从份利用project的好处,这接获得一个/多个结果对象(而不是通常JDBC的ResultSet)。由于JDO的Query接口考虑到了扩展,我们可以很容易的支持各种不用的查询语言,比如sql, JDOQL,甚至是Hibernate的HQL和EJB 3的QL。

 

 

 

 

6.动态Fetch Group。动态Fectch Group允许用户在运行中改变PO对象field的延迟加载计划( Fetch Plan)。比如在O/R Mapping的应用中,往往有一些很大的表,比如一个设备列表有多达30个属性,我们需要首先是一个简要列表,在简要列表中只需要显示少数几个属性,而在详细页面中需要显示所有的信息。这种情况下,动态改变Device对象的每个field的延迟加载(Lazy Load)属性就可以提高显示的效率,避免不必要的网络数据传输。

 

 

7.  工场还开发业界领先的动态表名映射。在大数据量的项目中,支持单个对象的多个分表映射(Dynamic Mapping),并允许在运行中动态指定实际映射表名,解决大数据量查询,更新,删除的性能问题。

 

 

8.  Liberator JDO 1.2支持aggregation的各种运算和统计功能。

 

9 Liberator JDO对每个PO可以工作在两种模式下,一种是纯JDO模式,一种是O/R Mapping的模式。JDO模式可以完全依赖JDO来完成数据库表的建立,维护。这种情况下的Mapping极其简单。

 

public class Account {

    private String firstName;

    private String lastName;

    private String password;

    private String email;

 

/**

 

……

}

她的映射可以是:

<package name="com.redsoft.samples">

        <class name="Account" table="tblAccount" identity-type="datastore">

        </class>

    </package>

存JDO模式可以不用考虑Mapping问题,很适合做原型或小型项目的快速开发。而O/R Mapping模式则适合在较大性的项目中使用。

 

 

10     Liberator JDO在所有的版本中都支持Eager Fetching。Eager Fectching就是在执行对象的加载的时候,把可能需要加载的相关的属性或关联对象一起加载,减少SQL地执行次数。在国外的一些同类产品中,类似的特性有些是作为高级功能需要另外购买。

 

 

 

 

Liberator PE 1.2正式版的新特性包括:

 

全面支持JSR-243标准。 支持Aggregation/Projection。 支持SQL Mapping,可以静态和动态的SQL定义,执行和Projection映射。 采用Eager Fectching, bulk load数据库访问策略, 避免N+1问题。 业界领先的动态表名映射。在大数据量的项目中,支持单个对象的多个分表映射(Dynamic Mapping),并允许在运行中动态指定实际映射表名,解决大数据量查询,更新,删除的性能问题。 支持SimpleIdentity。当表采用自定义主键并且只有一个主键的时候自动采用SimpleIdentity,用户无需象编写Identity Class对象,简化了开发。 允许用户使用标准语法定义对象属性的列类型, 支持标准的O/R Mapping映射,可以映射one-to-one, one-to-many, many-to-one,可以映射Map和Collection。JSR-243的映射方法和其他主流的O/R Mapping产品(EJB 3 JSR-220, Hiberante, TopLink)类似,大量的属性默认使映射易于学习并且更简单。 支持单个对象的多表映射。 对java.util.Map的映射时,key和value可以是简单java类型,也可以是可存储对象类型(PersistenceCapable)。 对java.util.Collection映射时,element可以是简单java类型,也可以是可存储对象类型(PersistenceCapable)。 对象引用(reference)映射时,同时支持inner join和outer join。 支持批量删除,关联批量删除 增加了查询数据集的分页(Paging)功能,可以定义获取某个区间的复合查询条件的结果集合 支持所有主流国外数据库的同时,支持国产数据库包括神州Oscar,东软OpenBase支持达梦关系数据库。

本文地址:http://com.8s8s.com/it/it12939.htm