|
![]() |
名片设计 CorelDRAW Illustrator AuotoCAD Painter 其他软件 Photoshop Fireworks Flash |
|
前一阵在研究O/R MAPPING,觉得HIBERNATE和IBATIS都是好东西,但IBATIS更轻易上手,而且跟数据库打交道的时候只需把SQL 语句配置在XML里即可,不象HIBERNAMTE要写复合其规范的HQL。当然现在HIBERNATE大行其道肯定是有道理的,我过一阵子也打算好好学习一下。 技术发展的太快,学习方式是很重要的。(看来开源确实促进了生产力的发展啊,由此推断,共产主义社会肯定会实现的啦。)我认为必须摒弃抱本书按部就班的学习方式,而应该是STUDY IN ACTION,在实践中学习,缺啥补啥,大不了不断重构好了。当然前提是有一定的技术积累了。 为了学习IBATIS,除了大致看了一下IBATIS的官方文档,我把主要精力放在研究作者的范例JPETSTORE上了,大家可以道WWW.IBATIS.COM去下载4.0版本的例子,3.X的不要下了,代码写的没有4.0的柔美。 然后再去下载MYSQL,TOMCAT,安装调试让JETSTORE跑起来。这个过程我就不讲了,大家动动脑筋找点成就感吧。工欲善其事,必先利其器。我用的是JBUILDER9,因为我以前用DELPHI的对BORLAND的产品有感情啊(当然BORLAND不会对我有感情,因为。。。。。。^_^,中国特色)。建一个新项目,保存后关掉PROJECT,然后把JPETSTORE的代码包拷贝到:project rc/下,再打开刚才的项目,顺利的话你就能看到项目下的一堆包啦。现在编译肯定是有问题的,别急别急,在项目里加载上JPETSTORE源码LIB目录下的所有.JAR和SERVLET.JAR,为了连MYSQL,你还得加载MYSQL的JDBC驱动。详细做法,你可以在JBUILDER9 Tools/config libraries 新建三个LIB,比如IBATISLIB里放上JPETSTORE源码LIB目录下的所有.JAR,servlet就不要建了,JB9里带了,再建一个MYSQLLIB放上MYSQL的JDBC驱动的.jar,然后修改JPETSTORE源码SRC/PROPERTIES/database.properties的内容,例如,我的是driver=org.gjt.mm.mysql.Driverurl=jdbc:mysql://localhost/jpetstoreusername=jpetstorepassword=ibatis9977现在MAKE PROJECT应该可以通过了。好啦,打开com.ibatis.jpetstore底下的所有.java文件吧。Domain目录下放的是JAVABEAN,一般是跟表相对应的。Persistence目录下放的是DAO接口和详细实现类,DAO即数据访问对象(DATA ACCESS OBJECT),是用来跟数据库打交道的。IBATIS的O/R MAPPING的使用方式也就在这个目录里面。Presentation目录下放的是FORMBEAN,后面还要说到JPETSTORE范例对STRUTS的创造性使用。Service目录下放的是SERVICE类,通过SERVICE对象调用DAO对象的方式来访问数据库的,这是一种常用的设计模式。 常见的STRUTS编程应该是一个动作对应一个ACTION,例如写一个交友网站,用户登录和用户查询就得写分别写两个ACTION来处理。而JPETSTORE的作者克林顿(Clinton Begin,名字够响亮的)写了一个ACTION动态的调用FORMBEAN的不同方式来处理不同的动作。代码如下,注重execute()的写法! public class BeanAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String forward = \"success\"; try { ActionContext.initialize(request, response); if (form != null) { // Explicit Method Mapping Method method = null; String methodName = mapping.getParameter(); if (methodName != null && !\"*\".equals(methodName)) { try { method = form.getClass().getMethod(methodName, null); forward = (String) method.invoke(form, null); } catch (Exception e) { throw new BeanActionException(\"Error dispatching bean action via method parameter (\\\'\" + methodName + \"\\\'). Cause: \" + e, e); } } // Path Based Method Mapping if (method == null && !\"*\".equals(methodName)) { methodName = mapping.getPath(); if (methodName.length() > 1) { int slash = methodName.lastIndexOf(\"/\") + 1; methodName = methodName.substring(slash); if (methodName.length() > 0) { try { method = form.getClass().getMethod (methodName, null); forward = (String) method.invoke(form, null); } catch (Exception e) { throw new BeanActionException(\"Error dispatching bean action via URL pattern (\\\'\" + methodName + \"\\\'). Cause: \" + e, e); } } } } } } catch (Exception e) { request.setAttribute(\"BeanActionException\", e); throw e; } return mapping.findForward(forward); } } 也就是通过对struts-config.xml的配置信息的读取来决定调用的方式,或者是不调用任何方式。例如: 当ACTIONSERVLET收到哀求/shop/viewCategory.shtml,(JPETSTORE里后缀定义的是“.shtml”)调用catalogBean的viewCategory方式。怎么样,有创意吧,假如你愿意,就再也不用写那么多的ACTION了。下面谈一谈IBATIS的O/R MAPPING吧。请大家打开目录your project/com/ibatis/jpetstore/persistence qlmapdao ql,看到了什么?除了配置文件sql-map-config.xml以外,是一些和JAVABEAN相对应的XML,打开sql-map-config.xml和Acount.xml看看吧,再返到your project/com/ibatis/jpetstore/persistence目录,打开dao.xml发现他们的关系了吧。可能这时你搞不清这些XML有什么用处,别急,IBATIS官方文档里说的很清晰(有中文版的哦)。我大致说一下跟JAVABEAN对应的那些XML文件的作用吧,比如Acount.xml,是映射JAVABEAN和数据库的表的文件。你可以按照IBATIS的规范在里面写任意的SQL语句,参数和返回值可以是基本类型及其包装类,MAP,自定义的类。最常用的当然是返回自定义类实例了。不过假如返回值是自定义的类实例的话,你就需要先定义resultMap,比如:<resultMap id=\"accountResult\" class=\"account\"> <result property=\"username\" column=\"USERID\"/> <result property=\"email\" column=\"EMAIL\"/> <result property=\"firstName\" column=\"FIRSTNAME\"/> <result property=\"lastName\" column=\"LASTNAME\"/> <result property=\"status\" column=\"STATUS\"/> <result property=\"address1\" column=\"ADDR1\"/> <result property=\"address2\" column=\"ADDR2\"/> <result property=\"city\" column=\"CITY\"/> <result property=\"state\" column=\"STATE\"/> <result property=\"zip\" column=\"ZIP\"/> <result property=\"country\" column=\"COUNTRY\"/> <result property=\"phone\" column=\"PHONE\"/> <result property=\"languagePreference\" column=\"LANGPREF\"/> <result property=\"favouriteCategoryId\" column=\"FAVCATEGORY\" /> <result property=\"listOption\" column=\"MYLISTOPT\" /> <result property=\"bannerOption\" column=\"BANNEROPT\" /> <result property=\"bannerName\" column=\"BANNERNAME\" /> <resultMap>然后再引用:<select id=\"getAccountByUsername\" resultMap=\"accountResult\" parameterClass=\"string\"> select SIGNON.USERNAME as USERID, ACCOUNT.EMAIL, ACCOUNT.FIRSTNAME, ACCOUNT.LASTNAME, ACCOUNT.STATUS, ACCOUNT.ADDR1, ACCOUNT.ADDR2, ACCOUNT.CITY, ACCOUNT.STATE, ACCOUNT.ZIP, ACCOUNT.COUNTRY, ACCOUNT.PHONE, PROFILE.LANGPREF, PROFILE.FAVCATEGORY, PROFILE.MYLISTOPT, PROFILE.BANNEROPT, BANNERDATA.BANNERNAME from ACCOUNT, PROFILE, SIGNON, BANNERDATA where ACCOUNT.USERID = #value# and SIGNON.USERNAME = ACCOUNT.USERID and PROFILE.USERID = ACCOUNT.USERID and PROFILE.FAVCATEGORY = BANNERDATA.FAVCATEGORY <select>再打开AccountSqlMapDao.java看看: public Account getAccount(String username) { return (Account) queryForObject(\"getAccountByUsername\", username); } 思索一下,看明白其中的关联了吧。打开AccountService.JAVA: public Account getAccount(String username) { return accountDao.getAccount(username); } 打开AccountBean.java: public String newAccount() { try { accountService.insertAccount(account); account = accountService.getAccount (account.getUsername());//在这调用的 myList = catalogService.getProductListByCategory (account.getFavouriteCategoryId()); authenticated = true; repeatedPassword = null; return \"success\"; } catch (Exception e) { throw new BeanActionException (\"There was a problem creating your Account Information. Cause: \" + e, e); } } 看了半天,写个例子试试吧 package com.ibatis.jpetstore.service; import com.ibatis.dao.client.DaoManager; import com.ibatis.jpetstore.domain.*; import com.ibatis.jpetstore.persistence.DaoConfig; import com.ibatis.common.util.PaginatedList; import com.ibatis.jpetstore.persistence.iface.*; import java.util.*; public class IbatisTest { private DaoManager daoManager = DaoConfig.getDaomanager(); private AccountDao accountDao; public IbatisTest() { accountDao = (AccountDao) daoManager.getDao (AccountDao.class); Account account=accountDao.getAccount(\"j2ee\", \"j2ee\"); System.out.println(account.getFirstName()); } public static void main(String[] args) { IbatisTest ibatisTest=new IbatisTest(); } } 你还可以试试insert,update,delete。IBATIS里可是支持分页的,用起来很爽的,大家有空还是花点功夫钻研一下吧。关于DEBUG:我前两天照搬JPETSTORE的架构试着写了一个交友网站,基本上挺顺利,只是感觉DEBUG比较麻烦,通常为了找一个错花上几个小时。JBUILDER带的DEBUG我没用过,但可是肯定肯定和DELPHI上的DEBUG是有天壤之别的。而且JUNIT我也是刚开始学,也没用上。这里,我把自己比较土的办法介绍一下:一, 当你写了新的O/R MAPPING的时候,可以先写个包含MAIN方式的类测试一下,就向我上面的测试例子相同。二, 当你想跟踪变量值的时候,你可以利用IBATIS带的工具类ActionContext把变量写到SESSION里,比如你有你个FORMBEAN:UserBean.java,其中有一个方式是处理用户登录的,你为了跟踪用户的用户名和密码,可以这样写: public String logon() { try { user = userService.getUser(user.getUsername(), user.getPassword()); if (user== null ) { clear(); return \"failure\"; } else { user.setPassword(null); authenticated = true; user.setMessageCount (messageService.getMessageNewCount(user.getUserId())); ActionContext.getActionContext().setSimpleMessage (\"newCount=\"+newCount.toString()+\" toUserId=\"+user.getUserId());//写入SESSION return \" failure \";}//导入到Error.jsp }catch (Exception e){ throw new BeanActionException (\"There was a problem logoning your Account Information. Cause: \" + e, e); } } 当然你需要包含下面的语句 import com.ibatis.struts.ActionContext; Error.jsp: <%@ taglib uri=\"struts-logic\" prefix=\"logic\" %> <%@ taglib uri=\"struts-bean\" prefix=\"bean\" %> <%@ taglib uri=\"struts-html\" prefix=\"html\" %> <%@ page import=\"java.io.PrintWriter\"%> <logic:present name=\"message\"> <bean:write name=\"message\" /> </logic:present> //输出你需要的信息 <logic:present name=\"errors\"> <logic:iterate id=\"error\" name=\"errors\"> <bean:write name=\"error\" /> </logic:iterate> </logic:present> <logic:notPresent name=\"BeanActionException\"> <logic:notPresent name=\"message\"> Something happened... But no further information was provided. </logic:notPresent> </logic:notPresent> <logic:present name=\"BeanActionException\">> Error! property=\"class.name\"/> <bean:write name=\"BeanActionException\" property=\"message\"/> </logic:present> <logic:present name=\"BeanActionException\"> Stack <% Exception e = (Exception)request.getAttribute (\"BeanActionException\"); e.printStackTrace(new PrintWriter(out)); %> </logic:present> 三, 为跟踪变量,你还可以利用LOG4J把变量值写到LOG里去,这种方式很常见,不明白就去www.google.com查吧。四, 为避免写javabean出现大小写或其他的错误,强烈建议不要把BEAN当做普通CLASS来写,要用IDE 新建一个BEAN,这样IDE会帮你找出很多错误。我就吃了不少苦头。入门了吗?有问题请留言。为了贴上XML费了老鼻子劲,不轻易啊。我要开始研究SPRING和HIBERNATE啦。 返回类别: 教程 上一教程: dynafuse 1.0 在sourceforge上发布! 下一教程: Java的一些类的使用经验 您可以阅读与"从Jpetstore 开始IBATIS之旅"相关的教程: · JDBC 入门 -- 开始 · 从零开始学 Java (一) Hello World 左光 2005.4 · java之旅(7)隐藏实现 & 复用类 · Java之旅(9)多态性 · JDBC 入门(一) - 开始 |
![]() ![]() |
快精灵印艺坊 版权所有 |
首页![]() ![]() ![]() ![]() ![]() ![]() ![]() |