笔者最近和后台开发、数据库打交道不少,自然ORM这块的东西也是应用频繁。笔者和很多朋友一样原来也是一直学习和使用Hibernate,毕竟Hibernate的大名还是要响亮的多。然而金无足赤,人无完人,每一款框架都有自己的优点和缺点,喜欢Hibernate的可以继续去喜欢,今天的主角是iBATIS。
iBATIS,目前已经更名为MyBatis,从命名上更加亲切,但对于iBATIS的使用者来说却相差不大,笔者今天还是来说iBATIS,并从实际开发的绝度谈下自己的使用经验和心得体会。
想跟大家分享以下内容:iBATIS的基本使用规则、iBATIS如何调用存储过程、如何使用IBATOR插件来简化代码以及使用插件的意义。开篇还是俗一点从如何使用来讲,一步一步的深入,先入门再跟大家提要点、难点。
iBATIS基础实例:
通过本实例我们完成以下事情:
从数据库里读取Student表里的所有数据。
环境准备:
iBATIS JAR包 笔者这里使用的是2.3.4.726的JAR包
MYSQL_Connector_JAVA JAR 包 注:不同的数据库使用与其对应的JAR包
APACHE_DBCP JAR包 注:不使用也无妨
配置文件:
<?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="DBCP">
<property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
<property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost:3306/DBExample"/>
<property name="JDBC.Username" value="root"/>
<property name="JDBC.Password" value="123456"/>
<property name="Pool.MaximumActiveConnections" value="80"/>
<property name="Pool.MaximumIdleConnections" value="40"/>
<property name="Pool.MaximumWait" value="60000"/>
<property name="Pool.LogAbandoned" value="false"/>
<property name="Pool.RemoveAbandoned" value="true"/>
<property name="Pool.RemoveAbandonedTimeout" value="50000"/>
</dataSource>
</transactionManager>
<!--
JNDI方式
<transactionManager type="JDBC" >
<dataSource type="JNDI">
<property name="DataSource"
value="java:comp/env/jdbc/ibatistest"/>
</dataSource>
</transactionManager>
-->
<sqlMap resource="com/example/sqlMap/student.xml" />
</sqlMapConfig>
基本属性解释:
cacheModelsEnabled="true" <!-- 是否使用缓存机制 -->
enhancementEnabled="true" <!-- 是否针对POJO 启用字节码增强机制以提升 getter/setter的调用效能,避免使用Java Reflect 所带来的性能开销。同时这也为Lazy Loading 带来了极大的性能 提升。 -->
lazyLoadingEnabled="true" <!-- 是否启用错误日志,在开发期间建议设为"true"以方便调试 -->
errorTracingEnabled="true" <!-- 是否启用延迟加载机制 -->
maxRequests="32" <!-- 最大并发请求数(Statement 并发数) -->
maxSessions="10" <!-- 最大Session 数。即当前最大允许的并发SqlMapClient 数。maxSessions 设定必须介于 maxTransactions 和maxRequests之间 -->
maxTransactions="5" <!-- 最大并发事务数 -->
useStatementNamespaces="false" <!-- 是否使用Statement命名空间。 -->
映射文件:
<?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="stuExampleMap">
<typeAlias alias="student" type="com.huan.bean.Student"/> <!--指定别名-->
<select id="getAllStudent" resultClass="student">
<![CDATA[
select * from student
]]>
</select>
<select id="selectStudentByName" parameterClass="java.lang.String" resultClass="student">
<![CDATA[
select * from student where stuname = #stuname#
]]>
</select>
</sqlMap>
POJO:
POJO类因为篇幅我就省略了,相信大家这个都知道的。
测试代码:
Reader reader = null;
try {
/* 获得ibatis配置文件 */
reader = Resources.getResourceAsReader("IbatisConfig.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlMapClient sqlMapClient = SqlMapClientBuilder
.buildSqlMapClient(reader);
SqlMapSession session = sqlMapClient.openSession();
try {
Student stu = (Student) session.queryForList(
"stuExampleMap.getAllStudent");//这里我们通过调用SQLMAP里的ID来执行相应的SQL,前面是命名空间
System.out.println(stu.getStuname() + " " + stu.getStuid());
} catch (SQLException e) {
e.printStackTrace();
}
项目结构:
OK,相信很多朋友都顺利运行成功了,从这部分代码中我们可以看出SqlMapClient是iBATIS中的核心组件,是提供数据操作的基本平台。同时SqlMapClient提供了众多的数据操作方法并且基本上是以SQL类型分别命名:INSERT、SELECT、UPDATE、DELETE。还有一些常用的方法queryForPaginatedList()分页查询queryForMap()基于map的批量查询。
当然我们也看出iBATIS之所以是一个半自动的ORM框架是因为它的很多操作都是用SQL语句写出来的,每一步的SQL操作对应的都是一个SQL语句。那么在使用iBATIS时一项很重要的工作就成了编写SQL代码。就拿我们上面的例子来说,我们要取到所有的学生那么我们就必须写我们熟悉的 SELECT * FROM student 。编写SQL语句,这就是使用iBATIS的一项重要工作,这就是不同于Hibernate的地方,有人说使用iBATIS代码非常多那么很大一部分就是在写SQL语句。这么写肯定是有优势的,试想下这么一种情况。公司因业务需要急需招一批新人来承担新增加的业务,去完成新业务的代码,而leader并不能保证这么几位新人的水平相差无几,再加上每个人都有自己的代码风格。项目的管理和进度控制就显得很棘手。如果leader选用的是Hibernate,那么结果就比较悲剧。由于新人对Hibernate的驾驭一般都是半斤八两,就会造成运用不熟、代码烂、进度不齐等情况。很有可能就因为这些原因耽误了项目的进度,那么使用iBATIS会将所有数据库操作规范到编写SQL和配置文件上,这样既有固定的SQL规范又有统一的使用方式又防范了参差不齐的技术问题引起的.....(你懂的),进度自然便于管理。
这样iBATIS的基础实例我们已经完成了,下一步我们来看如何使用iBATIS调用存储过程。
PS:个人感觉iBATIS框架的入门还是比较简单的,会用JDBC就会使用iBATIS,因此长话短说,有什么地方说的不好的或者说错的(这个不容原谅)还请提出,不胜感激!
如需转载请务必保留出处,感谢配合!