[关闭]
@MrXiao 2018-03-01T16:33:26.000000Z 字数 4412 阅读 939

Mybatis(4)——Mapper.xml映射文件

Mybatis


Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。
SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):

cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
parameterMap – 已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
下一部分将从语句本身开始来描述每个元素的细节。

1、parameterType(输入类型)

1.1 传递简单类型

  1. <!-- 根据名称模糊查询用户信息 -->
  2. <select id="selectUserByName" parameterType="string" resultType="user">
  3. select * from user where username like '%${value}%'
  4. </select>
  5. <!-- 根据id查询用户信息 -->
  6. <select id="selectUserById" parameterType="int" resultType="user">
  7. select * from user where userId = #{id}
  8. </select>

1.2 传递pojo

Mybatis使用ognl表达式解析对象字段的值,如下例子:

  1. <!-- 传递pojo对象综合查询用户信息 -->
  2. <select id="findUserByUser" parameterType="user" resultType="user">
  3. select * from user where id=#{id} and username like '%${username}%'
  4. </select>

id 和 username 都是 User对象里面的属性字段。

1.3 传递pojo包装对象

  1. public class QueryVo {
  2. private User user;
  3. //自定义用户扩展类
  4. private UserCustom userCustom;
  1. <!-- 传递pojo包装对象综合查询用户信息 -->
  2. <select id="findUserList" parameterType="queryVo" resultType="user">
  3. select * from user where id=#{user.id} and username like '%${user.username}%'
  4. </select>

1.4 传递hashmap

  1. <!-- 传递hashmap综合查询用户信息 -->
  2. <select id="findUserByHashmap" parameterType="hashmap" resultType="user">
  3. select * from user where id=#{id} and username like '%${username}%'
  4. </select>

id和username是map的key

2、resultType(输出类型)

输出简单类型,输出pojo,输出pojo列表(list),输出hashmap

输出pojo对象和输出pojo列表在sql中定义的resultType是一样的。
返回单个pojo对象要保证sql查询出来的结果集为单条,内部使用session.selectOne方法调用,mapper接口使用pojo对象作为方法返回值。

返回pojo列表表示查询出来的结果集可能为多条,内部使用session.selectList方法,mapper接口使用List对象作为方法返回值。

输出pojo对象可以改用hashmap输出类型,将输出的字段名称作为map的key,value为字段值。

3、resultMap

resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

4、动态sql

通过mybatis提供的各种标签方法实现动态拼接sql。

4.1 if

  1. <!-- 传递pojo综合查询用户信息 -->
  2. <select id="findUserList" parameterType="user" resultType="user">
  3. select * from user
  4. where 1=1
  5. <if test="id!=null and id!=''">
  6. and id=#{id}
  7. </if>
  8. <if test="username!=null and username!=''">
  9. and username like '%${username}%'
  10. </if>
  11. </select>

4.2 where

  1. <select id="findUserList" parameterType="user" resultType="user">
  2. select * from user
  3. <where>
  4. <if test="id!=null and id!=''">
  5. and id=#{id}
  6. </if>
  7. <if test="username!=null and username!=''">
  8. and username like '%${username}%'
  9. </if>
  10. </where>
  11. </select>

where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。

4.3 choose, when, otherwise

有些时候,我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

  1. <select id="findActiveBlogLike"
  2. resultType="Blog">
  3. SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  4. <choose>
  5. <when test="title != null">
  6. AND title like #{title}
  7. </when>
  8. <when test="author != null and author.name != null">
  9. AND author_name like #{author.name}
  10. </when>
  11. <otherwise>
  12. AND featured = 1
  13. </otherwise>
  14. </choose>
  15. </select>

4.4 foreach

向sql传递数组或List,mybatis使用foreach解析,如下:

  1. 通过pojo传递list

    1. <if test="ids!=null and ids.size>0">
    2. <foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
    3. #{id}
    4. </foreach>
    5. </if>
  2. 传递单个List

    1. <select id="selectUserByList" parameterType="java.util.List" resultType="user">
    2. select * from user
    3. <where>
    4. <!-- 传递List,List中是pojo -->
    5. <if test="list!=null">
    6. <foreach collection="list" item="item" open="and id in("
    7. separator="," close=")">
    8. #{item.id}
    9. </foreach>
    10. </if>
    11. </where>
    12. </select>
  3. 传递单个数组(数组中是pojo)

    1. <!-- 传递数组综合查询用户信息 -->
    2. <select id="selectUserByArray" parameterType="Object[]" resultType="user">
    3. select * from user
    4. <where>
    5. <!-- 传递数组 -->
    6. <if test="array!=null">
    7. <foreach collection="array" index="index" item="item" open="and id in("
    8. separator="," close=")">
    9. #{item.id}
    10. </foreach>
    11. </if>
    12. </where>
    13. </select>
  4. 传递单个数组(数组中是字符串类型)

    1. <!-- 传递数组综合查询用户信息 -->
    2. <select id="selectUserByArray" parameterType="Object[]" resultType="user">
    3. select * from user
    4. <where>
    5. <!-- 传递数组 -->
    6. <if test="array!=null">
    7. <foreach collection="array" index="index" item="item" open="and id in("
    8. separator="," close=")">
    9. #{item}
    10. </foreach>
    11. </if>
    12. </where>
    13. </select>
  5. SQL片段

    感觉实际开发中不怎么使用,不利于维护。

5、#{}与${}

  1. #{}实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符即?。使用占位符#{}可以有效防止sql注入,在使用时不需要关心参数值的类型,mybatis会自动进行java类型和jdbc类型的转换。#{}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称
  2. ${}和#{}不同,通过${}可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value,使用${}不能防止sql注入。
  3. 模糊查询时,推荐使用${}

    1. <!-- 根据名称模糊查询用户信息 -->
    2. <select id="selectUserByName" parameterType="string" resultType="user">
    3. select * from user where username like '%${value}%'
    4. </select>
  4. order by排序,如果将列名通过参数传入sql,根据传的列名进行排序,应该写为:
    ORDER BY ${columnName}
    如果使用#{}将无法实现此功能。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注