如何用JDO开发数据库应用(10)

发表于:2007-07-14来源:作者:点击数: 标签:
如何用JDO 开发 数据库 应用(10) · 4.5.5. 查询透支报表 这个功能是查询当前系统中已经处于透支状态的那些信用卡,这里我们将会用到条件过滤,也就是使用JDO的查询语言JDOQL。在Main中加一个方法 listOverDrafts(): /** * 列出已经透支的信用卡。 */ pub
如何用JDO开发数据库应用(10)

· 4.5.5. 查询透支报表

这个功能是查询当前系统中已经处于透支状态的那些信用卡,这里我们将会用到条件过滤,也就是使用JDO的查询语言JDOQL。在Main中加一个方法 listOverDrafts():

/**
* 列出已经透支的信用卡。
*/
public static void listOverDrafts() {
PersistenceManager pm = getPersistenceManager();
Query q = pm.newQuery(CreditCard.class,"balance < 0"); //过滤条件
Collection col = (Collection)q.execute();
for(Iterator itr = col.iterator(); itr.hasNext(); ) {
System.out.println(itr.next());
}

pm.close();
}

我们注意到,经过刚才的一系列操作后,目前还没人透支(张三吓出一身冷汗,幸好刚才补了仓!)。再执行这个方法之前,我们再让张三买点东西,改一下main()方法,还是调用:buySomething("1979371451-1",250.0f,"223003433995431237"); 结果如下:
开始测试功能……
刷卡成功!余额:-164.0

可怜的张三又背上了沉重的心理负担。

下面我们改一下Main.main(),调用列出透支信用卡方法:

public static void main(String[] args) throws Exception {
System.out.println("开始测试功能……");

System.out.println("以下是透支的信用卡列表:");
listOverDrafts();
}

运行,结果如下:
开始测试功能……
以下是透支的信用卡列表:
信用卡:余额=-164.0,持卡人=张三,身份证号=223003433995431237,电话=020-38864157


我们快马加鞭,继续挺进下一需求功能。

· 4.5.6. 查询交易明细

这个功能相对复杂一点,不过也只是理解上复杂,代码还是很简单的。我们在Main中增加一个方法 listTransactions():

/**
* 列出某信用卡的交易明细。
* @param idcard 身份证号
*/
public static void listTransactions(String idcard) {
PersistenceManager pm = getPersistenceManager();
Query q = pm.newQuery(TransactionRecord.class,
"card.idcard==_p0"); //过滤条件
q.declareParameters("String _p0"); //声明查询参数表
q.setOrdering("createTime ascending"); //按时间顺序列出

Collection col = (Collection)q.execute(idcard); //按指定身份证号查询
for(Iterator itr = col.iterator(); itr.hasNext(); ) {
System.out.println(itr.next());
}
}

在这个方法中,我们用到了JDOQL最吸引人的特性之一:对象引用,即“card.idcard==_p0”,这样实际上相当于两个数据表联表查询,显然,这样的语句更易理解,更简洁!此外,我们用到了查询参数“_p0”,最后还用到了排序。实际上,还可以按此类所引用的其它类的属性进行排序,比如按持卡人姓名顺序列出所有交易记录,排序语句将是:q.setOrdering("card.name ascending"); 又省下表连接的冗长SQL语句。

最后,我们再修改Main.main()方法:


public static void main(String[] args) throws Exception {
System.out.println("开始测试功能……");

System.out.println("以下是张三的交易记录:");
listTransactions("223003433995431237");
}
运行之,结果如下:
开始测试功能……
以下是张三的交易记录:
交易记录:持卡人=张三,身份证号=223003433995431237,交易额=250.0,时间=Mon Jun 30 09:24:51 GMT 2003
交易记录:持卡人=张三,身份证号=223003433995431237,交易额=250.0,时间=Mon Jun 30 09:25:34 GMT 2003
交易记录:持卡人=张三,身份证号=223003433995431237,交易额=250.0,时间=Mon Jun 30 09:27:24 GMT 2003
交易记录:持卡人=张三,身份证号=223003433995431237,交易额=250.0,时间=Mon Jun 30 09:29:15 GMT 2003
交易记录:持卡人=张三,身份证号=223003433995431237,交易额=250.0,时间=Mon Jun 30 09:29:53 GMT 2003
交易记录:持卡人=张三,身份证号=223003433995431237,交易额=250.0,时间=Mon Jun 30 10:35:57 GMT 2003

