XML映射器


SQL映射文件的几个顶级元素:

  • cache - 该命名空间的缓存配置

  • cache-ref - 引用其他命名空间的缓存配置

  • resultMap - 描述如何从数据库结果集中加载对象

  • sql - 可被其他语句引用的可重用语句块

  • insert - 增

  • update - 改

  • delete - 删

  • select - 查

select属性

属性 描述
id 标识符,与Mapper中对应方法的方法名一致
parameterType 传入这条语句的参数的类全限定名或别名
resultType 返回结果的类全限定名或别名,如果返回的是集合,应设置为集合包含的类型而不是集合本身的类型。resultType和resultMap之间只能使用一个
resultMap 对外部resultMap的命名引用,结果映射是Mybatis的最强大的特性

sql

sql元素可以用来定义可重用的SQL代码片段,以便在其他语句中使用。参数可以静态地(加载的时候)确定下来并且可以在不同的include元素中定义不同的参数值

<sql id="userColumns">
${alias}.id,${alias}.usernname,${alias}.password
</sql>

常用在include元素的refid属性或内部语句中使用属性值

<sql id="sometable">
${preifx}Table
</sql> <sql id="someinclude">
FROM
<include refid="${include_target}"/>
</sql> <select id="select" resultType="Map">
SELECT
field1,field2,field3
<include refid="someinclude">
<property name="prefix" value="Some"/>
<property name="include_target" value="sometable"/>
</include>
</select>

ResultMap

一对一查询:

<!-- 属性名不一致或进行关联查询时,可用resultMap标签
以查询订单为例,从查询订单角度出发为一对一,因为一个订单只会是一个人下的 -->
1)改造实体类:
<!-- 在订单类中添加User属性,即一个引用类型 --> 2)编写resultMap:
<resultMap type="order" id="orderUserResultMap">
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
...
<result property="note" column="note"/>
<association property="user" javaType="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
...
</association>
</resultMap> 3)调用实例:
<!-- 一对一关联,查询订单,订单内部包含用户属性 -->
<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON o.user_id = u.id
</select>

一对多查询:

<!-- 查询所有用户信息及相关订单 -->
<!-- 对于用户而言,一个用户可能对应多个不同的订单,即一对多 -->
1)改造实体类:
添加订单集合属性,如:List< Order > orders 2)编写resultMap:
<resultMap type="user" id="userOrderResultMap">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="sex" column="sex" />
<result property="address" column="address" /> <!-- 配置一对多的关系
property:填写pojo类中List集合类类属性的名称
javaType:填写集合类型的名称
-->
<collection property="orders" javaType="list" ofType="order">
<!-- 配置主键,是关联Order的唯一标识 -->
<id property="id" column="oid" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
</collection>
</resultMap> 3)调用实例:
<!-- 一对多关联,查询订单同时查询该用户下的订单 -->
<select id="queryUserOrder" resultMap="userOrderResultMap">
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.id oid,
o.number,
o.createtime,
o.note
FROM
`user` u
LEFT JOIN `order` o ON u.id = o.user_id
</select>

动态SQL


简介

主要介绍Mybatis提供的几种用于实现动态SQL的标签的基本使用方式:

  • if
  • choose、when、otherwise
  • trim、where、set
  • foreach

if

if 语句提供了可选的查找文本功能

若 if 中条件成立,则执行 if 标签中的语句,拼接至SQL语句中

若 if 中条件不成立,则忽略,举个栗子:

<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>

choose、when、otherwise

Mybatis提供的choose元素,类似Java的switch语句,可从多个条件中选择一个使用

举个栗子:传入了"title"就按"title"查找,传入了"author"就按"author"查找的情形。

若两者都没有传入,就返回标记为featured=1的BLOG(若多个条件满足则遵循就近原则)

<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<choose>
<when test="title !=null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>

trim、where、set

where

如何将上例中的"state='ACTIVE'"条件设置为动态条件,即WHERE标签

<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>

按上面所写,如果没有匹配的条件,SQL会变成:

SELECT * FROM BLOG
WHERE

导致查询失败。如果匹配的只是第二/三个条件,SQL会变成:

SELECT * FROM BLOG
WHERE
AND title like 'title'

从上例可看出 WHERE 语句后的第一个条件想要实现动态SQL不能简单使用条件元素来解决,对此可以使用Mybatis提供的where元素

<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>

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

set

用于动态更新语句的类似解决方案叫set。set元素可以用于动态包含需要更新的列,忽略其他不更新的列,比如:

<update id="updateAuthorIfNecessary">
UPDATE Author
<set>
<if test="username != null">
username=#{username},
</if>
<if test="password != null">
password=#{password},
</if>
<if test="email != null">
email=#{email},
</if>
<if test="bio != null">
bio=#{bio}
</if>
</set>
where id = #{id}
</update>

trim

如果选择的元素与你期望的不大一样,可以通过自定义trim元素来制定元素的功能,比如:

where标签:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>

set标签:

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

prefix:前缀

prefixOverrides:前缀覆盖,忽略通过管道符分隔的文本序列

suffixOverrides:后缀覆盖,覆盖了后缀值的设置

foreach

动态SQL的另一个常见使用场景是对集合进行遍历(尤其是在构建IN条件语句的时候)

<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>

可以将任何可迭代对象(List, Set)、Map或数组对象作为集合参数传递给foreach。当使用可迭代对象或者数组时,index是当前迭代的序号,item的值是本次迭代获取到的元素。使用Map对象时,index是key,item是value

最新文章

  1. 画图解释SQL联合语句
  2. .NET使用Com组件的一点点教训笔记~
  3. 安装.net Framework 3.5 SP1非常慢的解决方案
  4. 第三周总结PSP日志文件
  5. Web Api 在线参考文档
  6. c# 语法5.0 新特性 转自网络
  7. tesseract 字体训练资料篇
  8. bootbox.js [v4.2.0]设置确认框 按钮语言为中文
  9. Sublime Text 3 Build 3047 32bit/64bit 简体中文安装破解版
  10. word2vec 中的数学原理具体解释(三)背景知识
  11. HDU 5045 Contest
  12. 一步一步学Java IO
  13. Python之禅及释义
  14. 移动文件(git mv)
  15. 记录微信小程序报错 Unexpected end of JSON input;at pages/flow/checkout page getOrderData function
  16. Leetcode : eImplement strStr
  17. 【读书笔记】iOS-xib,点击事件的连接(三)
  18. 03_java基础(五)之项目结构搭建
  19. SSM 项目搭建 (IDEA)
  20. logstash收集ngx日志

热门文章

  1. Java进阶 | IO流核心模块与基本原理
  2. linux学习之路第三天
  3. XCTF getit
  4. CTF反序列化逃逸
  5. java基础---类和对象(4)
  6. Docker从容器拷贝文件到宿主机或从宿主机拷贝文件到容器
  7. 高校表白App-团队冲刺第二天
  8. 【系统配置】Ubuntu和Windons系统安装配置深度学习环境
  9. vue(23)Vuex的5个核心概念
  10. PAT甲级:1089 Insert or Merge (25分)