1、 什么叫ibatis
⑴、概念(官方文档)
MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(PlanOld Java Objects,普通的Java对象)映射成数据库中的记录。
总结:dao层,操作数据库,提供对sql的封装,作用跟jdbc,hibernate类似。
2.0版本:ibatis 网址:http://ibatis.apache.org/
3.0版本:mybatis 网址:http://www.mybatis.org/
时间分隔点:2010/06/16
从3.0之后,移往google code :http://code.google.com/p/mybatis/wiki/Welcome
⑵、特点
相对Hibernate和Apache OJB 等“一站式”ORM解决方案而言,ibatis 是一种“半
自动化”的ORM实现。 纵观目前主流的ORM,无论Hibernate 还是
Apache OJB,都对数据库结构提供了较为完整的封装,提供了从POJO 到数据库表的全
套映射机制。程序员往往只需定义好了POJO 到数据库表的映射关系,即可通过Hibernate 或者OJB 提供的方法完成持久层操作。程序员甚至不需要对SQL 的熟练掌握,Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL 并调用JDBC 接口加以执 行。 ---- 摘自官方资料的一段话
总结:ibatis是一种半自动化的ORM, 需要手工编写sql ;hibernate不需要手工编写sql。
2、 优点
⑴、iBATIS被广泛认为是最简单的一种持久化框架。
sql可以写在xml中,结构清晰,灵活配置。
⑵、文件归类,select 后的字须定义到标签中,可以实现部分代码复用。
⑶、执行sql后,返回的结果集自动封装。类似以下代码,均可省略。
while (rs.next()) {
so = new SoQueryMVO();
so.setQryFlag(rs.getString("qryFlag"));// so.setSoNbr(rs.getString("SO_NBR"));
so.setExtSoNbr(rs.getString("EXT_SO_NBR"));
so.setCoNbr(rs.getString("CO_NBR"));
so.setSoStaffName(rs.getString("SO_STAFF_NAME"));
so.setSoWorkAreaName(rs.getString("SO_WORK_AREA_NAME"));
so.setApplDate(rs.getTimestamp("APPL_DATE"));
so.setContactResult(rs.getString("CONTACT_RESULT"));
so.setBillType(rs.getString("BILL_TYPE"));
so.setPaySts(rs.getString("PAY_STS"));
res.add(so);
}
⑷、MyBatis真正的力量是在映射语句中。这里是奇迹发生的地方。对于所有的力量,SQL映射的XML文件是相当的简单。当然如果你将它们和对等功能的JDBC代码来比较,你会发现映射文件节省了大约95%的代码量。MyBatis的构建就是聚焦于SQL的,使其远离于普通的方式。
简洁的代码和简单的配置使得使用iBATIS所需的代码量可以减少到了相应JDBC代码的62%
总结一下:可以省代码。
⑸、动态sql, 没觉得有多好。
⑹、iBATIS改进了应用的设计方式以确保未来的可维护性,后期可维护性增加。
⑺、基于xml的,所以适合多平台。
iBATIS可以用任何具有完备功能的编程语言来实现。
3、 缺点
⑴、开源的东西,文档资料少,官方说明文档太简单,真正有应用价值的信息不多。
以官方文档为例:60%左右的代码讲述环境配置,即相当于我们的connection-config.xml配置,及创建一个链接, 对于服务开通来说,使用的是java代码,连接oracle库,一旦配置好环境,对于开发人员来说,专业于某些功能点,业务逻辑、流程、配置等的实现,在以后的开发过程中,其实很少关注环境。
这部分功能实现可以放到工具类中,对我们来说,文章中的说明没有什么大的使用价值。
⑵、实现了结果集自动封装,一把双刃剑。
①、返回的结果集封装结果单一,不能实现灵活封装。如Map<key=id ,value =vo >
②、不支持嵌套vo对象,如果有同名字段,会覆盖。
关联查询,需要返回很多信息,很有可能需要复写MVO,把嵌套的vo,拿出来,放到第一层的vo里面。
因为mvo改变,原来jsp页面上使用soMVO.soResMVO.resId,诸如这种形势,有可能修改前台页面。
③、以查询为例,入参单一,只有一个入参,如果有两个以上的参数,必须定义到一个对象中,感觉不灵活。
当然可以用paraMap方式进行配置,麻烦,感觉还不如定义到一个对象中。
④、部分写在dao中的逻辑,改动起来麻烦。目前的目标是只修改domIpml类,其它的尽量不修改,现在看来,
如此肯定不行了。部分复杂的逻辑靠标签无法实现。
if (!StringUtil.isBlank(so.getChbAccNbr())&& !StringUtil.isBlank(so.getAccNbr())) {
// 增加批量查询业务号码
isAvaibleCondition = true;
String tempAccNbr[] = so.getAccNbr().split(";");
List accNbrList = (List) CollectionFactory
.createCollection(CollectionFactory.COLLECTION_LIST);
for (int i = 0; i < tempAccNbr.length; i++) {
accNbrList.add(tempAccNbr[i].trim());
}
if (accNbrList.size() == 1) {
sql.append(" AND SO.SO_NBRIN ( ");
sql.append(" SELECTDISTINCT SO_NBR FROM SO_ACC_NBR where ");
if(!StringUtil.isBlank(so.getLocalNetId())) {
sql.append(" local_net_id=:lcId ");
sql.setLong("lcId", so.getLocalNetId());
sql.append(" andSTS = 'A' AND ACC_NBR LIKE :accNbr )");
sql.setString("accNbr", so.getAccNbr().trim() +"%");
} else {
sql.append(" STS ='A' AND ACC_NBR LIKE :accNbr )");
sql.setString("accNbr", so.getAccNbr().trim() +"%");
}
} else {
sql.append(" AND SO.SO_NBRIN ( ");
sql.append(" SELECTDISTINCT SO_NBR FROM SO_ACC_NBR where ");
if(!StringUtil.isBlank(so.getLocalNetId())) {
sql.append(" local_net_id=:lcId AND STS = 'A' ");
sql.setLong("lcId", so.getLocalNetId());
} else {
sql.append(" STS ='A' ");
}
int i = 0;
while (i <accNbrList.size()) {
if (i == 0)
sql.append(" AND (ACC_NBR = :accNbr");
else
sql.append(" OR ACC_NBR = :accNbr");
sql.append(""+ i + "");
sql.setString("accNbr" + i + " ", accNbrList.get(i)+ "");
i++;
}
sql.append(" ))");
}
}
⑤、其它
⑶、sql写在xml, 没有办法打断点,调试非常不方便,及其浪费时间。
有可以十几分钟写的一个大sql,完事后,调试了一天还是编译性错误,完全不夸张,很多可能。
⑷、日志输出不完全,可能是我还没有找到方法。
无法输出预编译赋值之后的sql ,查看不方便 (原来咱们系统中使用Sql.log实现)
⑸、错误信息提示异样 ,报错信息比较混乱,有些时间没有参考价值,没有起到提示作用。
⑹、文档少,现有的文档提供的标签,也不能完全满足我们的需求
如有if 没有else,形式上感到别扭,某些
大小写是否敏感?
Ibatis适用于小项目,简单的业务逻辑映射,尤其是单表操作,很方便。
4、 尚未进行验证的已知功能
⑴、分页查询
⑵、性能问题,介于jdbc,和hibernate之间,理论上也是这样。
⑶、是否有代码生成工具,根据xml文件,或者根据xml生成dao类。