JDO 的使用和集成

JDO 的使用和集成
JDO 的使用和集成
     这里不想讨论JDO和JPA的区别,也不讨论JDO的规范,单只是从JDO的使用和与应用的集成角度来概述。

1. 下载JDO规范的实现开源包。目前主流的JDO实现有:
*.TJDO http://tjdo.sf.net
*.Speedo http://speedo.objectweb.org
*.JORM http://jorm.objectweb.org
*.XORM http://xorm.sourceforge.net
*.JPOX http://jpox.sourceforge.net
*.OJB http://db.apache.org/ojb/
*.DataNucleus http://www.datanucleus.org/
 
2. 这里选择DataNucleus为JDO的实现,因为个人认为datanucleus大有一统O/R Mapping天下的架势。前端支持JDO/JPA规范,后面能接多种数据存储平台(RDBMS, ODBMS, Map-based, Web-based, documents, etc) . 并且直接可与bigtable、hbase等分布式数据库集成。实在强大。
     * 下载DataNucleus程序包
     * 下载DataNucleus在eclipse下的扩展插件

3. 如果使用dataNucleus连接DBMS数据库(Mysql)需要加入以下几个jar包:
     datanucleus-enhancer-3.0.0-m4.jar   jdo-api-3.1-SNAPSHOT-20110319.jar  datanucleus-api-jdo-3.0.0-m4.jar  datanucleus-jdo-query-3.0.0-m2.jar    asm.jar
     mysql-connector-java-5.0.4-bin.jar  datanucleus-cache-3.0.0-m2.jar    datanucleus-management-1.0.2.jar datanucleus-core-3.0.0-m4.jar     datanucleus-rdbms-3.0.0-m4.jar

4. 创建一个entity class 并配置映射文件 如下:
     entity class :
@PersistenceCapable
public class Person {     
       @PrimaryKey
       private String name ;
       private int age ;
       private String mail ;
     .......
}
   mapping xml
<jdo>
    <package name="com.jdo.data.nucleus.model">
        <class name="Person">
            <field name="name" persistence-modifier="persistent">
                 <column length="100" />
            </field>
            <field name="age" persistence-modifier="persistent"/>
            <field name="mail" persistence-modifier="persistent"/>
        </class>
    </package>
</jdo>

5.创建JDO操作类:
             Map<String,String> JDOConfig = new HashMap<String,String>();
            JDOConfig.put( "javax.jdo.PersistenceManagerFactoryClass" ,"org.datanucleus.api.jdo.JDOPersistenceManagerFactory" );
           
            JDOConfig.put("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost/acegi" );
            JDOConfig.put( "javax.jdo.option.ConnectionDriverName" , "com.mysql.jdbc.Driver" );
            JDOConfig.put( "javax.jdo.option.ConnectionUserName" , "root");
            JDOConfig.put( "javax.jdo.option.ConnectionPassword" , "root");
            JDOConfig.put( "javax.jdo.option.NontransactionalRead" , "true");
            JDOConfig.put( "javax.jdo.option.NontransactionalWrite" , "true");
            JDOConfig.put( "datanucleus.autoCreateSchema" , "true" );
           
            PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(JDOConfig);
            PersistenceManager pm = pmf.getPersistenceManager();
            Person person = null;
            System. out.println("Insert iterm into DB. " );
             //insert
            person = new Person("wenhao" ,123,"[email protected]");
            pm.makePersistent(person);
             //select
             getPersonsFromDB(pm);
             //update
            person.setMail( "[email protected]");
            pm.close();
           
            person.setAge(1000);
            System. out.println("instance level : " + person.getAge());
           
            pmf = JDOHelper. getPersistenceManagerFactory(JDOConfig);
            pm = pmf.getPersistenceManager();
            List<Person> updatePersons = getPersonsFromDB(pm);
             if(updatePersons != null && updatePersons.size() > 0) {
                   for(Person updatePerson : updatePersons)
                         //delete
                        pm.deletePersistent(updatePerson);
                  System. out.println("Delete iterms from DB." );
            }
            pm.close();
            //select
            Query q = pm.newQuery( "SELECT FROM " + Person.class.getName() + " WHERE name == 'wenhao'" );
            List<Person> updatePersons = (List)q.execute();

6. 运行JDO操作类,这时直接运行会报如下的错误:
This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found
     这个错误的是因为没有对Entity class进行jdo的enhance来增强entity的二进制代码。故需要在project上增加datanucleus支持。并运行enhancer tool来enhance entity。运行后可通过反编译工具来查看transform后的class。可发现多了一些属性和方法。这些都是对JDO entity的扩展。

7.正常运行
     会发现在person.setMail( "[email protected]" );会更改到底层的数据库中,而person.setAge(1000);并不会更改数据库字段。其实很容易理解。类似hibernate的entity的几个状态,自由态·持久态·游离态。 当pm.close();后person处于自由态,修改的属性只有在instance内部有效。而在pm cloase或transaction.commit之前时,entity仍处理持久化状态,直接修改属性,会持久化到底层数据库中。
    
8.JDO对象的多对多关系实现。多对多和hibernate的配置类似,主要还是在配置文件上做一些配置。配置文件如下:
Person.jdo:
<jdo>
    <package name="com.jdo.data.nucleus.model">
        <class name="Person">
            <field name="name" persistence-modifier="persistent">
                  <column length="100" jdbc-type="VARCHAR" />
            </field>
            <field name="age" persistence-modifier="persistent"/>
            <field name="mail" persistence-modifier="persistent"/>
            <field name="roles" persistence-modifier="persistent" table="PERSON_RULE">
                  <collection element-type="com.jdo.data.nucleus.model.Role" />
                  <join>
                    <column name="name" />
                </join>
                <element>
                    <column name="roleName" />
                </element>
            </field>

        </class>
    </package>
</jdo>
Role.jdo:
<jdo>
    <package name="com.jdo.data.nucleus.model">
        <class name="Role">
            <field name="roleName" persistence-modifier="persistent">
                  <column length="100" jdbc-type="VARCHAR" />
            </field>
            <field name="roleDesc" persistence-modifier="persistent"/>
            <field name="persons" persistence-modifier="persistent" table="PERSON_RULE">
                  <collection element-type="com.jdo.data.nucleus.model.Person" />
                  <join>
                    <column name="roleName" />
                </join>
                <element>
                    <column name="name" />
                </element>
            </field>

        </class>
    </package>
</jdo>
Person.java:
@PersistenceCapable
public class Person {
       @PrimaryKey
       private String name ;
       private int age ;
       private String mail ;     
       @Element
       private Set<Role> roles ;
}
Role.java:
@PersistenceCapable
public class Role {
       @PrimaryKey
       private String roleName ;
       private String roleDesc ;
       @Element
       private Set<Person> persons ;
}
以上配置可实现多对多的关系。并能够进行关联查询。



欢迎大家访问我的个人网站 萌萌的IT人

你可能感兴趣的:(JDO 的使用和集成)