这些就是我们前面的几次调用产生的交易记录。实际上,存款记录也应该算是交易记录,只不过本系统中暂时没有这种需求。(注意了,以后提需求的时候要多加考虑才行,否则又会让开发商钻空子了!)

· 4.6. 让程序更实用些

上面我们已经完成了所有的需求功能,大家也看到了基于JDO的应用是如何开发的,需要哪些配置。我再次说明一下,JDOGenie是最方便学习JDO的工具,尽管每隔一个月你得去重新索取一个试用license。

话又说回来,上面这些完成业务逻辑的方法太简单了,不被开发主管打才怪!(参见:程序写得烂被主管狂扁!)

为了让程序更实用,我们需要将其改造成一个真正的应用,这就涉及到安全性、性能优化与索引创建、容易操作的界面、后台操作日志、备份、图文并茂的报表,等等等等。尽管这些已经超出本文的范围,我们下面还是进行一点简单的讨论。

一般有两种最常见的方式做这样的系统:独立的GUI程序或者基于浏览器的Web应用。下面分别给出两种方式下的建议:

· 4.6.1. 图形界面的独立程序

首先,我们要从java.awt.Frame扩展出一个子类,在其窗口中放入几个Panel,分别对应需求中的几项功能,如果该功能是需要输入参数的,则在相应的Panel中放几个TextField,然后给一个提交按钮;如果该功能不需要输入参数,则直接给一个功能按钮即可。每个按钮的事件响应中,将相关的参数从界面元素中读出,传入到相应的方法中,然后接收方法的返回,将结果打印在界面的输出区(对了,还需要在界面上加一个输出区域,比如TextArea)。

前面我们的Main类的业务逻辑方法中,很多地方都是直接打印了查询取得的数据,在独立GUI程序中不能这样做,只能将查询取得的数据(如Collection)返回到调用的按钮事件中,再由按钮事件处理的代码打印到输出区域。这也算是一种MVC的方式了,呵呵。

还有一点建议,由于pm.close()后,对象的属性不能保证准确读出,所以,在独立的GUI程序中,最好系统一直保留一个打开的pm,各个方法共享。

· 4.6.2. 采用JSP的Web应用

基于JSP的Web应用相对复杂一些,我们需要将jdogenie.jar(合并了jta.jar和其license文件的包)和mysql.jar放到应用的/WEB-INF/lib中,然后将自己的enhance过的类代码按目录结构放到/WEB-INF/classes/中,同时配置文件creditSys.jdogenie和system.jdo一并放到/WEB-INF/classes/目录中。

这些只是目录的配置,我们还需要对前面的代码进行改造。

首先,与独立的GUI程序一样,需要将直接通过System.out.println()输出的业务逻辑方法改为将查询所得的Collection或具体对象返回到调用者。这里的调用者就是JSP。我们可以对每个功能写一到两个jsp,这些JSP只完成数据输入和显示的作用,这一点与独立的程序差不多。

不过,由于Web应用是多线程的,就需要考虑到并发连接的问题,因此系统中不能只设置一个始终打开的PM,而是每个页面请求需要使用一个PM。为了能在一个页面请求的处理过程中在不同的代码片断里共享一个PM,你可以参考我在JDOCentral的论坛上发表的这篇贴子。

关于Web应用中PM连接池和资源释放的细节已经超出本文的范围,请参考我在CSDN上发表的其它关于JDO的文章(见本文尾部的“参考文章”)。

· 5. 总结

下面我们对以上的基于JDO的开发作一点总结。

· 5.1. 开发流程的变化

基于JDO开发的流程在本文开始处通过一幅图进行了介绍,主要增加了两个步骤:编写metadata,和根据metadata对类代码进行增强。而这两步通过JDOGenie的工作台很容易搞定,都是自动化的。

剩下的开发过程就比原始的JDBC包装简单多了,我们不再有SQL代码,不再有复杂的“增、删、改、查”通用接口,不再有不支持事务的担心,不再有……我们只需要在一个完全面向对象的数据对象模型上通过JDO的API进行操作即可。

另外一点,我们可以看到,基于JDO的开发中,各种开发角色(JavbaBean编写、JSP编写、数据库维护、配置)都是基于数据对象模型进行开发,比如说,用JDOGenie就可以生成数据模型的UML类图后,打印下来,交给各个开发参与人员,无论是写控制类JavaBean,还是JSP,还是数据库结构维护,都可以以这个图作基准,大家统一进行开发,而不是象基于JDBC的应用,大家都基于数据库结构进行开发。

JDO给我们带来的太多了,需要在开发过程中慢慢体会。

(未完待续)

原文转自:http://www.ltesting.net