2.1 mybatis配置篇-mapper.xml

1 mybatis的mapper实用详解

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。动态sql和映射
顶级元素mapper有一个参数值namespace表示该映射配置文件的对应的接口位置

    <mapper namespace="com.tadpole.itemorder.ItemOrderMapper">
    </mapper>

顶级元素mapper下的子元素

  1. insert – 映射插入语句。
  2. update – 映射更新语句。
  3. delete – 映射删除语句。
  4. select – 映射查询语句。
  5. cache – 该命名空间的缓存配置。
  6. cache-ref – 引用其它命名空间的缓存配置。
  7. resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
  8. sql – 可被其它语句引用的可重用语句块。

1.1 insert, update 和 delete 修改语句

属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句,所以mapper接口的方法是不能重载的。
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
statementType可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys(仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键,默认值:false。
keyProperty(仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。
keyColumn(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
<insert
  id="insertAuthor"
  parameterType="com.tadpole.itemorder.ItemOrder"
  flushCache="true"
  statementType="PREPARED"
  keyProperty=""
  keyColumn=""
  useGeneratedKeys=""
  timeout="20"></insert>
<update
  id="updateAuthor"
  parameterType="com.tadpole.itemorder.ItemOrder"
  flushCache="true"
  statementType="PREPARED"
  timeout="20"></update>

<delete
  id="deleteAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20"></delete>

1.2 select查询语句

属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句,所以mapper接口的方法是不能重载的。
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
resultType期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
resultMap对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
useCache将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
fetchSize这是一个给驱动的建议值,尝试让驱动程序每次批量返回的结果行数等于这个设置值。 默认值为未设置(unset)(依赖驱动)。
statementType可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
resultOrdered这个设置仅针对嵌套结果 select 语句:如果为 true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。 这就使得在获取嵌套结果集的时候不至于内存不够用。默认值:false。
resultSets这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。

select的子元素中有selectKey ,不建议使用selectKey
支持动态sql,的循环语句foreach

  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password})
  </foreach>

1.3 sql

该元素可以用来定义重用的sql片段,使用include引入到对应的语句中

    <sql id="orderPayColumns">order_id orderId, orderName,price,${}</sql>
     <select id="selectById" resultMap="itemOrder">
         select  <include refid="orderPayColumns"></include> from  item_order where id = #{id}
     </select>

1.4 resultMap 映射集合

  • constructor - 用于在实例化类时,注入结果到构造方法中
    • idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
    • arg - 将被注入到构造方法的一个普通结果
  • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
    • result – 注入到字段或 JavaBean 属性的普通结果
  • association – 一个复杂类型的关联;许多结果将包装成这种类型
    • 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
  • collection – 一个复杂类型的集合
    • 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
  • discriminator – 使用结果值来决定使用哪个 resultMap
    • case – 基于某些值的结果映射
      • 嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射

下面是 id 和 result 元素的属性。

属性描述
column数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。
javaType一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之前的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能存在空值的列指定这个类型。
typeHandler我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。 这个属性值是一个类型处理器实现类的完全限定名,或者是类型别名。
select用于加载复杂类型属性的映射语句的 ID,它会从 column 属性中指定的列检索数据,作为参数传递给此 select 语句。具体请参考关联元素。
resultMap结果映射的 ID,可以将嵌套的结果集映射到一个合适的对象树中。 它可以作为使用额外 select 语句的替代方案。它可以将多表连接操作的结果映射成一个单一的 ResultSet。这样的 ResultSet 将会将包含重复或部分数据重复的结果集。为了将结果集正确地映射到嵌套的对象树中,MyBatis 允许你 “串联”结果映射,以便解决嵌套结果集的问题。想了解更多内容,请参考下面的关联元素。
name构造方法形参的名字

1.5 cache 缓存

    <cache/>

缓存只作用于 cache 标签所在的映射文件中的语句,基本上就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

可用的清除策略有:

  • LRU – 最近最少使用:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
  • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
参数名说明
type指定缓存(cache)接口的实现类型,当需要和ehcache整合时更改该参数值即可。
flushInterval刷新间隔。可被设置为任意的正整数,单位毫秒。默认不设置。
size引用数目。可被设置为任意正整数,缓存的对象数目等于运行环境的可用内存资源数目。默认是1024。
readOnly只读,true或false。只读的缓存会给所有的调用者返回缓存对象的相同实例。默认是false。
eviction缓存收回策略。LRU(最近最少使用的),FIFO(先进先出),SOFT( 软引用),WEAK( 弱引用)。默认是 LRU。

cache的属性有type

  • 如果要实现自定义缓存的话,就实现type 属性指定的类必须实现 org.apache.ibatis.cache.Cache 接口

1.6 cache-ref

对某一命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。 但你可能会想要在多个命名空间中共享相同的缓存配置和实例。要实现这种需求,你可以使用 cache-ref 元素来引用另一个缓存

1.7 动态sql

借助功能强大的基于 OGNL 的表达式

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

1.7.1 if

<select id="selectCountAll"
     resultType="int">
  SELECT count(*) FROM item_order
  WHERE id > 0 
  <if test="index != null">
    AND index > #{index}
  </if>
</select>

1.7.2 choose、when、otherwise

<select id="selectCountAll"
     resultType="int">
  SELECT count(*) FROM item_order
  WHERE id > 0 
    <choose>
        <when test="name != null">
          AND name like #{name}
        </when>
        <when test=" price != null">
          AND price = #{price}
        </when>
        <otherwise>
          AND price = 20
        </otherwise>
      </choose>
</select>

1.7.3 trim、where、set

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT count(*) FROM item_order
  <where>
    <if test="name != null">
         name = #{name}
    </if>
    <if test="price != null">
        AND price = #{price}
    </if>
  </where>
</select>

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号

<update id="updateAuthorIfNecessary">
  update item_order
    <set>
      <if test="name != null">name=#{username},</if>
      <if test="price != null">price=#{password}</if>
    </set>
  where id=#{id}
</update> 

trim 可以实现和set一样的功能,prefix开头的指定内容,suffixOverrides多余的额外内容

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

1.7.4 foreach

<select id="selectByIds" resultType="com.tadpole.itemOrder.ItemOrder">
  SELECT *
  FROM item_order
  WHERE id in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

1.7.5 script

要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。比如

    @Update({"<script>",
      "update item_order",
      "  <set>",
      "    <if test='name != null'>name=#{name},</if>",
      "    <if test='price != null'>price=#{price}</if>",
      "  </set>",
      "where id=#{id}",
      "</script>"})
    void selectByName(ItemOrder itemOrder);

1.7.6 bind

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文

<select id="selectBlogsLike" resultType="com.tadpole.itemOrder.ItemOrder">
  <bind name="pattern" value="'%' + itemOrder.getName() + '%'" />
  SELECT * FROM item_order
  WHERE name LIKE #{pattern}
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值