对象持久性几乎是所有 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 是一个在 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 的样例程序向您展示通过 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 中随需检索。这确保了内存中最终不会出现成千上万的对象。
清单 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 应用程序演示了 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;
}
}
|
保存了多个 StockBean和 StockBeanExt对象后,目标字段处于 StockBean类的查询会返回 StockBean和 StockBeanExt对象。
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.zip | 3KB | HTTP |
学习
- 您可以参阅本文在 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 的原始许可协议,现在进行了修订并具有许多分支协议。
获得产品和技术
-
下载 Simple Persistence for Java 2.1.0:针对 Java 应用程序的一个开源对象关系型库。
-
下载 HSQLDB:存储 Java 对象的一个轻量级、低维护数据库。
讨论
-
参与 developerWorks 论坛。
- 通过参与 developerWorks blogs加入 developerWorks 社区。
