




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ibatis介绍使用ibatis 提供的ORM机制,对业务逻辑实现人员而言,面对的是纯粹的Java对象, 这一层与通过Hibernate 实现ORM 而言基本一致,而对于具体的数据操作,Hibernate 会自动生成SQL 语句,而ibatis 则要求开发者编写具体的SQL 语句。相对Hibernate等 “全自动”ORM机制而言,ibatis 以SQL开发的工作量和数据库移植性上的让步,为系统 设计提供了更大的自由空间。作为“全自动”ORM 实现的一种有益补充,ibatis 的出现显 得别具意义。版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接作者:fellowArrayArray原文:/resource/article/44/44410_iBatis.html关键字:iBatis;ORM一、为什么要设计“通用”的东西在大多数时候,我们所需要的持久层对象(PO)大多都是一张表(or视图)对应一个类。按照Hibernate的思想,就是抛开数据库的束缚,把焦点集中到业务对象中。而很多自动化工具的确让做到了通过表结构生成对应的对象,or通过对象自动生成表。对于小项目来说,一切都是简单的;对于有规范设计的项目来说,PO的设计也不是一件困难的工作。但是对于那些业务变动频繁的项目来说,改动PO可能成了一件很繁重的工作。试想一下,假设某个表需要增加一个字段:对于Hibernate(or iBaits),首先要改配置文件,然后PO,然后DAO(也许没有),然后业务逻辑,然后JO,然后界面,etc,贯通了全部层次。恩,写程序的都不喜欢这些重复劳动,但是做企业级应用的谁不是每天在这些工作中打滚。研究过iBaits以后,发现有些通用的方法可以解决,就是设计一个通用的持久层对象。二、基于什么技术iBatis可以使用Map对象作为PO,Hibernate好像也有相关的功能(我没有细看,不确定)。iBatis执行一条指令的过程大概是这样的:其中圈圈1、2、3描述了iBatis最重要的三个对象。圈圈1:statement简单来说就是存储sql语句的配置信息,一个最简单的statement:insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (1, “Shih Tzu”)其中id属性是这个statement的唯一标识,全局不能重复。以上当然是最简单的了,没有参数也不需要返回值,但实际情况下基本都需要传入参数,下面就是介绍参数。圈圈2:参数对象主要分两种类型:parameterMap、parameterClass和Inline Parameter。其中parameterMap是配置文件定义传入参数表,如下:insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);而parameterClass是传入参数对象(JavaBean),如下:insert into PRODUCT values (#id#, #description#, #price#)Inline Parameter则是强化版的parameterClass,如下: insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)values (#id:NUMERIC:-ArrayArrayArrayArrayArrayArray#, #description:VARCHAR:NO_ENTRY#);其中第一种方法看着就复杂,实际是为了兼容老版本留下来的,所以parameterClass是我们最常用的方法。官方文档对parameterClass介绍很详细,因为这是核心之一,具体请自己查阅。有3个特性说明一下:a. parameterClass对象可以传入一个Map对象(or Map子类)。本来如果是传入JavaBean,程序会通过get/set来分析取得参数;而Map是key-value结构的,那程序会直接通过key来分析取参数。b. 看以下语句:insert into PRODUCT values (#id#, #description#, #price#, #classify.id#)蓝色部分#classify.id#翻译过来实际是product.getClassify().getId(),classify是Product对象的一个子对象。c. 在模板sql语句中除了“#”以外,还有“$”,它们两代表的意思当然不同了:select * from PRODUCT order by $preferredOrder$“#”在生成sql语句的过程中,会变成“?”,同时在参数表中增加一个参数;“$”则会直接替换成参数对象对应的值,例如上面的preferredOrder的值可能是“price”,则生成的sql语句就是:select * from PRODUCT order by price。*需要特别说明的是传入参数这一部分将会是后面正题“通用持久层对象”的核心,怎么个通用法,怎么设计模板sql语句,都是在这部分上。圈圈3:结果对象跟参数对象差不多,也有两种,resultMap和resultClass,如下:resultMap就是配置文件中预定义了要取得的字段:select * from PRODUCTresultClass则是通过分析返回的字段,来填充结果对象:SELECT PER_ID as id, PER_FIRST_NAME as firstNameFROM PERSON WHERE PER_ID = #value#跟参数对象相反,结果对象一般使用resultMap形式。引用官方的话:使用resultClass的自动映射存在一些限制,无法指定输出字段的数据类型(如果需要的话),无法自动装入相关的数据(复杂属性),并且因为需要ResultSetMetaData的信息,会对性能有轻微的不利影响。但使用resultMap,这些限制都可以很容易解决。三、正题来了,怎么做“通用持久层对象”1. 表结构:每个表都必须包含两个字段:id和parentId,其他字段按照需求来定义,其他各种索引、约束、关系之类的也按需求定义。2. 通用的持久层对象,CustomPO:public class CustomPO protected String moduleTable;/该PO对应的表名(视图名)protected int id;/表的idprotected int parentID;/父表的id(如果有的话)protected Map fieldMap;/字段Map,核心,用于存储字段及其值public String getModuleTable()public void setModuleTable(String moduleTable)public int getId()public void setId(int id)public int getParentID()public void setParentID(int parentID)public Map getFieldMap()public void setFieldMap(Map fieldMap)public void copyFieldMap(Map fieldMap)/取得字段名列表public List getFieldList()/设置字段名列表。如果fieldMap没有相应的字段,则增加,字段值为null;如果有则不增加。public void setFieldList(List fieldList)/返回字段的“字段名 - 字段值”列表,使用com.fellow.pub.util.KeyValuePair对象作为存储public List getFieldValueList()那些成员变量的get/set就没什么说的,主要说说getFieldValueList()这个方法。该方法返回一个列表,列表元素是一个key-value结构,简单来说就是把字段map序列化。在构造模板sql语句时会体现它的用途。3. iBatis对象配置文件CustomPO.xml:SELECT id, parentID$fieldList$ FROM $moduleTable$ WHERE id = #id#INSERT INTO $moduleTable$ (parentID$fieldValueList.key$)VALUES (#parentID#fieldValueList.value#)SELECT last_insert_id()UPDATE $moduleTable$ SET$fieldValueList.key$ = #fieldValueList.value# WHERE id = #id#DELETE FROM $moduleTable$ WHERE id = #id#要注意的地方如下:a. 跟一般的ibatis配置文件不一样,该配置中没有包含resultMap,使用的就是resultClass的方式(效率没那么高的那种)。当然,也可以使用resultMap,这样就要为每个表写自己的配置文件了。因此,在该设计没完成前,我暂时先使用resultClass的方式。b. 上面只列举了最简单的增删改以及按id查询,并没有更复杂的查询,为什么呢?因为我还在研究中。研究通用的模板sql的写法。4. CustomPO对应的DAO:我使用了ibaits提供的DAO框架,很好用,不单支持ibatis的框架,还支持Hibernate、JDBC等等,而且是与ibatis本身独立的,完全可以单独使用。以后就不用自己写DAO框架了。一下是该DAO接口:public interface ICustomDAO /* * 通过传入moduleTable和id取得一条记录 */CustomPO findByID(String moduleTable, int id) throws Exception;/* * 通过传入CustomPO对象取得一条记录 * param po CustomPO 该对象在传入前应该先设置moduleTable和id参数, * 并且使用setFieldList()函数设置字段列表(该设置决定所返回的字段)。 */CustomPO findByID(CustomPO po) throws Exception;/* * 通过传入moduleTable和parentID取得一条记录 */CustomPO findByParentID(String moduleTable, int parentID) throws Exception;/* * 通过传入CustomPO对象插入一条记录 * param po CustomPO 该对象在传入前应该先设置moduleTable和id参数, * 并且使用setFieldMap()函数设置“字段-值”对。 */void insert(CustomPO po) throws Exception;/* * 通过传入CustomPO对象更新一条记录 * param po CustomPO 该对象在传入前应该先设置moduleTable和id参数, * 并且使用setFieldMap()函数设置“字段-值”对。 */void update(CustomPO po) throws Exception;/* * 删除moduleTable和id所对应的记录 */void delete(String moduleTable, int id) throws Exception;我没有把所有的方法都列出来,反正挺简单的,跟一般的DAO没什么分别。另外列几个实现的片断:a. 统一的数据装填函数,需要手工把id和parentID字段去掉。protected void fill(Map result, CustomPO po) Long returnId = (Long) result.get(id);Long returnParentID = (Long) result.get(parentID);result.remove(id);result.remove(parentID);if (returnId != null) po.setId(returnIValue();if (returnParentID != null) po.setParentID(returnParentID.intValue();po.setFieldMap(result);b. 一般的查询,返回的是一个map,然后再用fill()函数/查询 Map result = (Map)this.queryForObject(customPO_findByID, po);/处理返回结果if(result = null)po = null;elsefill(result, po);c. 增删改,没有返回值,值得一提的是增加操作完成后,po里面的id会更新,具体看前面相关的statement。/增删改this.insert(customPO_insert, po);this.update(customPO_update, po);this.delete(customPO_delete, po);5. 前面是通用的部分,光是通用是不够的。因此我另外建立了一套配置文件,记录字段对应关系。看看我所定义的一个配置文件,挺简单的:。其中,name是字段名,column是字段对应数据表的字段名,type是字段类型,not-null是是否不能为空,unique是是否唯一。只有name这个属性是必填的,column如果不填默认与name相等,type默认为string,not-null和unique默认为false。配置文件的读取类在这里就省略了。为什么要自己定义一
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电容理论考试题及答案
- 灯具导购考试题及答案
- (正式版)DB15∕T 3253.4-2023 《食品生产加工小作坊生产规范 第4部分:粉条》
- 护士护理资格证考试题库及答案
- 大学茶道考试题及答案
- 《初中数学几何推理练习题教学方案》
- 市场推广活动策划书标准化模板
- 珍惜所拥有的一切13篇
- 建设工程施工安全操作承诺书5篇
- 打羽毛球500字六年级作文小学作文11篇
- 做有梦想的少年+课件-2025-2026学年统编版道德与法治七年级上册
- 医院2025年院感防控及传染病考核试题及答案
- 老乡贷贷款管理办法
- 2025年职业技能内河船员证理论知识-理论知识参考题库含答案解析(5卷)
- 安装大棚合同(标准版)
- 维稳工作汇报课件
- 企业重污染天气应急预案
- 患者身份识别管理标准WST840-2025学习解读课件
- 2025全国企业员工全面质量管理知识竞赛题库(含答案)
- 内分泌科进修总结课件
- 人民陪审员培训民事课件
评论
0/150
提交评论