📄 如何用jdo开发数据库应用.htm
字号:
cc.setName(name);
cc.setAddress(address);
cc.setIdcard(idcard);
cc.setPhone(phone);
cc.setInitialBalance(initialBalance);
cc.setAllowOverDraft(allowOverDraft);
//以下是自动产生的信息:
cc.setCreateTime(new Date());
cc.setBalance(initialBalance); //使刚创建后的余额等于初始余额,这是典型的业务逻辑
//下面将新信用卡保存到数据库,注意其中的JDO API。
PersistenceManager pm = getPersistenceManager();
//先检测是否已经有该身份证注册的信用卡存在:
Query q = pm.newQuery(CreditCard.class,"idcard==_newIdcard");
q.declareParameters("String _newIdcard");
Collection existCards = (Collection)q.execute(idcard);
if(existCards.iterator().hasNext()) {
throw new IdCardDuplicatedException(); //已经该身份证号存在
}
//身份证号没重复,以下保存该信用卡对象:
pm.currentTransaction().begin(); //每次对数据库的更新必须放到事务中
pm.makePersistent(cc);
pm.currentTransaction().commit(); //提交新对象
pm.close(); //释放JDO资源
return cc;
}
public static class IdCardDuplicatedException extends RuntimeException {}
</PRE><BR>下面我们运行一下这个程序,将Main.main()改写如下:<BR><PRE> public static void main(String[] args) throws Exception {
System.out.println("开始测试功能……");
inputCard("张三","东风东路311号","223003433995431237","020-38864157",500.00f,5000.0f);
System.out.println("信用卡已创建!");
}
</PRE>
<P>编译,并运行(也可以在build.xml所在目录下运行“ant run”),系统显示:</P>
<P>开始测试功能……<BR>jdbc.con.connect
jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GB2312<BR>jdbc.stat.exec
set session transaction isolation level read committed<BR>jdbc.stat.execQuery
select version()<BR>jdbc.con.rollback<BR>jdbc.con.close<BR>jdbc.con.connect
jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GB2312<BR>jdbc.stat.exec
set session transaction isolation level read committed<BR>jdbc.stat.execUpdate
update jdo_keygen set last_used_id = last_used_id + ? where table_name =
'transaction_record'<BR>jdbc.stat.execQuery select max(transaction_record_id)
from transaction_record<BR>jdbc.stat.exec insert into jdo_keygen (table_name,
last_used_id) values ('transaction_record',
0)<BR>jdbc.con.commit<BR>jdbc.stat.execUpdate update jdo_keygen set last_used_id
= last_used_id + ? where table_name = 'credit_card'<BR>jdbc.stat.execQuery
select max(credit_card_id) from credit_card<BR>jdbc.stat.exec insert into
jdo_keygen (table_name, last_used_id) values ('credit_card',
0)<BR>jdbc.con.commit<BR>jdbc.con.commit<BR>jdbc.con.rollback<BR>JDO Genie:
Created RMI registry on port 2388<BR>JDO Genie: Bound to
jdogenie.jdogenie1<BR>pm.created<BR>jdoql.compile
credit.system.CreditCard<BR>idcard==_newIdcard<BR>jdbc.stat.execQuery select
credit_card_id, address, allow_over_draft, balance, create_time, idcard,
initial_balance, last_transaction_time, nme, phone, jdo_version from credit_card
where idcard = ?
<BR>jdbc.con.commit<BR>tx.begin<BR>tx.commit<BR>jdbc.con.connect
jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GB2312<BR>jdbc.stat.exec
set session transaction isolation level read committed<BR>jdbc.stat.execUpdate
update jdo_keygen set last_used_id = last_used_id + ? where table_name =
'credit_card'<BR>jdbc.stat.execQuery select last_used_id from jdo_keygen where
table_name = 'credit_card'<BR>jdbc.con.commit<BR>jdbc.stat.exec insert into
credit_card (credit_card_id, address, allow_over_draft, balance, create_time,
idcard, initial_balance, last_transaction_time, nme, phone, jdo_version) values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?)<BR>jdbc.con.commit<BR>jdbc.con.commit<BR>pm.closed<BR>信用卡已创建!<BR></P>
<P>以上信息说明我们的第一个功能已经正常完成,一条信用卡记录已经生成到数据库中。你可以通过mysql的数据库查询工具验证。我们发现Main函数返回后,系统并未退出运行,为什么呢?原来JDOGenie在默认的状态下打开了远程控制的监听服务,这对以后跟踪WebApp的服务器状态并进行调节时是很有用的。不过在这里只会干扰我们的视线,姑且将它关掉:在JDOGenie的工作台中,选择“File-->Project
Properties”菜单,然后在弹出的项目属性配置对话框中将“Remote
Access”检查框清掉,表示禁止远程访问,然后点击“OK”,并保存该Project。</P>
<P>然后,我们再次运行credit.system.Main,这次我们看到两个现象:一是程序扔出了异常,表示身份证号重复,这符合我们的预期;二是系统退出了,没有产生监听的线程,这即是刚才更改配置的结果。</P>
<P>到此为止,我们的创建信用卡的功能便完成了,现在我们来看一看JDOGenie提供的工作台集成的JDOQL查询功能:在工作台(WorkBench)中选中CreditCard类,然后选择菜单“Run-->View
Class Extent”可以查看CreditCard类的所有对象,这里我们看到下面的结果:</P>
<P><IMG height=374 src="如何用JDO开发数据库应用.files/CSDN_Dev_Image_2003-7-212531516.jpg"
width=470> </P>
<P>如果我们修改程序并创建了多张信用卡的话,在这个对话框中会看到更多的CreditCard类的实例对象(上图实际上已经显示了两张信用卡信息。</P>
<P>下面我们接着实现需求描述中的其它功能,并且在输出信息中不再显示JDOGenie的调试跟踪信息(实际上在项目配置中可以将这些信息屏蔽掉),如图(将日志级别改为“errors”):</P>
<P><IMG height=313 src="如何用JDO开发数据库应用.files/CSDN_Dev_Image_2003-7-212531518.jpg"
width=554></P>
<H4>4.5.2. 浏览信用卡信息</H4>
<P>这个功能仅仅是一个对所有信用卡的查看。实际上前面已经看到,在工作台中已经可以很轻松地完成这个功能,不过我们这里需要在程序中完成。</P>
<P>我们在Main类中加入一个方法:listCards()</P><PRE> /**
* 列出系统中所有的信用卡资料
*/
public static void listCards() {
PersistenceManager pm = getPersistenceManager();
for(Iterator itr = pm.getExtent(CreditCard.class,false).iterator();
itr.hasNext(); ) {
Object o = itr.next();<BR> System.out.println("DataStoreIdentity="+JDOHelper.getObjectId(o)+", "+o);<BR> }
pm.close();<BR> }
</PRE>
<P>该方法列出当前系统中的所有信用卡,包括自动生成的卡号(对象标识)。可以看到,方法的内容非常简单。你可以不屑一顾地说:哦,原来JDOGenie的工作台中的查看类对象的功能也不过如此而已!不错,确实如此而已,原因很简单:科技以人为本,JDO的目标就是简化操作!</P>
<P>另外,再将main()方法改一下: </P><PRE> public static void main(String[] args) throws Exception {
System.out.println("开始测试功能……");
listCards();
}
</PRE>
<P>然后编译,运行,结果如下(如果用Ant来运行,可能显示结果会有一些Ant工具的信息,以后不再解释): </P>
<P>开始测试功能……<BR>DataStoreIdentity=1979371451-1,
信用卡:余额=500.0,持卡人=张三,身份证号=223003433995431237,电话=020-38864157<BR>DataStoreIdentity=1979371451-11,
信用卡:余额=500.0,持卡人=李四,身份证号=320012194501032339,电话=020-38864157<BR></P>
<P>这里,我们可以看到几点:一是JDOGenie的日志功能已经关闭(前面的设置生效了),二是显示信用卡时利用到了CreditCard中的toString()方法。俗话说,机遇只照顾有准备的头脑,前面我们似乎是画蛇添足地给两个数据类加入了toString()方法,现在我们看到,这两个方法发挥了作用!</P>
<H4>4.5.3. 交易刷卡</H4>
<P>这个功能应该算是本系统的基本功能,信用卡拿来干什么的?就是拿来刷的。当然,拿来摆阔也有一定的可能,我就听说过有的人钱包一拿出来,N张信用卡排成一排,够豪气!不过可能一张都刷不了!</P>
<P>好了,废话少说,我们在Main类中加入一个新的刷卡方法buySomething():</P><PRE> /**
* 用信用卡购买商品时的刷卡功能。
* @param cardId 信用卡的标识,一般可通过刷卡机识别得到
* @param amount 交易金额
* @param idcard 用于验证的身份证号,可通过收银员输入
* @return 交易后的卡上余额
* @throws IdcardMismatchException 身份证号不符,拒绝交易
* @throws TooMuchOverDraftException 该卡已经透支太多,不能完成本交易
*/
public static float buySomething(String cardId, float amount, String idcard)
throws IdcardMismatchException, TooMuchOverDraftException {
PersistenceManager pm = getPersistenceManager();
pm.currentTransaction().begin();
CreditCard cc = (CreditCard)<BR> pm.getObjectById(pm.newObjectIdInstance(CreditCard.class,cardId),false);<BR>
if(idcard == null || !idcard.equals(cc.getIdcard()))
throw new IdcardMismatchException();
if(cc.getBalance()-amount < -cc.getAllowOverDraft())
throw new TooMuchOverDraftException();
TransactionRecord tr = new TransactionRecord();
tr.setCard(cc);
tr.setAmount(amount);
tr.setCreateTime(new Date());
tr.setNote("在天贸南大购买了一件商品");
pm.makePersistent(tr);
cc.setBalance(cc.getBalance()-amount);
pm.currentTransaction().commit();</PRE><PRE> float balance = cc.getBalance();
pm.close();
return balance;
}
public static class IdcardMismatchException extends RuntimeException {}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -