跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

Simple Persistence for Java 的零配置对象持久性

Java 应用程序开箱即用的对象持久性

Sami Salkosuo, 软件架构师, EMC
Sami Salkosuo 从 1999 年起一直在 IBM 工作。他的主要兴趣领域是 Java 编程,是 Sun 认证的 Java 程序员,IBM 认证的 XML 和相关技术解决方案开发人员,IBM 认证的 IBM WebSphere Portal 解决方案开发人员。除了 Java 技术,他还有 Python、Fortran、LabVIEW、Visual Basic、LISP、Perl 和 PHP 的经验。

简介: Simple Persistence for Java 是一个开源的对象关系型持久性库,它使用定制查询语言以及内建数据库支持来简化 Java 应用程序中的对象持久性。在本文中,软件架构师 Sami Salkosuo 介绍了该库,并带您领略解决对象持久性的零管理以及零配置方法。

发布日期: 2007 年 3 月 12 日
级别: 初级
访问情况 : 2020 次浏览
评论: 


对象持久性几乎是所有 Java™应用程序(从桌面应用程序到企业级应用程序)中的必备。持久性的缺点是它一直都不太简单。但这一情况已在最近一版的 Simple Persistence for Java(一个开源的对象关系型持久性库)中有所改变。

Simple Persistence for Java 2.1.0 版添加了对 HSQLDB 的支持,HSQLDB 是一个纯 Java 数据库。Simple Persistence for Java 和 HSQLDB 都不需要应用程序用户进行管理和配置。考虑以上因素,这些工具让您能够花相当少的力气就将持久性引入到应用程序中。

本文向您介绍 Simple Persistence for Java v2.1.0,并展示了如何几乎不费力气地使用该库以在 Java 应用程序中获得对象持久性。

Simple Persistence for Java

Simple Persistence for Java 是一个在 LGPL 许可下的开源库,由 Hungarian company NetMind Consulting 公司内部开发并发布到开源社区。

Java 开发人员有许多对象关系型库可用。Simple Persistence for Java 与其他库的不同之处是它零配置即可使用。此库的一个主要设计原则是:无需配置配置文件、XML 映射文件和属性(当然,您要有一个合适的数据库)。

Simple Persistence for Java 库还有以下一些重要特征:

  • 小的存储空间(135KB)
  • 简单的 API
  • 支持多个数据库
  • 简单查询语言
  • 多态性
  • 惰性结果列表

在 2.1.0 版中,Simple Persistence for Java 库添加了对 HSQLDB 数据库的支持。HSQLDB 是一个开源的、轻量级的纯 Java SQL 数据库引擎,它由一个 BSD 风格的许可协议授权。HSQLDB 支持 ANSI-92 SQL 的富子集,也支持 SQL 99 和 2003 增强版。它提供基于内存和基于磁盘的表,并支持内嵌式操作模式和服务器操作模式。


StockData 应用程序

我将用一个叫做 StockData 的样例程序向您展示通过 Simple Persistence for Java 库和 HSQLDB 来获得对象持久性是多么简单。StockData 基于用户查询过滤历史证券数据(在一个 CSV 文件中)。该程序和一个内嵌式数据库一起操作,且从命令行中运行。

为继续讨论,您需要重建类似我这样的开发环境并建立样例应用程序。StockData 的开发环境为 Eclipse 3.2.1,最低的 Java 版本是 JDK 1.5.0。我使用了基于内存的数据库选项在内嵌模式下开启了 HSQLDB 数据库。请注意,我可以选一个基于磁盘的内嵌式数据库或服务器端数据库,但出于演示的目的,我选了 HSQLDB 基于内存的数据库。

需要下列库来执行 StockData 样例程序:

  • commons-io-1.2.jar
  • commons-logging-api.jar
  • commons-logging.jar
  • hsqldb.jar
  • java-cup-11-runtime.jar
  • log4j-1.2.8.jar
  • netmind-persistence-2.1.0.jar

