Ibatis

  数据访问层框架,ORM,Object Relation Mapping,将对象映射到关系,通过操作对象来达到操作关系的目的。
  通过hibernate访问数据层不需要自己编写sql,简单智能,调用方法就可完成。ibatis需要自己编写sql语句,更加灵活,可对sql进行优化。ibatis的最后版本为2.3.4,从3.x开始,转投到Google Code门下,并改名为MyBatis。

===========================================

  ibatis的核心类是SqlMapClient,通过其可完成对数据库的访问操作。
  spring提供的SqlMapClientFactoryBean对SqlMapClient进行了封装,类内提供对SqlMapClient实例进行初始化的方法,并提供返回SqlMapClient实例的方法getObject。SqlMapClientFactoryBean实现FactoryBean接口,spring规定实现该接口的Bean,由框架实例化时,返回的是getObject返回的实例,这也体现了SqlMapClientFactoryBean是SqlMapClient的实例工厂的意义——配置SqlMapClientFactoryBean,要注入configLocation属性,对应ibatis的配置文件;datasource属性,对应数据源bean。
  spring提供的SqlMapClientTemplate对SqlMapClient进行了封装,类内实际是对SqlMapClient的增删改查方法做了一个外包层,类内SqlMapClient实例的初始化需要外部的注入,本身不提供初始化方法。SqlMapClientTemplate继承JdbcAccessor,JdbcAccessor内部封装了DataSource数据源Bean——配置SqlMapClientTemplate,要注入sqlMapClient属性,对应注入SqlMapClientFactoryBean的实例,因为其返回的就是SqlMapClient的实例;datasource属性,对应数据源bean。
  spring提供的SqlMapClientDaoSupport对SqlMapClientTemplate进行了封装,是一个抽象类,必须继承才能使用,类内以new的方式生成一个SqlMapClientTemplate的实例。
  
  DataSource可在SqlMapClientFactoryBean内注入,也可在SqlMapClientTemplate内注入,放在SqlMapClientTemplate内更合适。
  实际项目中肯能会有多个数据源,如mysql、sqlserver、oracle等。
  SqlMapClientFactoryBean旨在生成SqlMapClient的实例,与属性configLocation有关,需要指明映射关系,而SqlMapClient实例的生成与属性datasource无关,仅在连接数据库时会用到。
  SqlMapClientTemplate内部使用SqlMapClient的实例进行数据库操作,需要连接数据库,必须注入属性datasource。
  针对不同的数据源,需要对每个数据源配置一个SqlMapClientFactoryBean用于注入对应数据源的映射文件,需要对每个数据源配置一个SqlMapClientTemplate用于注入数据源bean来连接不同的数据库。

  dao的三种实现方式,根据设计模式能用对象组合不用继承的原则,不建议使用后两种方式。
  对象组合方式,dao内部定义SqlMapClientTemplate的实例,SqlMapClientTemplate的实例由spring注册并注入,SqlMapClientTemplate要注入SqlMapClientFactoryBean与DataSource。
  继承方式,dao继承SqlMapClientTemplate,dao的配置也就包括了SqlMapClientTemplate的配置,dao内部可以直接使用继承的方法操作数据库,dao配置要注入SqlMapClientFactoryBean与DataSource——类内属性不加注解,配置文件内也不给类注入,配置文件头部<beans default-autowire="byName"> 给出default-autowire,spring也能完成注入。
  继承方式,dao继承SqlMapClientDaoSupport,同样dao的配置也包括了SqlMapClientTemplate的配置,dao内部可以直接使用继承的SqlMapClientTemplate实例操作数据库,dao配置要注入SqlMapClientFactoryBean与DataSource——类内只给出set方法,不给出属性定义,spring也能完成注入。

===========================================

  ibatis中一个pojo对应一个dao,一个dao对应一个映射文件,由此项目中通常会有多个映射文件。由于ibatis最终会将所有的映射文件合并到一起,为防止id冲突,需要命名空间namespace来唯一标识该映射文件。
  以下两个配置文件在dao层,属于ibatis的内容。

