1.下载iBatis包,配置开发环境
2.创建测试数据库,并在数据库中创建一个t_user 表,其中包含三个字段: id(int),name(varchar),sex(int)。
3.配置log4j.properties文件: log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%c{1} - %m%n log4j.logger.java.sql.PreparedStatement=DEBUG
4.iBatis配置文件设定如下: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd "> <sqlMapConfig> <settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" errorTracingEnabled="true" maxRequests="32" maxSessions="10" maxTransactions="5" useStatementNamespaces="false" /> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="com.p6spy.engine.spy.P6SpyDriver"/> <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/sample"/> <property name="JDBC.Username" value="user"/> <property name="JDBC.Password" value="mypass"/> <property name="Pool.MaximumActiveConnections" value="10"/> <property name="Pool.MaximumIdleConnections" value="5"/> <property name="Pool.MaximumCheckoutTime" value="120000"/> <property name="Pool.TimeToWait" value="500"/> <property name="Pool.PingQuery" value="select 1 from ACCOUNT"/> <property name="Pool.PingEnabled" value="false"/> <property name="Pool.PingConnectionsOlderThan" value="1"/> <property name="Pool.PingConnectionsNotUsedFor" value="1"/> </dataSource>
</transactionManager> <sqlMap resource="com/ibatis/sample/User.xml"/> </sqlMapConfig>
其中各个节点含义如下:
⑴ Settings 节点 参数 描述 cacheModelsEnabled 是否启用SqlMapClient 上的缓存机制。 建议设为"true" enhancementEnabled 是否针对POJO启用字节码增强机制以提升getter/setter的调用效能,避免使用Java Reflect所带来的性能开销。同时,这也为Lazy Loading带来了极大的性能提升。建议设为"true"
errorTracingEnabled 是否启用错误日志,在开发期间建议设为"true" 以方便调试
lazyLoadingEnabled 是否启用延迟加载机制,建议设为"true"
maxRequests 最大并发请求数(Statement 并发数)
maxTransactions 最大并发事务数
maxSessions 最大Session 数。即当前最大允许的并发 SqlMapClient 数。 maxSessions设定必须介于 maxTransactions和maxRequests之间,即 maxTransactions<maxSessions=< maxRequests useStatementNamespaces 是否使用Statement命名空间。
这里的命名空间指的是映射文件中,sqlMap节点 的namespace属性,如在上例中针对t_user 表的映射文件sqlMap节点: <sqlMap namespace="User">
这里,指定了此sqlMap节点下定义的操作均从 属于"User"命名空间。 在useStatementNamespaces="true"的情况下,Statement调用需追加命名空间,如: sqlMap.update("User.updateUser",user); 否则直接通过Statement名称调用即可,如: sqlMap.update("updateUser",user); 但请注意此时需要保证所有映射文件中,Statement定义无重名。
⑵ transactionManager节点 transactionManager 节点定义了ibatis 的事务管理器,目前提供了两种内置选择: Ø JDBC 通过传统JDBC Connection.commit/rollback实现事务支持。 Ø JTA 使用容器提供的JTA服务实现全局事务管理。 Ø EXTERNAL 外部事务管理,如在EJB中使用ibatis,通过EJB的部署配置即可实现自动的事务管理机制。此时ibatis 将把所有事务委托给外部容器进行管理。此外,通过Spring 等轻量级容器实现事务的配置化管理也是一个不错的选择。关于结合容器实现事务管理,参见“高级特性”中的描述。
⑶ dataSource节点 dataSource从属于transactionManager节点,用于设定ibatis运行期使用的DataSource属性。 type属性: dataSource节点的type属性指定了dataSource的实现类型。 可选项目: Ø SIMPLE: SIMPLE是ibatis内置的dataSource实现,其中实现了一个简单的数据库连接池机制, 对应ibatis 实现类为 com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。 Ø DBCP: 基于Apache DBCP 连接池组件实现的DataSource 封装,当无容器提供DataSource 服务时,建议使用该选项,对应ibatis 实现类为com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。 Ø JNDI: 使用J2EE 容器提供的DataSource 实现,DataSource 将通过指定的JNDI Name 从容器中获取。对应ibatis 实现类为com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory。
dataSource的子节点说明(SIMPLE&DBCP):
参数 描述 JDBC.Driver JDBC 驱动。 如:org.gjt.mm.mysql.Driver JDBC.ConnectionURL 数据库URL。 如:jdbc:mysql://localhost/sample 如果用的是SQLServer JDBC Driver,需要在url后追加SelectMethod=Cursor以获得JDBC事务的多statement支持。 JDBC.Username: 数据库用户名 JDBC.Password: 数据库用户密码 Pool.MaximumActiveConnections:数据库连接池可维持的最大容量。 Pool.MaximumIdleConnections:数据库连接池中允许的挂起(idle)连接数。 以上子节点适用于SIMPLE 和DBCP 模式,分别针对SIMPLE 和DBCP 模式的DataSource私有配置节点如下: SIMPLE: 参数 描述 Pool.MaximumCheckoutTi me 数据库联接池中,连接被某个任务所允许占用的最大时间,如果超过这个时间限定,连接将被强制收回。(毫秒) Pool.TimeToWait 当线程试图从连接池中获取连接时,连接池中无可用连接可供使用,此时线程将进入等待状态, 直到池中出现空闲连接。此参数设定了线程所允许等待的最长时间。(毫秒) Pool.PingQuery 数据库连接状态检测语句。 某些数据库在连接在某段时间持续处于空闲状态时会将其断开。而连接池管理器将通过此语句检测池中连接是否可用。 检测语句应该是一个最简化的无逻辑SQL。 如“select 1 from t_user”,如果执行此语句成功,连接池管理器将认为此连接处于可用状态。 Pool.PingEnabled 是否允许检测连接状态。 Pool.PingConnectionsOlderThan 对持续连接时间超过设定值(毫秒)的连接进行检测。 Pool.PingConnectionsNotUsedFor 对空闲超过设定值(毫秒)的连接进行检测。 DBCP: 参数 描述 Pool.MaximumWait 当线程试图从连接池中获取连接时,连接池中无可用连接可供使用,此时线程将进入等待状态,直到池中出现空闲连接。此参数设定了线程所允许等待的最长时间。(毫秒) Pool.ValidationQuery 数据库连接状态检测语句。某些数据库在连接在某段时间持续处于空闲状态 时会将其断开。而连接池管理器将通过此语句检测池中连接是否可用。检测语句应该是一个最简化的无逻辑SQL。 如“select 1 from t_user”,如果执行此语句成功,连接池管理器将认为此连接处于可用状态。 Pool.LogAbandoned 当数据库连接被废弃时,是否打印日志。 Pool.RemoveAbandonedTimeout数据库连接被废弃的最大超时时间 Pool.RemoveAbandoned 当连接空闲时间超过 RemoveAbandonedTimeout时,是否将其废弃。 JNDI由于大部分配置是在应用服务器中进行,因此ibatis中的配置相对简单,下面是分别使用JDBC和JTA事务管理的JDNI配置: 使用JDBC事务管理的JNDI DataSource配置 <transactionManager type="JDBC" > <dataSource type="JNDI"> <property name="DataSource" value="java:comp/env/jdbc/myDataSource"/> </dataSource> </transactionManager> <transactionManager type="JTA" > <property name="UserTransaction" value="java:/ctx/con/UserTransaction"/> <dataSource type="JNDI"> <property name="DataSource" value="java:comp/env/jdbc/myDataSource"/> </dataSource> </transactionManager> ⑷ sqlMap节点 sqlMap 节点指定了映射文件的位置,配置中可出现多个sqlMap 节点,以指定项目内所包含的所有映射文件。 5.编写POJO类: public class User implements Serializable { private Integer id; private String name; private Integer sex; private Set addresses = new HashSet(); /** default constructor */ public User() { } public Integer getId() { return this.id;} public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Integer getSex() { return this.sex; } public void setSex(Integer sex) { this.sex = sex; } } 6.编写映射文件User.xml如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd "> <sqlMap namespace="User"> <typeAlias alias="user" type="com.ibatis.sample.User"/> <select id="getUser" parameterClass="java.lang.String" resultClass="user"> <![CDATA[ select name, sex from t_userwhere name = #name# ]]> </select> <update id="updateUser" parameterClass="user"> <![CDATA[ UPDATE t_user SET name=#name#, sex=#sex# WHERE id = #id# ]]> </update> <insert id="insertUser" parameterClass="user" > INSERT INTO t_user ( name, sex) VALUES ( #name#, #sex# )</insert> <delete id="deleteUser" parameterClass="java.lang.String"> delete from t_user where id = #value# </delete> </sqlMap> 7.编写操作类,部分代码如下: String resource ="com/ibatis/sample/SqlMapConfig.xml"; Reader reader; reader = Resources.getResourceAsReader(resource);XmlSqlMapClientBuilder xmlBuilder = new XmlSqlMapClientBuilder(); SqlMapClient sqlMap = xmlBuilder.buildSqlMap(reader); //sqlMap系统初始化完毕,开始执行update操作 try{ sqlMap.startTransaction(); User user = new User(); user.setId(new Integer(1)); user.setName("Erica"); user.setSex(new Integer(1)); sqlMap.update("updateUser",user); sqlMap.commitTransaction(); finally{ sqlMap.endTransaction(); }