StockData 程序使用 commons-io 包和 commons-logging 包,HQSLSB 并不依赖于任何 jar 文件。netmind-persistence-2.1.0.jar 依赖于 java-cup-11-runtime.jar 和 log4j-1.2.8.jar。

样例源代码

清单 1 展示了 StockData 程序的源代码:


清单 1. StockData
				
 public class StockData 
 { 
  private static Log log; 
  public static void main(String[] args) 
  { 
    System.setProperty("log4j.configuration", "file:log4j.properties"); 
    log = LogFactory.getLog(StockData.class); 
    try 
    { 
      String symbol = args[0]; 
      String csvFile = args[1]; 
      String query = args[2]; 
      // open store, uses HSQLDB driver and memory only database 
      Store store = new Store("org.hsqldb.jdbcDriver","jdbc:hsqldb:mem:stockdata"); 
      // read csv and generate beans 
      List historicalData = FileUtils.readLines(new File(csvFile), "UTF-8"); 
      // remove first line (header) 
      historicalData.remove(0); 
      // store beans to database 
      for (Object _data : historicalData) 
      { 
        String[] data = ((String) _data).split(","); 
        StockBean bean = new StockBean(symbol, data[0], 
            Double.parseDouble(data[4]), Double.parseDouble(data[5])); 
        //save stock bean to database 
        store.save(bean); 
      } 
      // find beans that match query 
      List results=store.find(query); 
      // print beans that matched 
      System.out.println("Total results: "+results.size()); 
      for (Object object : results) 
      { 
        StockBean bean=(StockBean)object; 
        System.out.println(bean.toString()); 
      } 
    } 
    catch (Exception e) 
    { 
      log.error(e.getMessage(), e); 
      System.out 
          .println("Usage: java sample.StockData " + 
              "<symbol name> <historical prices file> <query>"); 
    } 
  } 
 } 

StockData 应用程序使用 Apache Commons IO 包将 CSV 文件读入 List。然后,for循环解析文本行并创建 StockBean对象,该对象被存入数据库中。CSV 文件的格式如下:

Date,Open,High,Low,Close,Volume,Adj. Close*
29-Dec-06,97.00,97.88,96.83,97.15,4455900,97.15
28-Dec-06,97.11,97.40,96.87,96.97,4501700,96.97
27-Dec-06,96.30,97.23,96.27,97.20,4571600,97.20

可下载演示包中提供了一个样例 CSV 文件。

将所有对象存入数据库后,会执行一个简单的 find查询(在命令行中指定)并返回一份相匹配结果的 List。结果打印到 System.out。请注意,Simple Persistence for Java 实现 LazyList,对象可在 LazyList 中随需检索。这确保了内存中最终不会出现成千上万的对象。

StockBean 对象

清单 2 展示了 StockBeanJava 对象的源代码,该代码用于存储 StockData 中的信息。StockBean有四个字段:symbol name、date、price 和 volume。


清单 2. StockBean 对象
				
 public class StockBean 
 { 
  private String symbolName = ""; 
  private String date = null; 
  private double price = 0.0; 
  private double volume = 0.0; 
  public StockBean() 
  { 
    // no-argument constructor required by Simple Persistence 
  } 
  public String toString() 
  { 
    StringBuffer sb=new StringBuffer(); 
    sb.append(symbolName); 
    sb.append(','); 
    sb.append(date); 
    sb.append(','); 
    sb.append(price); 
    sb.append(','); 
    sb.append(volume); 
    return sb.toString(); 
  } 
  public StockBean(String symbolName, String date, double price, double volume) 
  { 
    this.symbolName = symbolName; 
    this.date = date; 
    this.price = price; 
    this.volume = volume; 
  } 
  public String getDate() 
  { 
    return date; 
  } 
  public void setDate(String date) 
  { 
    this.date = date; 
  } 
  public double getPrice() 
  { 
    return price; 
  } 
  public void setPrice(double price) 
  { 
    this.price = price; 
  } 
  public String getSymbolName() 
  { 
    return symbolName; 
  } 
  public void setSymbolName(String symbolName) 
  { 
    this.symbolName = symbolName; 
  } 
  public double getVolume() 
  { 
    return volume; 
  } 
  public void setVolume(double volume) 
  { 
    this.volume = volume; 
  } 
 } 


