技术开发 频道

JDO技术分析及如何进入企业应用的研究


持久对象查询
  
JDO查询主要有以下两种方式。
  
使用Extend查询
  
Extend可以查询指定类及子类的持久对象。
  
  PersistenceManager
  manager = persistenceManagerFactory.
  getPersistenceManager();
  manager.currentTransaction().begin();
  Extend extend =
  manager.getExtend(Book.class,true);
  //true表明同时查询子类
  Iterator it = extend.iterator();
  while(it.hasNext())
  {
   Book book = (Book)it.next();
   System.out.println(book.getISBN());
  }
  extend.closeAll();
  manager.currentTransaction().commit();
  
  Extend查询方法,提供了一种基于类的查询途径,它可以与下面的Query构成更为强大的查询。
  
使用Query查询
  
  Query可以指定过滤条件,是一种常用的查询方式。
  
  下例是查找条件为书名以Java设计模式开头且出版日期小于今天的书籍。
  
  String filter =
  ((String)name).startsWith(\Java设计模式\)
  && publishDate < today;
  Query query =
  pm.getQuery(Book.class,filter);
  query.declareImports(import java.util.Date);
  query.declareParameters(Date today);
  
  Date today = new Date();
  results = (Collection)
  query.execute(today);
  //传入参数值today
  if (results.isEmpty())
  {
   System.out.println(No data!);
  }else{
   Iterator it = results.iterator();
   while(it.hasNext())
   {
      Book book = (Book)it.next();
      System.out.println
  (Book Name: + book.getName()
  + , ISBN: + book.getISBN());
   }
  }
  
  注:该条件使用了一个变元today,通过declareParameters来声明该变量,并在execute方法中传入该变量的实例。这种带参数的查询,很类似于我们以前采用JDBC的带?的查询方式。
  
  其中startsWith(String s)是JDO提供的标准字符方法,类似的方法还有endsWith(String s)。
  
  JDOQL:上述使用的就是一个JDOQL样例,JDOQL是JDO规范一个组成部分。使用JDOQL可以使用应用在不同的JDO实现上运行。为了解决JDOQL的某些不足,JDO规范提供了支持特定JDO供应商查询语句接口。
  
查询排序
  
  下例是将查询结果按出版日期降序、书名升序进行排序。
  
  Query query =
  pm.newQuery(Book.class, filter);
  
  String orderStr =
  publishDate decending, name ascending;
  query.setOrdering(orderStr);
  
  results = query.execute(today);
 
对象更新
  
  当客户端对业务数据进行了更新后,需要通过业务过程将其更新到持久层中。这有两个过程,首先根据主键找到该实例,接着更新字段及提交。如下例,将指定书目编号的书本的出版日期进行更改。
  
  public void updateBookPublishDate
  (String isbn, Date newDate)
  {
   PersistenceManager pm = null;
   try{
  pm = pmf.getPersistenceManager();
  Object obj =
  pm.newObjectIdInstance(Book.class,isbn);
  Book book =
  (Book)pm.getObjectById(obj,true);
  book.setPublishDate(newDate);
   }catch(Exception e)
   {
  xxxContext.setRollbackOnly();
  throw new Exception(e);
   }finally{
      try{
  if (pm != null && !pm.isClosed())
  {
      pm.close();
  }
  }catch(Exception ex)
  {
   System.out.println(ex);
   }
  }
  
  注,在PersistenceManager使用newObjectIdInstance()方法时,JDO是如何知道通过书目编号ISBN来找到该对象呢?其实在本可持久类Book的jdo描述文件中,还需提供如下信息:
  
  <?xml version=1.0
  encoding = UTF-8?>
  <!DOCTYPE jdo SYSTEM jdo.dtd>
  <jdo>
   <package name = business.model>
       <class name = Book
  identity-type=application
  objectid-class=BookKey >
            <field name=isbn
        primary-key=true/>
       </class>
   </package>
  </jdo>
  
  其中identity-type=application””声明可持久类Book采用程序标识方式,即应用程序传入ID(字段isbn为primary-key)信息,JDO实现构造出指定的objectid-class的实例(即newObjectIdInstance过程),并由JDO来检索出指定的持久化对象(即getObjectById)。
  
  BookKey类源码如下:
  
  package businesss.model;
  public class BookKey implements
  java.io.Serializable
  {
        public String isbn;
        public BookKey()
   {
        }
        public BookKey(String oid)
   {
      isbn = oid;
      }
      public String toString()
   {
            return isbn;
      }
      public Boolean equals(Object obj)
   {
        return isbn.equals
   ((BookKey)obj).isbn);
      }
      public int hashCode()
   {
            return isbn.hashCode();
      }
  }
  
  符合 JDO 的objectid-class类,如BookKey,须具备以下条件:
  
  类声明为 public,并实现 java.io.Serializable;
  
  带有一个公有且不带参数的构造方法;
  
  当字段作为主键时,须有公有的,且名称和类型与持久类的字段一致,如:public String isbn;
  
  equals 和 hashCode 须使用全部(特指多字段的联合主键)的主键字段值;
  
  类必须有一个构造方法,与 toString 方法的处理过程是逆向过程;即将 toString 的输出值,作为该构造方法的输入值,又可以重新生成该实例(如构造方法public BookKey(String oid))。
  
  综上所述,如果Book由两个字段作为主键,如isbn和name,则可能的代码是pm.newObjectIdInstance(Book.class,isbn+#+name),且BookKey的构造方法作相应更改,并有两个公有字段isbnname
0
相关文章