Mybatis SQL映射文件讲解

Mybatis SQL映射文件讲解

SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):

  • cache – 配置给定命名空间的缓存。
  • cache-ref – 从其他命名空间引用缓存配置。
  • resultMap – 最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加 载你的对象。
  • parameterMap – 已经被废弃了!老式风格的参数映射。内联参数是首选,这个元 素可能在将来被移除。
  • sql – 可以重用的 SQL 块,也可以被其他语句引用。
  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句

select

查询语句是使用 MyBatis 时最常用的元素之一,对简单类别的查询元素是非常简单的。比如:

<select id="selectPerson" parameterType="int" resultType="java.lang.Hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>
  • 1
  • 2
  • 3

这个语句被称作 selectPerson, 使用一个 int (或 Integer) 类型的参数, 并返回一个 HashMap 类型的对象,其中的键是列名,值是列对应的值。

这就告诉 MyBatis 创建一个预处理语句参数。 使用 JDBC, 这样的一个参数在 SQL 中会 由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:

// Similar JDBC code, NOT MyBatis…
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
  • 1
  • 2
  • 3
  • 4

默认情况下,使用#{}格式的语法会导致 MyBatis 创建预处理语句属性并以它为背景设 置安全的值(比如?) 。这样做很安全,很迅速也是首选做法,有时你只是想直接在 SQL 语 句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:

ORDER BY ${columnName}
  • 1

这里 MyBatis 不会修改或转义字符串,接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会 导致潜在的 SQL 注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检 查。

select 元素有很多属性允许你配置,来决定每条语句的作用细节。

  1. id 
    在命名空间中唯一的标识符,可以被用来引用这条语句。
  2. parameterType 
    将会传入这条语句的参数类的完全限定名或别名,参数可以是基本数据类型,也可以是一个对象。
  3. parameterMap 
    这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数 映射和 parameterType 属性。

  4. resultType 
    从这条语句中返回的期望类型的类的完全限定名或别名。注意集 合情形,那应该是集合可以包含的类型,而不能是集合本身。使 用 resultType 或 resultMap,但不能同时使用。

  5. resultMap 
    命名引用外部的 resultMap。 返回 map 是 MyBatis 最具力量的特性, 对其有一个很好的理解的话, 许多复杂映射的情形就能被解决了。通俗来讲pojo属性与表中列名不区分大小写情况下相同使用resultType,不同使用resultMap。
  6. flushCache 
    将其设置为 true,不论语句什么时候被调用,都会导致缓存被 清空。默认值:false。
  7. useCache 
    将其设置为 true, 将会导致本条语句的结果被缓存。 默认值: true。
  8. timeout 
    这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的 最大等待值。默认不设置(驱动自行处理)
  9. fetchSize 
    这是暗示驱动程序每次批量返回的结果行数。默认不设置(驱动 自行处理)。
  10. statementType 
    STATEMENT,PREPARED 或 CALLABLE 的一种。 这会让 MyBatis 使用选择使用 Statement,PreparedStatement 或 CallableStatement。 默认值:PREPARED。

insert, update and delete

数据变更语句 insert,update 和 delete 在它们的实现中非常相似:

<insert id="insertAuthor" parameterType="domain.blog.Author">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>

<update id="updateAuthor" parameterType="domain.blog.Author">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>

<delete id="deleteAuthor" parameterType="int">
  delete from Author where id = #{id}
</delete>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

sql

这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。比如:

<sql id="userColumns"> 
  id,username,password
</sql>
  • 1
  • 2
  • 3

这个 SQL 片段可以被包含在其他语句中,例如:

<select id="selectUsers" parameterType="int" resultType="hashmap">
  select <include refid="userColumns"/>
  from some_table
  where id = #{id}
</select>
  • 1
  • 2
  • 3
  • 4
  • 5

ResultMap

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="username"/>
  <result property="password" column="password"/>
</resultMap>
  • 1
  • 2
  • 3
  • 4
  • 5

引用它的语句使用 resultMap 属性就行了(注意我们去掉了 resultType 属性)。比如:

<select id="selectUsers" parameterType="int" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>
  • 1
  • 2
  • 3
  • 4
  • 5

ResultMap功能是非常强大的,里面还涉及到各种嵌套查询,这块会单独讨论。

缓存

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

<cache/>
  • 1

字面上看就是这样。这个简单语句的效果如下:

•映射语句文件中的所有 select 语句将会被缓存。 
•映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。 
•缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。 
•根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。 
•缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。 
•缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

所有的这些属性都可以通过缓存元素的属性来修改。比如:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
  • 1
  • 2
  • 3
  • 4
  • 5

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。

可用的收回策略有:

•LRU – 最近最少使用的:移除最长时间不被使用的对象。 
•FIFO – 先进先出:按对象进入缓存的顺序来移除它们。 
•SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。 
•WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。 
默认的是 LRU。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是 1024。

readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。

参照缓存

这个特殊命名空间的唯一缓存会被使用或者刷新相同命名空间内 的语句。也许将来的某个时候,你会想在命名空间中共享相同的缓存配置和实例。在这样的 情况下你可以使用 cache-ref 元素来引用另外一个缓存。

<cache-ref namespace="com.someone.application.data.SomeMapper"/>

猜你喜欢

转载自blog.csdn.net/Demo__/article/details/79530380
今日推荐