简单元素

正如能在 清单 1的 StockData 源码中看到的那样,Simple Persistence for Java 真正简化了对象关系型持久性。基本上只需三行代码就可将持久性添加到您的 Java 应用程序中并从 HSQLDB 中检索对象:

  • Store对象构造函数。
  • 将对象保存到数据库的 save()方法。
  • 用于检索对象的一个或多个 find()方法。

构造函数十分简单;只需将 JDBC 驱动作为第一个参数,将 JDBC URL 作为第二个参数:

 Store store = new Store("org.hsqldb.jdbcDriver","jdbc:hsqldb:mem:stockdata"); 

稍后,Store对象将用于存储及检索对象。

将对象保存到数据库中也很直接:

 StockBean bean = new StockBean(symbol, date, price, volume); 
 store.save(bean); 

只需调用 save()将对象存储到数据库。任何必要的表都会在幕后创建。

使用用于检索对象的查询语言来查找对象也相当简单:

 List results=store.find(query); 

有四种不同的 find()方法:

  • find(String statement)
  • find(String statement, Object[] parameters)
  • findSingle(String statement)
  • findSingle(String statement, Object[] parameters)

带参数的 find()方法与在 SQL 中时一样:“?” 是参数对象的占位符。findSingle()方法是自解释的。


定制查询语言

到现在,您也许注意到了一件事,Simple Persistence for Java 使用定制查询语言来查找对象。查询语法是面向对象的,并且没有了表、索引或其他典型的对象关系型数据库的概念。例如,下列查询在一个 List中返回所有 StockBean对象:

 find stockbean 

由于作为结果的 List惰性的,因而可以不影响应用程序性能或内存消耗即可查询大量对象。所以,即使实际对象是随需检索的,getSize()方法也会返回一个结果的总数。

查询语法

Simple Persistence for Java 查询由 “find” 开始,第二个元素是要检索的类名。只有当许多类重名但所处包不同时才需要一个完整类名。

Where子句与在 SQL 中的那些类似。典型的操作符,如 “or”、“and”、“not”、“<”、“>”、“=”、“like” 等等也得到了支持。

下列查询会返回其值介于 USD90 和 USD92.5 之间的所有 StockBean对象:

 find stockbean where price>90 and price6lt;'92.5' and symbolname='IBM'

注意,表示整型值可以不用引号,但双精度值和字符串值则需要引号。

也可以使用 SQL 中常见的 “order by” 语法来对结果进行排序。例如,下列命令指定结果按价格降序排列:

 find stockbean where price>90 and price<'92.5' and symbolname='IBM' order by price desc 


运行样例

StockData 程序在一个 CSV 文件中搜索证券数据。可下载包包含编译过的源代码和一个叫做 stockdata.bat的批处理文件。该程序的语法是 stockdata.bat <symbol name> <csv file name> <find query>。可以使用此语法自己来查询样例应用程序。

下列命令的结果

stockdata.bat IBM ibm_2006.csv "find stockbean where price>90 and price6lt;'92.5' and symbolname='IBM'"

如图 1 所示:


图 1. 查询 StockData 应用程序的输出
查询 StockData 的输出

额外功能

StockData 应用程序演示了 Simple Persistence for Java 的基本功能。除此之外, Simple Persistence for Java 库还有一些 StockData 未表现出来的更高级的功能,包括多态性和用户管理事务。

多态性