// Computer.xml
// namespace,通常用pojo名
<sqlMap namespace="Computer">
    // alias,类型别名,通常为首字母小写的pojo名
    <typeAlias alias="computer" type="xx.Computer" />

    // 对应一类查询结果集
    // class,指明查询结果要映射的pojo类
    <resultMap id="all" class="computer">
        // 指明pojo类的属性与关系表中字段的对应关系
        // jdbcType与javaType的对应关系用时去网上查一下,不要背
        <result property="id" column="id" jdbcType="INT" javaType="java.lang.Integer" />
        <result property="name" column="name" jdbcType="VARCHAR" javaType="java.lang.String" />
        <result property="price" column="price" jdbcType="VARCHAR" javaType="java.lang.String"/>
    </resultMap>

    <resultMap id="part" class="computer">
        <result property="name" column="name" jdbcType="VARCHAR" javaType="java.lang.String" />
        <result property="price" column="price" jdbcType="VARCHAR" javaType="java.lang.String"/>
    </resultMap>

    // id,指出该sql语句的名字,代码中会用到,用时必须加命名空间
    // parameterClass,指出参数类型
    <insert id="insert" parameterClass="computer">
        // CDATA中的内容被定义为纯文本,以防与xml标签混淆
        // 在#之间的为变量
        <![CDATA[
            insert into computer(name, price) values(#name#, #price#)
        ]]>
        // selectKey,用于在插入时自动生成主键
        // keyProperty,定义主键名字
        // resultClass,定义返回类型
        <selectKey resultClass="java.lang.Long" keyProperty="id">
            // 返回上次插入自动生成的id
            select @@IDENTITY as id
        </selectKey>
    </insert>

    // 项目中不要用基本类型,要用类包装
    // 也有将删除操作放在update标签内的,没多大区别
    <delete id="delete" parameterClass="java.lang.Long">
        delete from computer where id = #id#
    </delete>

    <update id="update" parameterClass="computer">
        update computer set name = #name#, price = #price# where id = #id#

        // 或
        // dynamic的prepend值会覆盖条件标签中第一个条件为真的prepend的值
        // 前提是条件标签prepend的值被设置且长度 > 0
        update computer
        <dynamic prepend="set">
            <isNotEmpty property="name" prepend=','>
                name = #name#
            </isNotEmpty>
            <isNotEmpty property="price" prepend=','>
                price  = #price #
            </isNotEmpty>
        </dynamic>
        where id = #id#
    </update>

    // select查询出的字段必须和resultMap配置的字段对应,多了、少了或不对应都会抛出异常
    // ibatis内部会将查询结果依次赋值到resultMap配置的pojo实例内对应的属性上
    // resultMap,为前面定义的resultMap的id
    <select id="list" resultMap="all">
        select id, name, price from computer
    </select>

    // 或
    // resultMap是显示映射,pojo属性与关系字段映射明确,性能更好,推荐使用
    // resultClass,指出查询结果要映射的类,为隐式映射,若pojo的属性名与关系的字段名不同,查询结果就不会映射到类
    <select id="list" resultClass="computer">
        select id, name, price from computer
    </select>

    // 查询结果仅一个字段
    <select id="getName" parameterClass="java.lang.Long" resultClass="java.lang.String">
        select name from computer where id = #id#
    </select>

    // sql标签用来定义sql语句片段
    // id,为sql片段标识,后面可根据此id拼接sql语句
    <sql id="list_where">
        // isNotNull,指当property设置的变量name不为空时,执行标签里内容
        // prepend,表示将其内容and追加在isNotNull标签的内容之前
        <isNotNull property="name" prepend="and">
            name = #name#
        </isNotNull>
        <isNotNull property="price" prepend="and">
            price = #price#
        </isNotNull>

        // 上述打印内容为 and name = xx and price = xx
        // 通过设置dynamic标签的prepend来覆盖第一个条件为真的and
        // 打印内容为where name = xx and price = xx
        <dynamic prepend="where">
            <isNotNull property="name" prepend="and">
                name = #name#
            </isNotNull>
            <isNotNull property="price" prepend="and">
                price = #price#
            </isNotNull>
        </dynamic>
    </sql>

    // parameterClass,参数为map类型
    <select id="list_2" parameterClass="map" resultMap="part">
        // where 1 = 1,用于巧妙的连接name之前的and,若用dynamic可以不用此
        // include,用于包含sql片段
        // start,属性值来自map类型的参数
        // limit start, rows 返回查询结果的第start行,偏移从0开始,共返回rows行
        // limit start, -1 返回查询结果的第start,及其之后的所有行
        // limit end 等价于 limit 0, end 返回查询结果第end行,及其之前的所有行
        // #与$的区别,#之间放变量,$用于字符串之间的拼接,$间不要放字符或字符串变量,否则出错
        select name, price from computer
        where 1 = 1
        <include refid="list_where" />
        order by id asc
        <isNotNull property="start" prepend=" ">
            limit $start$, $rows$
        </isNotNull>
    </select>
</sqlMap>

// sqlmap-config-mysql.xml
// 用于配置数据源信息,以及整合全部的映射文件
// 若有其它异构数据库,应单独建立另一个文件,如sqlmap-config-sqlserver.xml
<sqlMapConfig>
    // useStatementNamespaces,设为true表示开启映射文件的命名空间
    <settings useStatementNamespaces="true"/>

    // 配置数据源,与spring整合后,该部分移植到spring配置文件
    ....

    // 以当前目录为相对路径,加载映射文件
    <sqlMap resource="xx/mysql/xx.xml" />
</sqlMapConfig>

===========================================

  以下配置文件在web层,属于spring与ibatis的整合内容。

// spring-config-datasource-dbcp.xml
// 所有的数据源在此配置
<beans>
    // 将数据源注册为bean
    <bean id="mysqlDataSource" class="..BasicDataSource">
        // 属性的名字都是在BasicDataSource里定义好的,不要自定义
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/xxdb" />
        <property name="username" value="root" />
        <property name="password" value="123" />
    </bean>

    // 其它的数据源,如sqlserver、oracle、分库的
</beans>

// spring-dao.xml
// 注册项目所有的dao
<beans>
    // 注册SqlMapClientFactoryBean
    <bean id="sqlMapClient" class="..SqlMapClientFactoryBean">
        // SqlMapClientFactoryBean源码内定义了属性dataSource和configLocation
        // dataSource放在SqlMapClientTemplate内注入
        // configLocation在此注入,看为与ibatis整合的入口
        <property name="configLocation" value="classpath:sqlmap-config-mysql.xml" />
    </bean>

    // 针对不同的数据源,要再次配置新的SqlMapClientFactoryBean
    ....

    // 配置SqlMapClientTemplate
    <bean id="mysqlSqlMapClientTemplate" class="..SqlMapClientTemplate">
        <property name="dataSource" ref="mysqlDataSource">
        // SqlMapClientTemplate源码内定义了ibatis的SqlMapClient类型的属性sqlMapClient
        <property name="sqlMapClient" ref="sqlMapClient">
    </property>

    // 针对不同的数据源,要再次配置新的SqlMapClientTemplate
    ....

    // 放到项目用注解完成
    <bean id="xxDaoImpl" class="xx.xxDaoImpl">  
        <property name="myClientTemplate" ref="mysqlSqlMapClientTemplate" />
    </bean>
</beans>

// spring-config.xml
// 将上述xml文件整合到一起

@Repository("computerDao ")
public class ComputerDaoImpl implements ComputerDao {
    @Resource(name = "mysqlSqlMapClientTemplate")
    private SqlMapClientTemplate mysqlTool;
    ..

    public Integer insertComputer(Computer computer) {
        // 加命名空间
        return (Integer)mysqlTool.insert("Computer.insert", computer);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值