博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个对iBatis的总结写的不错(转载)
阅读量:5819 次
发布时间:2019-06-18

本文共 11184 字,大约阅读时间需要 37 分钟。

转载自:

一、 ibatis介绍

ibatis始于2002年,2010年更名为mybatis,并迁移到了googlecode.com里。

ibatis最初侧重于密码软件的开发,现在是一个基于Java的持久层框架。

 

Hibernate与ibatis相比而言:

1、Hibernate是“一站式”ORM解决方案而言,ibatis是一种“半自动化”的ORM实现。

2、Ibatis需要手写sql语句,也可以生成一部分,Hibernate则基本上可以自动生成,偶而需要写一些Hql。

3、维护性方面:iBatis 的 sql 都保存到单独的文件中。而Hibernate在有些情况下可能会在java 代码中保sql/hql。

 

ibatis优点总结:

1、ibatis把sql语句从Java源程序中独立出来,放在单独的XML文件中编写,给程序的维护带来了很大便利。 

2、ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,大大简化了Java数据库编程的重复工作。 

3、简单易于学习,易于使用, 非常实用。 

4、因为Ibatis需要程序员自己去编写sql语句,程序员可以结合数据库自身的特点灵活控制sql语句,因此能够实现比hibernate等全自动ORM框架更高的查询效率,能够完成复杂查询。 

5、阿里巴巴、慧点科技等多家知名软件公司都使用Ibatis。

 

二、 ibatis简单入门

1、  创建一个java项目

2、  导入驱动包和ibatis的jar包:ibatis-2.jar 和 classes12.jar。

3、  添加一个SqlMapConfig.xml到src下面,在xml中写入以下内容:

 

[html] 
  1. <?xml version="1.0"encoding="UTF-8" ?>  
  2. <!DOCTYPE sqlMapConfig       
  3.     PUBLIC"-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"       
  4.    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">  
  5. <sqlMapConfig>  
  6.  <transactionManager type="JDBC"commitRequired="false">  
  7.    <dataSource type="SIMPLE">  
  8.      <property name="JDBC.Driver"value="oracle.jdbc.driver.OracleDriver"/>  
  9.      <property name="JDBC.ConnectionURL"value="jdbc:oracle:thin:@localhost:1521:ORAC"/>  
  10.      <property name="JDBC.Username" value="test"/>  
  11.      <property name="JDBC.Password" value="test"/>  
  12.     </dataSource>  
  13.  </transactionManager>  
  14.   <sqlMapresourcesqlMapresource="com/cn/thinkmore/bean/BuMen_SqlMap.xml"/>  
  15. </sqlMapConfig>  

4、创建pojo,对应数据库中的一个表,

 

 