在 Simple Persistence for Java 中,想要存储到数据库中的 JavaBean 能够从类中扩展。例如:

 public class StockBeanExt extends StockBean 
 { 
  private int totalTrades=0; 
  public StockBeanExt() 
  { 
    // no-argument constructor required by Simple Persistence 
  } 
  public int getTotalTrades() 
  { 
    return totalTrades; 
  } 
  public void setTotalTrades(int totalTrades) 
  { 
    this.totalTrades=totalTrades; 
  } 
 } 

保存了多个 StockBeanStockBeanExt对象后,目标字段处于 StockBean类的查询会返回 StockBeanStockBeanExt对象。

用户管理事务

Simple Persistence for Java 库也支持用户管理事务,允许指定事务何时开始,何时执行。以下列事务为例:

 Transaction tx = tt.getTransaction(TransactionTracker.TX_REQUIRED); 
 tx.begin(); 
 try 
 { 
   ...operations... 
 } catch ( ... ) { 
   ... handling code... 
   tx.markRollbackOnly(); 
 } finally { 
   tx.commit(); 
 } 

注意 finally子句是如何包含 commit的。这行命令总在执行,即使出现异常也是一样。在 catch()子句中,markRollbackOnly()方法指示 commit()何时被调用,它实际上会用回滚代替提交。

参见 参考资料了解更多信息和 Simple Persistence for Java v2.1.0 库的其他功能。


结束语

在本文中,我介绍了 Simple Persistence for Java v2.1.0 库,解释了它的基本功能及组件。我还使用该库的定制查询语言和 HSQLDB 数据库演示了一个简单的对象持久性场景,也探讨了该库的一些高级功能。

我发现:Simple Persistence for Java 库简单的 API 和零配置方法极大地简化了对象关系型持久性。如果您需要持久性(尤其是在小的实用项目中)但又想避免编写 SQL、使用持久性框架或在计算机上安装一个独立的数据库,那么,使用带 HSQLDB 数据库的 Simple Persistence for Java v2.1.0 就是一个不错的选择。



下载

描述名字大小下载方法
样例代码j-sp4j.zip3KBHTTP

关于下载方法的信息


参考资料

学习

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文

  • 轻量级开发的成功秘诀,第 6 部分 : 持久性策略” (Bruce Tate,developerWorks,2005 年 9 月):关于 Java 持久性框架和策略的一个较早却仍有价值的概览。

  • 使用 Apache Derby 和 iBATIS 提高持久性” (Daniel Wintschel,developerWorks,2006 年 1 月):对 iBatis 和 Apache Derby(另一个 Java 应用程序中对象持久性的一流组合)的教程式介绍。

  • 不要重复 DAO !” (Per Mellqvist,developerWorks,2006 年 5 月):描述使用 Java 5 泛型解决对象持久性问题的一种更为面向配置的、更为类型安全的方法。

  • 使用 EJB 3.0 Java Persistence API 设计企业应用程序” (Borys Burnayev,developerWorks,2006 年 3 月):介绍了针对 EJB 3.0 的 Java 持久性 API。

  • LGPL:GNU Lesser General Public License 是一个由自由软件基金会发布的免费软件许可协议。

  • BSD 协议:Berkeley Software Distribution 的原始许可协议,现在进行了修订并具有许多分支协议。

获得产品和技术

讨论

关于作者

Sami Salkosuo

Sami Salkosuo 从 1999 年起一直在 IBM 工作。他的主要兴趣领域是 Java 编程,是 Sun 认证的 Java 程序员,IBM 认证的 XML 和相关技术解决方案开发人员,IBM 认证的 IBM WebSphere Portal 解决方案开发人员。除了 Java 技术,他还有 Python、Fortran、LabVIEW、Visual Basic、LISP、Perl 和 PHP 的经验。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology, Open source
ArticleID=201356
ArticleTitle=Simple Persistence for Java 的零配置对象持久性
publish-date=03122007
author1-email=sami.salkosuo@fi.ibm.com
author1-email-cc=

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。