ibatis 开发指南(pdf)
ibatis 开发指南<br>ibatis Quick Start............................................................................................ 5 <br>准备工作.......................................................................................................... 5 <br>构建ibatis 基础代码.................................................................................... 5 <br>ibatis 配置........................................................................................................... 11 <br>ibatis 基础语义...................................................................................................... 16 <br>XmlSqlMapClientBuilder................................................................... 16 <br>SqlMapClient ........................................................................................... 16 <br>SqlMapClient 基本操作示例.......................................................... 16 <br>OR 映射........................................................................................................... 19 <br>ibatis 高级特性...................................................................................................... 26 <br>数据关联........................................................................................................ 26 <br>一对多关联............................................................................................ 26 <br>一对一关联............................................................................................ 28 <br>延迟加载........................................................................................................ 30 <br>动态映射........................................................................................................ 31 <br>事务管理........................................................................................................ 35 <br>基于JDBC 的事务管理机制................................................................ 35 <br>基于JTA 的事务管理机制................................................................... 36 <br>外部事务管理......................................................................................... 38 <br>Cache .............................................................................................................. 39 <br>MEMORY 类型Cache 与WeakReference ........................................ 40 <br>LRU 型Cache ....................................................................................... 42 <br>FIFO 型Cache ...................................................................................... 43 <br>OSCache................................................................................................. 43 <br><br>ibatis 开发指南<br>相对Hibernate 和Apache OJB 等“一站式”ORM 解决方案而言,ibatis 是一种“半<br>自动化”的ORM 实现。<br>所谓“半自动”,可能理解上有点生涩。纵观目前主流的ORM ,无论Hibernate 还是<br>Apache OJB,都对数据库结构提供了较为完整的封装,提供了从POJO 到数据库表的全<br>套映射机制。程序员往往只需定义好了POJO 到数据库表的映射关系,即可通过Hibernate <br>或者OJB 提供的方法完成持久层操作。程序员甚至不需要对SQL 的熟练掌握, <br>Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL 并调用JDBC 接口加以执<br>行。<br>大多数情况下( 特别是对新项目,新系统的开发而言)<br>,这样的机制无往不利,大有一<br>统天下的势头。但是,在一些特定的环境下,这种一站式的解决方案却未必灵光。<br>在笔者的系统咨询工作过程中,常常遇到以下情况: <br>1. 系统的部分或全部数据来自现有数据库,处于安全考虑,只对开发团队提供几<br>条Select SQL(或存储过程)以获取所需数据,具体的表结构不予公开。<br>2. 开发规范中要求, 所有牵涉到业务逻辑部分的数据库操作,必须在数据库层由<br>存储过程实现(就笔者工作所面向的金融行业而言,工商银行、中国银行、交<br>通银行,都在开发规范中严格指定)<br>3. 系统数据处理量巨大,性能要求极为苛刻,这往往意味着我们必须通过经过高<br>度优化的SQL 语句(或存储过程)才能达到系统性能设计指标。<br>面对这样的需求,再次举起Hibernate 大刀,却发现刀锋不再锐利,甚至无法使用,<br>奈何?恍惚之际,只好再摸出JDBC 准备拼死一搏……,说得未免有些凄凉,直接使用JDBC <br>进行数据库操作实际上也是不错的选择,只是拖沓的数据库访问代码,乏味的字段读取操作<br>令人厌烦。<br>“半自动化”的ibatis,却刚好解决了这个问题。<br>这里的“半自动化”,是相对Hibernate 等提供了全面的数据库封装机制的“全自动化”<br>ORM 实现而言,“全自动”ORM 实现了POJO 和数据库表之间的映射,以及SQL 的自动<br>生成和执行。而ibatis 的着力点,则在于POJO 与SQL 之间的映射关系。也就是说,ibatis <br>并不会为程序员在运行期自动生成SQL 执行。具体的SQL 需要程序员编写,然后通过映<br>射配置文件,将SQL 所需的参数,以及返回的结果字段映射到指定POJO 。<br>使用ibatis 提供的ORM 机制,对业务逻辑实现人员而言,面对的是纯粹的Java 对象, <br>这一层与通过Hibernate 实现ORM 而言基本一致,而对于具体的数据操作,Hibernate <br>会自动生成SQL 语句,而ibatis 则要求开发者编写具体的SQL 语句。相对Hibernate 等<br>“全自动”ORM 机制而言,ibatis 以SQL 开发的工作量和数据库移植性上的让步,为系统<br>设计提供了更大的自由空间。作为“全自动”ORM 实现的一种有益补充,ibatis 的出现显<br>得别具意义。<br><br>ibatis Quick Start <br>准备工作<br>1. 下载ibatis 软件包(http://www.ibatis.com)。<br>2. 创建测试数据库,并在数据库中创建一个t_user 表,其中包含三个字段: <br>. id(int) <br>. name(varchar) <br>. sex(int) 。<br>3. 为了在开发过程更加直观,我们需要将ibatis 日志打开以便观察ibatis 运作的细节。<br>ibatis 采用Apache common_logging,并结合Apache log4j 作为日志输出组件。在<br>CLASSPATH 中新建log4j.properties 配置文件,内容如下:<br>log4j.rootLogger=DEBUG, stdout <br>log4j.appender.stdout=org.apache.log4j.ConsoleAppender <br>log4j.appender.stdout.layout=org.apache.log4j.PatternLayout <br>log4j.appender.stdout.layout.ConversionPattern=%c{1} -%m%n <br>log4j.logger.java.sql.PreparedStatement=DEBUG <br>构建ibatis 基础代码<br>ibatis 基础代码包括: <br>1. ibatis 实例配置<br>一个典型的配置文件如下(具体配置项目的含义见后): <br><?xml version="1.0" encoding="UTF-8" ?><br><!DOCTYPE sqlMapConfig<br>PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"<br>"http://www.ibatis.com/dtd/sql-map-config-2.dtd"><br><sqlMapConfig><br><settings<br>cacheModelsEnabled="true"<br>enhancementEnabled="true"<br>lazyLoadingEnabled="true"<br>errorTracingEnabled="true"<br>maxRequests="32"<br>maxSessions="10"<br>maxTransactions="5"<br>useStatementNamespaces="false" <br>/><br><transactionManager type="JDBC"><br><br><dataSource type="SIMPLE"> <br><property name="JDBC.Driver" <br>value="com.p6spy.engine.spy.P6SpyDriver"/> <br><property name="JDBC.ConnectionURL" <br>value="jdbc:mysql://localhost/sample"/> <br><property name="JDBC.Username" ="user"/> <br><property name="JDBC.Password" ="mypass"/> <br><property name=<br>value="10"/> <br><property name=value="5"/> <br><property name=<br>value="120000"/> <br><property name="Pool.TimeToWait" ="500"/> <br><property name="Pool.PingQuery" ="select 1 from <br>ACCOUNT"/> <br><property name="Pool.PingEnabled" ="false"/> <br><property name=<br>value="1"/> <br><property name=<br>value="1"/> <br></dataSource> <br></transactionManager> <br><sqlMap resource="com/ibatis/sample/User.xml"/> <br></sqlMapConfig> <br>valuevalue"Pool.MaximumActiveConnections" <br>"Pool.MaximumIdleConnections" <br>"Pool.MaximumCheckoutTime" <br>valuevaluevalue"Pool.PingConnectionsOlderThan" <br>"Pool.PingConnectionsNotUsedFor" <br>2. POJO(Plain Ordinary Java Object) <br>下面是我们用作示例的一个POJO: <br>public class User implements Serializable { <br>private Integer id; <br>private String name; <br>private Integer sex; <br>private Set addresses = new HashSet(); <br>/** default constructor */<br>public User() { <br>} <br>public Integer getId() {<br>return this.id; <br><br>} <br>public void setId(Integer id) {<br>this.id = id; <br>} <br>public String getName() {<br>return this.name; <br>} <br>public void setName(String name) {<br>this.name = name; <br>} <br>public Integer getSex() {<br>return this.sex; <br>} <br>public void setSex(Integer sex) {<br>this.sex = sex; <br>} <br>}<br>3. 映射文件<br>与Hibernate 不同。因为需要人工编写SQL 代码,ibatis 的映射文件一般采<br>用手动编写(通过Copy/Paste,手工编写映射文件也并没想象中的麻烦)。<br>针对上面POJO 的映射代码如下:<br><?xml version="1.0" encoding="UTF-8"?><br><!DOCTYPE sqlMap<br>PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"<br>"http://www.ibatis.com/dtd/sql-map-2.dtd"><br><sqlMap namespace="User"><br><typeAlias alias="user" type="com.ibatis.sample.User"/><br><select id="getUser"<br>parameterClass="java.lang.String"<br>resultClass="user"><br><![CDATA[<br>select <br>name, <br>sex <br>from t_user <br><br>where name = #name# <br>]]><br></select><br><update id="updateUser"<br>parameterClass="user"> <br><![CDATA[<br>UPDATE t_user <br>SET<br>name=#name#, <br>sex=#sex# <br>WHERE id = #id# <br>]]><br></update><br><insert id="insertUser"<br>parameterClass="user"<br>><br>INSERT INTO t_user ( <br>name, <br>sex)<br>VALUES ( <br>#name#,<br>#sex# <br>) <br></insert><br><delete id="deleteUser"<br>parameterClass="java.lang.String"><br>delete from t_user <br>where id = #value# <br></delete><br></sqlMap> <br>从上面的映射文件可以看出,通过<insert>、<delete>、<update>、<br><select>四个节点,我们分别定义了针对TUser 对象的增删改查操作。在这<br>四个节点中,我们指定了对应的SQL 语句,以update 节点为例: <br>……<br><update id="updateUser" ⑴ <br>parameterClass="user"> ⑵ <br><![CDATA[ ⑶ <br>UPDATE t_user ⑷ <br>SET ( <br><br>IBATIS Developer’s Guide Version 1.0 <br>name=#name#, ⑸ <br>sex=#sex# ⑹ <br>) <br>WHERE id = #id# ⑺ <br>]]> <br></update> <br>…… <br>⑴ ID <br>指定了操作ID,之后我们可以在代码中通过指定操作id 来执行此节点所定<br>义的操作,如:<br>sqlMap.update("updateUser",user); <br>ID 设定使得在一个配置文件中定义两个同名节点成为可能(两个update 节<br>点,以不同id 区分) <br>⑵ parameterClass <br>指定了操作所需的参数类型,此例中update 操作以<br>com.ibatis.sample.User 类型的对象作为参数,目标是将提供的User <br>实例更新到数据库。<br>parameterClass="user"中,user 为“com.ibatis.sample.User” <br>类的别名,别名可通过typeAlias 节点指定,如示例配置文件中的:<br><typeAlias alias="user" type="com.ibatis.sample.User"/><br>⑶ <![CDATA[……]]> <br>通过<![CDATA[……]]>节点,可以避免SQL 中与XML 规范相冲突的字符对<br>XML 映射文件的合法性造成影响。<br>⑷ 执行更新操作的SQL,这里的SQL 即实际数据库支持的SQL 语句, 将由<br>ibatis 填入参数后交给数据库执行。<br>⑸ SQL 中所需的用户名参数,<br>“#name#”在运行期会由传入的user 对象的name <br>属性填充。<br>⑹ SQL 中所需的用户性别参数“#sex#”, 将在运行期由传入的user 对象的<br>sex 属性填充。<br>⑺ SQL 中所需的条件参数“#id#”, 将在运行期由传入的user 对象的id 属性<br>填充。<br>对于这个示例,ibatis 在运行期会读取id 为“updateUser”的update 节点<br>的SQL 定义,并调用指定的user 对象的对应getter 方法获取属性值,并用此<br>属性值,对SQL 中的参数进行填充后提交数据库执行。<br>此例对应的应用级代码如下,其中演示了的基本使用方法:<br>String resource ="com/ibatis/sample/SqlMapConfig.xml"; <br>Reader reader; <br>ibatis SQLMap <br><br>reader = Resources.getResourceAsReader(resource); <br>XmlSqlMapClientBuilder xmlBuilder =<br>new XmlSqlMapClientBuilder(); <br>SqlMapClient sqlMap = xmlBuilder.buildSqlMap(reader); <br>//sqlMap系统初始化完毕,开始执行update操作<br>try{ <br>sqlMap.startTransaction(); <br>User user = new User(); <br>user.setId(new Integer(1)); <br>user.setName("Erica"); <br>user.setSex(new Integer(1)); <br>sqlMap.update("updateUser",user); <br>sqlMap.commitTransaction(); <br>finally{ <br>sqlMap.endTransaction(); <br>} <br>其中,SqlMapClient 是ibatis 运作的核心,所有操作均通过SqlMapClient <br>实例完成。<br>可以看出,对于应用层而言,程序员面对的是传统意义上的数据对象,而非JDBC <br>中烦杂的ResultSet,这使得上层逻辑开发人员的工作量大大减轻,同时代码更<br>加清晰简洁。<br>数据库操作在映射文件中加以定义,从而将数据存储逻辑从上层逻辑代码中独立<br>出来。<br>而底层数据操作的SQL 可配置化,使得我们可以控制最终的数据操作方式,通过<br>SQL 的优化获得最佳的数据库执行效能,这在依赖SQL 自动生成的“全自动”ORM <br>机制中是所难以实现的。<br><br>ibatis 配置<br>结合上面示例中的ibatis 配置文件。下面是对配置文件中各节点的说明:<br><?xml version="1.0" encoding="UTF-8" ?> <br>PUBLIC <br>"> <br><sqlMapConfig> <br><settings ⑴<br>cacheModelsEnabled=<br>enhancementEnabled=<br>lazyLoadingEnabled=<br>errorTracingEnabled=<br>maxRequests=<br>maxSessions=<br>maxTransactions=<br>useStatementNamespaces=<br>/> <br><transactionManager type="JDBC"> ⑵<br><dataSource type="SIMPLE"> ⑶<br><property name="JDBC.Driver" <br>value="com.p6spy.engine.spy.P6SpyDriver"/> <br><property name="JDBC.ConnectionURL" <br>value="jdbc:mysql://localhost/sample"/> <br><property name="JDBC.Username" ="user"/> <br><property name="JDBC.Password" ="mypass"/> <br><property name=<br>value="10"/> <br><property name=value="5"/> <br><property name=<br>value="120000"/> <br><property name="Pool.TimeToWait" ="500"/> <br><property name="Pool.PingQuery" ="select 1 from <br>ACCOUNT"/> <br><property name="Pool.PingEnabled" ="false"/> <br><property name=<br>value="1"/> <br><property name=<br>value="1"/> <br></dataSource> <br><!DOCTYPE sqlMapConfig <br>"-//iBATIS.com//DTD SQL Map Config 2.0//EN" <br>"http://www.ibatis.com/dtd/sql-map-config-2.dtd"true" <br>"true" <br>"true" <br>"true" <br>"32" <br>"10" <br>"5" <br>"false" <br>valuevalue"Pool.MaximumActiveConnections" <br>"Pool.MaximumIdleConnections" <br>"Pool.MaximumCheckoutTime" <br>valuevaluevalue"Pool.PingConnectionsOlderThan" <br>"Pool.PingConnectionsNotUsedFor" <br><br></transactionManager> <br><sqlMap resource="com/ibatis/sample/User.xml"/> ⑷ <br><sqlMap resource="com/ibatis/sample/Address.xml"/> <br></sqlMapConfig> <br>⑴ Settings 节点<br>参数描述<br>cacheModelsEnabled 是否启用SqlMapClient 上的缓存机制。<br>建议设为"true" <br>enhancementEnabled 是否针对POJO 启用字节码增强机制以提升<br>getter/setter 的调用效能,避免使用Java <br>Reflect 所带来的性能开销。<br>同时,这也为Lazy Loading 带来了极大的性能<br>提升。<br>建议设为"true" <br>errorTracingEnabled 是否启用错误日志,在开发期间建议设为"true" <br>以方便调试<br>lazyLoadingEnabled 是否启用延迟加载机制,建议设为"true" <br>maxRequests 最大并发请求数(Statement 并发数) <br>maxTransactions 最大并发事务数<br>maxSessions 最大Session 数。即当前最大允许的并发<br>SqlMapClient 数。<br>maxSessions 设定必须介于<br>maxTransactions 和maxRequests 之间,即<br>maxTransactions<maxSessions=< <br>maxRequests <br>useStatementNamespaces 是否使用Statement 命名空间。<br>这里的命名空间指的是映射文件中,sqlMap 节点<br>的namespace 属性,如在上例中针对t_user <br>表的映射文件sqlMap 节点: <br><sqlMap namespace="User"> <br>这里,指定了此sqlMap 节点下定义的操作均从<br>属于"User"命名空间。<br>在useStatementNamespaces="true"的情<br>况下,Statement 调用需追加命名空间,如:<br><br>⑵ transactionManager 节点<br>sqlMap.update("User.updateUser",use <br>r); <br>否则直接通过Statement 名称调用即<br>sqlMap.update("updateUser",user); <br>但请注意此时需要保证所有映射<br>定义无重名。<br>可,如:<br>文件中,<br>Statement <br>transactionManager 节点定义了ibatis 的事务管理器,目前提供了以下几<br>种选择: <br>. JDBC <br>通过传统JDBC Connection.commit/rollback 实现事务支持。<br>. JTA <br>使用容器提供的JTA 服务实现全局事务管理。<br>. EXTERNAL <br>外部事务管理, 如在EJB 中使用ibatis,通过EJB 的部署配置即可实现自<br>动的事务管理机制。此时ibatis 将把所有事务委托给外部容器进行管理。<br>此外,通过Spring 等轻量级容器实现事务的配置化管理也是一个不错的选<br>择。关于结合容器实现事务管理,参见“高级特性”中的描述。<br>⑶ dataSource 节点<br>dataSource 从属于transactionManager 节点,用于设定ibatis 运行期使<br>用的DataSource 属性。<br>type 属性: dataSource 节点的type属性指定了dataSource 的实现类型。<br>可选项目: <br>. SIMPLE: <br>SIMPLE 是ibatis 内置的dataSource 实现,其中实现了一个简单的<br>数据库连接池机制,对应ibatis 实现类为<br>com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory 。<br>. DBCP: <br>基于Apache DBCP 连接池组件实现的DataSource 封装,当无容器提<br>供DataSource 服务时,建议使用该选项,对应ibatis 实现类为<br>com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory 。<br>. JNDI: <br>使用J2EE 容器提供的DataSource 实现,DataSource 将通过指定<br>的JNDI Name 从容器中获取。对应ibatis 实现类为<br>com.ibatis.sqlmap.engine.datasource.JndiDataSourceFacto <br>ry。<br>dataSource 的子节点说明(SIMPLE
剩余47页未读,继续阅读
- 粉丝: 2
- 资源: 15
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- ExcelVBA中的Range和Cells用法说明.pdf
- 基于单片机的电梯控制模型设计.doc
- 主成分分析和因子分析.pptx
- 共享笔记服务系统论文.doc
- 基于数据治理体系的数据中台实践分享.pptx
- 变压器的铭牌和额定值.pptx
- 计算机网络课程设计报告--用winsock设计Ping应用程序.doc
- 高电压技术课件:第03章 液体和固体介质的电气特性.pdf
- Oracle商务智能精华介绍.pptx
- 基于单片机的输液滴速控制系统设计文档.doc
- dw考试题 5套.pdf
- 学生档案管理系统详细设计说明书.doc
- 操作系统PPT课件.pptx
- 智慧路边停车管理系统方案.pptx
- 【企业内控系列】企业内部控制之人力资源管理控制(17页).doc
- 温度传感器分类与特点.pptx
评论1