[java] 
  1. public class User{  
  2.          private String id;  
  3.      private String name;  
  4.      private String password;  
  5.      getter与setter方法…..  

 

 

4、  创建此pojo的xml映射文件,可自定义

User.xml

 

[html] 
  1. <?xml version="1.0"encoding="UTF-8" ?>  
  2. <!DOCTYPE sqlMap       
  3.    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"       
  4.    "http://ibatis.apache.org/dtd/sql-map-2.dtd">  
  5. <sqlMap>  
  6.  <select id="selectAll"resultClass="com.cn.thinkmore.bean.User">  
  7.      select id,name,password from User  
  8.  </select>  
  9. </sqlMap>  

5、  测试

 

 

[java] 
  1. import java.io.IOException;  
  2. import java.io.Reader;  
  3. import java.sql.SQLException;  
  4. import java.util.List;  
  5.    
  6. importcom.ibatis.common.resources.Resources;  
  7. importcom.ibatis.sqlmap.client.SqlMapClient;  
  8. importcom.ibatis.sqlmap.client.SqlMapClientBuilder;  
  9.    
  10. public class TestIbatis {  
  11.     private static SqlMapClient sqlMapClient;  
  12.     static {  
  13.         Reader reader =Resources.getResourceAsReader("SqlMapConfig.xml");  
  14.         sqlMapClient =SqlMapClientBuilder.buildSqlMapClient(reader);  
  15.         reader.close();     
  16.     }  
  17.     public static void main(String[] args) {  
  18.              List list =sqlMapClient.queryForList("selectAll");  
  19.    }  
  20. }  

6、  运行成功

 

 

三、 ibatis核心技术

1、  ibatis配置文件:sqlMapConfig.xml

<sqpMapConfig/> 父标签

<properties/> 标签,引用属性文件,用于引用properties属性文件

例如:url=jdbc:oracle:thin:@localhost:1521:ORAC

可以在xml文件中,这样调用:

<propertyname=" JDBC.ConnectionURL" value="${url}"/>

<settings/>设置属性,用于配置和优化SqlMap实例的各种属性

 maxRequests:同时执行SQL语句的最大线程数。大于这个值的时候,后面的线程将被阻塞,直到有线程执行完成,不同的数据库有不同的限制值,但是任何数据库通常应该把此属性值设置为maxTransactions的10倍,并且总是大于maxSessions和maxTransactions,减少此值可能会提高性能(默认值 512)

maxSessions:同一时间内活动的最大Session数,一个Session可以是代码请求的显式Session,也可以是当线程使用SqlMapClient实例(执行一条语句)自动获得的Session,它应该总是大于或者等于maxTransactions

并且小于maxRequests,减小这个参数值可能会减少内存使用(默认值 128)

maxTransactions:同时进入SqlMapClient.startTransaction()的最大线程数,大于这个值的线程将阻塞直到另一个线程退出。不同的数据库有不同的限制值,但任何数据库都有这些限制,这个参数值应该总是小于或等于maxSessions,并总是远远小于maxRequests,减小这个参数值可能会提高性能(默认值 32)

cacheModelsEnabled:全局性的启用或禁用SqlMapClient的所有缓存Model,在调试程序时使用(默认值 true)

lazyLoadingEnabled:全局性的启用或禁用SqlMapClient的所有延迟加载,在调试程序时使用(默认值 true)

useStatementNamespaces:如果启用本属性,则必须使用全限定名来引用执行命令,例如:sqlMapClient.queryForObject("映射文件名.方法名");

(默认值 false)     

 

<transactionManager/>  

定义事务管理器,包含一个唯一的属性type,用以指定使用的事务管理器类型。有三种不同的选择:JDBC,JTA,EXTERNAL

JDBC:让jdbc来管理事务(常用)

JTA:使用JTA全局事务

EXTERNAL:可以让开发人员来管理事务

                                                          

<dataSource/>                      

定义数据源,type="SIMPLE"定义一个基本的实现,基于ibatis的SimpleDataSource连接池实现,其别名为SIMPLE

  

<property/>                          

设置数据源参数

JDBC.Driver           JDBC驱动程序类名

JDBC.ConnectionURL    数据库URL

JDBC.Username         数据库用户名

JDBC.Password         数据库密码

JDBC.DefaultAutoCommit连接池中所有连接默认的自动提交模式(默认为true)

Pool.MaximumActiveConnections数据库连接池可维持的最大容量 默认值为10

Pool.MaximumIdleConnections  数据库连接池中允许的挂起连接数,默认值为5

 

<sqlMap/>                           

引用映射文件

 

 

1.POJO映射文件---SqlMap.xml:

 

<sqlMap namespace="BuMen">

     此配置文件的父标签,所有标签都需要配置在此标签内部,它可以设定一个命名空间,但是通常没有作用。

 

<typeAlias alias="BuMen" type="com.cn.thinkmore.bean.BuMen"/>

为POJO设置一个别名,为了在使用SQL标签的时候引用,例如:

<select id="selectOne"resultClass="BuMen">

type属性是指定POJO的包名+类名,alias属性是给此POJO定义一个别名,为以后调用

 

<resultMap id="BuMenResult"class="BuMen">

    <result property="bid" javaType="java.lang.String" column="bid" jdbcType="varchar2" nullValue="null"/>

    <result property="bumenname" column="bumenname"/>

    <result property="bumencode" column="bumencode"/>

</resultMap>

设置结果集映射,优先选用resultClass而不是resultMap,此标签大多时候用于存储过程的处理

id:引用的值

      class:映射的POJO

      result标签是指定每一个属性

      property:指定关联的属性名

      javaType:指定属性的类型

      column:指定此属性关联的字段名

      jdbcType:指定字段的类型

      nullValue:当此属性没有取到值的时候,指定的默认值

通常情况下,只需要设置property和column属性。

 

下面介绍在ibatis中怎么操作数据库的增删改查,对应的标签分别是insert, delete,update,select,在这四个标签中,都有id,resultClass,parameterClass常用属性:

 

id:指定要调用的名字

parameterClass:指定传入参数的类型,例如:parameterClass="com.cn.thinkmore.bean.BuMen",也可以设定为基本类型

parameterMap:指定传入参数的类型,(很少使用)

resultClass:指定返回的类型,例如:

resultClass="com.cn.thinkmore.bean.BuMen",也可以设定为基本类型

resultMap:指定返回的类型,(很少使用)

 

    注意:为了避免特殊符号与XML的标签冲突,所以有时候需要使用

<![CDATA[select * fromBuMen where bid<#bid#]]>的方式来编写SQL

 

<select id="selectAll" resultClass="com.cn.thinkmore.bean.BuMen">

      selectbid,bumenname,bumencode from BuMen

</select>

定义一个SQL的插入语句,ibatis会自动根据select语句中的字段名,调用对应POJO 的set方法设定属性值,如上例中,ibatis会调用setBid,setBumenname,setBumencode方法将Select语句返回的数据,装载到相应的POJO实例属性中。

 

<insert id="insertObj" parameterClass="com.cn.thinkmore.bean.BuMen">

    insert intoBuMen(bid,bumenname,bumencode) values (#bid#,#bumenname#,#bumencode#)

</insert>

定义一个SQL的插入语句,ibatis会自动根据select语句中的字段名,调用对应POJO 的get方法设定属性值,如上例中,ibatis会调用getBid,getBumenname,getBumencode方法将POJO实例属性中的值插入了SQL语句中。

 

<delete id="deleteObj" parameterClass="int">

    delete from BuMen where bid=#bid#

</delete>

     定义一个SQL的删除语句,parameterClass属性定义传入的类型为Integer类型,它会自动添加到#bid#位置,现在的#bid#不会再调用set或者get,ibatis会自动把它当做填充符使用。

 

<update id="updateObj" parameterClass="bumen">

    update bumen setbid=#bid#,bumenname=#bumenname#,bumencode=#bumencode# wherebumencode=#bumencode#

</update>

定义一个SQL的更新语句。 

 

 

一.使用SqlMapClient操作

1. SqlMapClient的开发:

每一个Dao或者Service都会有一个SqlMapClient的实例,通常情况,我们并不希望外部能访问此实例对象,所以我们需要这样做:

      private static SqlMapClient sqlMapper;

为了让程序在开始的时候就可以操作数据库,所以,我们还需要一个静态方法来自动创建这个实例:

    static {

        try {

          Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");

          sqlmapClient =SqlMapClientBuilder.buildSqlMapClient(reader);

          reader.close();

        } catch (IOExceptione) {

          //Fail fast.

          throw newRuntimeException("Something badhappened while building the SqlMapClient instance." + e, e);

        }

      }

这样做了以后,我们就可以创建我们想操作数据库的方法了。

我们在第二章里面已经学习怎样快速搭建ibatis并且把它使用起来了,现在来说说,开发中,有哪些方法可以让我们操作,这些方法都需要SqlMapClient的实例来调用。

 

1. sqlmapClient.queryForList(Stringid)  基于一个id指定的sql来执行查询,返回一个List

2. sqlmapClient.queryForList(Stringid,Object param) 基于一个id和一个字符串参数来执行查询,返回一个List

3. sqlmapClient.queryForList(Stringid,Object pojo) 基于一个id和一个pojo参数来执行查询,返回一个List

4. sqlmapClient.queryForList(Stringid,Object map) 基于一个id和一个map参数来执行查询(适合于多参查询的时候使用),返回一个List

5. sqlmapClient.queryForObject(Stringid)基于一个id来执行查询,返回一个Object,此方法也有4种常用方式,用法和queryForList一样,只是返回值只有一个。

6. sqlmapClient.update(Stringid) 基于一个id来执行更新,返回一个Integer值决定执行了多少条记录,此方法也有4种常用方式,和queryForList类似,只是返回值是执行的结果个数

7. sqlmapClient.insert(Stringid)和update类似

8. sqlmapClient.delete(Stringid)和update类似

 

二.事务管理

2. SqlMapClient中的事务:

sqlMapClient.startTransaction();  

开始事务

sqlMapClient.commitTransaction();

    提交事务

sqlMapClient.endTransaction();   

  结束事务,操作失败的时候,整个事务就会在endTransaction时回滚。

新版的ibatis中,不再有rollbackTransaction方法,只能选择endTransaction代替。

如果代码没有显式的调用SqlMapClient.startTransaction()方法,则ibatis会将当前的数据库操作视为自动提交模式(AutoCommit=true),不过,值得注意的是,这里的所谓“自动判定”,实际上ibatis并没有去检查当前是否已经有事务开启。

    实际上,在执行update语句时,sqlMap会检查当前的Session是否已经关联了某个

数据库连接,如果没有,则取一个数据库连接,将其AutoCommit属性设为true,然后

执行update 操作,执行完之后又将这个连接释放。这样,上面两次update 操作实际上

先后获取了两个数据库连接,而不是我们通常所认为的两次update 操作都基于同一个

JDBC Connection。这点在开发时需特别注意。

对于多条SQL 组合而成的一个JDBC 事务操作而言,必须使用startTransaction、commit和endTransaction操作以实现整体事务的原子性。

注意!事务不能嵌套。在调用commit或end方法之前,从同一线程多次调用startTransaction将引起抛出例外。换句话说,对于每个SqlMap实例,每个线程最多只能打开一个事务。

 

 

三.深入SqlMap.xml中的SQL开发

3. 增删改查4种SQL的深入化开发:

 

<select id="selectLike"  parameterClass="java.lang.String"resultClass="bumen">

    select * from BuMenwhere bumencode like '%$bumencode$%'

</select>

当我们需要使用模糊查询的时候,通配符需要特殊处理,否则无法查询到想要的数据

 

 

<select id="selectUser"  parameterClass="bumen" resultClass="int">

    select count(*) fromBuMen where bid=#bid# and bumenname=#bumenname#

</select>

我们可以使用聚集函数来查询,返回类型定义为int类型,也就是java.lang.Integer类型,这里我们传入的参数是一个POJO类型,ibatis会自动get需要的属性值,不用的属性值不会get出来,这样做虽然可以实现查询,但是看来有点浪费资源。

 

 

<resultMap id="BuMenResult"class="BuMen">

    <result property="bid" javaType="java.lang.String" column="bid" jdbcType="varchar2" nullValue="null"/>

    <result property="bumenname" column="bumenname"/>

    <result property="bumencode" column="bumencode"/>

</resultMap>

<select id="selectUser"  parameterClass="bumen" resultMap="BuMenResult">

    select count(*) fromBuMen where bid=#bid# and bumenname=#bumenname#

</select>

和上面的查询是一样的效果,只是返回的方式有所改变,我们这次选用了resultMap来返回,这样做的好处是可以让其他开发人员来看懂POJO和数据库中表的对应关系。

 

 

<select id="selectAll2" parameterClass="int" resultClass="bumen">

      <![CDATA[select bid asid,bumenname as name,bumencode as code from BuMen where bid<#bid#]]>

  </select>

数据库表中的字段名和POJO中的属性名不相同的时候,我们希望字段映射到POJO时,我们可以通过Select的as字句对字段名进行转义,这样就会调用POJO的setId,setName,SetCode方法装载数据。并且小于符号是xml中的关键字,使用会报错,所以,我们还需要<![CDATA[……]]>的方式来编写SQL语句。

 

 

<update id="updateUser" parameterClass="java.util.Map">

    update bumen

    set

    bumenname=#bumenname#,

    bumencode=#bumencode#

    where bid = #bid#

  </update>

  这里传入的参数就是一个Map对象,ibatis将以key "bid"、"bumenname"、"bumencode"从中提取对应的参数值,

  此方式大部分时候用于嵌套查询,或者多表查询,把要查询的条件以Map拼接。

  此方式还可以用于任意的增删改查SQL中,例如,我们要查询一个用户的名字和密码是否存在的时候。

 

 

<select id="getUsers" parameterClass="bumen" resultClass="bumen">

      select bid,bumenname,bumencode from bumen

      <dynamic prepend="where">

         <isNotEmpty prepend="and" property="bumenname">

           (bumenname=#bumenname#)

          </isNotEmpty>

         <isNotEmpty prepend="and" property="bumencode">

           (bumencode=#bumencode#)

         </isNotEmpty>

      </dynamic>

   </select>

在很多时候,可能我们需要一些变化的sql语句,比如说,当用户输入几个关键字查询的时候,我们需要判断用户到底输入了几个关键字,然后通过if-else的方式,组建不同的SQL语句来操作数据库,但是这样做的话,会产生大量的代码或者配置文件内容,但是我们在使用ibatis的时候,可以避免这个问题,我们通过dynamic节点,定义了一个动态的where子句。此where子句中将可能包含两个针对bumenname和bumencode 字段的判断条件。而这两个字段是否加入查询取决于用户所提供的查询条件(字段是否为空[isNotEmpty])。

由于ibatis会自动判定是否需要追加prepend前缀,这里(bumenname=#bumenname#)是where 子句中的第一个条件子句,无需and前缀,所以自动省略。

当用户没有传入参数的时候,我们可以让ibatis使用全表查询,也就是上面配置中的select bid,bumenname,bumencode from bumen语句,如果用户传入了一个参数查询的时候,我们可以让ibatis基于一个条件查询,也就是上面配置中的

select bid,bumenname,bumencode from bumen where bumenname=#username#语句,如果用户传入了两个参数查询的时候,我们可以让ibatis基于两个条件查询,也就是上面配置中的

select bid,bumenname,bumencode from bumen where bumenname=#username#and bumencode=#bumencode#语句,通过这样的方式,我们就可以灵活的操作用户的查询规则,而不必要去增加太多的代码和配置内容,下面还有几种判定标签可以使用。

<isPropertyAvailable>参数类中是否提供了此属性

<isNotPropertyAvailable>与<isPropertyAvailable>相反

<isNull>属性值是否为NULL

<isNotNull> 与<isNull>相反

<isNotEmpty> 属性值是否为空。

<isEmpty>与<isNotEmpty>相反

 

 

二元判断(使用方式和dynamic节点一样,只是加入了一个属性compareValue,它可以指定一个比较值):

例如:

<isEqual prepend="AND" property="bid" compareValue="18">

            (bid=#bid#)

</isEqual>

上面的作用是如果bid属性等于18(compareValue),则在SQL中加入(bid=#bid#)条件。

同样,二元判断也有及各种判断标签供我们选择。

<isEqual>相等。

<isNotEqual>不等。

<isGreaterThan>大于

<isGreaterEqual>大于等于

<isLessThan>小于

<isLessEqual>小于等于

 

你可能感兴趣的文章
Go开发之路(目录)
查看>>
RHEL6.5安装成功ORACLE11GR2之后,编写PROC程序出错解决方法
查看>>
(50)与magento集成
查看>>
Ubuntu设置python3为默认版本
查看>>
日期Calendar/Date的用法
查看>>
现实世界的Windows Azure:采访Soluto的创始人Tomer Dvir
查看>>
JsonCpp 的使用
查看>>
问题账户需求分析
查看>>
JavaSE-代码块
查看>>
爬取所有校园新闻
查看>>
32、SpringBoot-整合Dubbo
查看>>
python面向对象基础
查看>>
组装服务器注意事项
查看>>
HDU 2044 一只小蜜蜂(递归)
查看>>
docker 下 安装rancher 笔记
查看>>
spring两大核心对象IOC和AOP(新手理解)
查看>>
数据分析相关
查看>>
mysql乱码处理一则
查看>>
cf #345 div2 C(Vasya and String。双端队列)
查看>>
Python LDAP中的时间戳转换为Linux下时间
查看>>