Mybatis 那些 Xml 模板标签
SQL 标签
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。
这里很明显就能看出来 SQL 标签一般是用于复用一组确定的列名 or
<sql id="userColumns">${tablename}.id,${tablename}.username,${tablename}.password</sql>
<select id="getUser" resultType="com.example.springmvclearn.entity.User">
select
<include refid="userColumns"><property name="tablename" value="user"/></include>
from user where id=1;
</select>
<!-- 这里等效于
select user.id,user.username,user.password from user where id=1;
-->
tablename 对应下面 include 的 name 属性,用于确定要替换的位置
include 中的 value 用于确定 tablename 要替换成啥,这里就是替换成 user
#{} 和 ${}
#{}: 占位符,传入的内容会作为字符串 加上引号 ,以 预编译 的方式传入,将 sql 中的 #{} 替换为 ? 号,调用 PreparedStatement 的 set 方法来赋值,有效的防止 SQL 注入,提高系统安全性
${}: 拼接符,传入的内容会 直接替换 拼接,不会加上引号,可能存在 sql 注入的安全隐患
- 能用 #{} 的地方就用 #{},不用或少用 ${}
- 必须使用 ${} 的情况:
- 表名作参数时,如:
SELECT * FROM ${tableName}
- order by 时,如:
SELECT * FROM t_user ORDER BY ${columnName}
- 表名作参数时,如:
- sql 语句使用 #{},properties 文件内容获取使用 ${}
动态 sql
动态 SQL 是 MyBatis 强大特性之一,逻辑复杂时,MyBatis 映射配置文件中,SQL 是动态变化的,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
动态 SQL 包含的标签:
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
if
if 标签使用是最常见的,和我们正常 java 语法的 if 差不多,看个例子就知道了
<select id="getUser" resultType="User">
select * from user where 1=1
<if test="id!=null">
and id=#{id}
</if>
</select>
<!--这里其实就是拼 sql,必须要有个 1=1 来让 id!=null 也能成功
id==null 时:select * from user where 1=1
id!=null 时:select * from user where 1=1 and id=#{id}
-->
choose、when、otherwise
这个类似与 java 语法中的 switch 与 case 和 default,
- choose -> switch
- when -> case
- otherwise -> default
但是这里相比于 switch,他里面的 when 和 otherwize 只会触发一次,类似于 if
else if
else
,即代码块只会拼凑一个
接着看个栗子吧
<select id="getUser" resultType="User">
select * from user where 1=1
<choose>
<when test="id!=null">
and id=#{id}
</when>
<when test="username!=null and username!=''">
and username=#{username}
</when>
<when test="password!=null and password!=''">
and password=#{password}
</when>
<otherwise>
and ~~~~自己定义吧
</otherwise>
</choose>
</select>
trim、where、set
where
先来看 where 吧,还记得上面我们写的 where 1=1
以及if 标签里面的 and 吗?,再来回顾一下上面可能出现的问题
-- 如果没有 1=1 的话且 if 标签判断的是 false
select * from user where --戛然而止了
-- 如果没有 1=1 的话且 if 标签里面判断成功,但是没有 and
select * from user where 1=1 ??? id=#{id} --缺少 and
为了是不是觉得为了解决 sql 拼凑的错误,要写这个 1=1 或者 and 很丑陋,在这里where 标签就解决了这个问题,以上面的 if 的例子来说明吧
<select id="getUser" resultType="User">
select * from user
<where>
<if test="id!=null">
and id=#{id}
</if>
</where>
</select>
是不是看着舒服多了。看看 where 标签做了啥呢?
where 标签只会在子元素返回任何内容的情况下才插入 WHERE 子句。而且,若子句的开头为 AND
或 OR
,where 元素也会将它们去除。
trim
如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 标签。
trim 有如下参数可以选择
- prefix:给拼串后的整个字符串加一个前缀,trim 标签体中是整个字符串拼串后的结果
- prefixOverrides:去掉整个字符串前面多余的字符
- suffix:给拼串后的整个字符串加一个后缀
- suffixOverrides:去掉整个字符串后面多余的字符
我们类似可以这样实现where 标签类似的功能
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
来看个具体点的栗子
<select id="selectUserByUsernameAndPassword" resultType="User">
SELECT * FROM user
<trim prefix="where" prefixOverrides="and | or">
<if test="username != null">
AND username=#{username}
</if>
<if test="password != null">
AND password=#{password}
</if>
</trim>
</select>
set
set :进行更新操作的时候,含有 set 关键词,使用该标签
<!-- 根据 id 更新 user 表的数据 -->
<update id="updateUserById">
UPDATE user
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="password != null and password != ''">
password = #{password}
</if>
</set>
WHERE id=#{id}
</update>
- 如果第一个条件 username 为空,那么 sql 语句为:update user u set password=? where id=?
- 如果第一个条件不为空,那么 sql 语句为:update user u set u.username = ? ,u.password = ? where id=?
同时set 其实也能用trim 实现,这里其实主要就是删除掉最后的逗号
<trim prefix="SET" suffixOverrides=",">
...
</trim>
foreach
这个其实也与 java 语法中的 for 循环差不多
foreach 提供了如下参数选择:
- collection 集合参数的名称,看个方法签名,
List<User> selectByIds(@Param("ids") List<Integer> ids);
这里只要填 ids 即可 - close 结束的 SQL 语句
- index 此时遍历到参数的下标(从 0 开始)
- item 参数变量名
- open 开始的 SQL 语句
- separator 分隔符
定义那么多,看个栗子吧
<select id="selectByIds" resultType="user" >
SELECT * FROM user where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
<!--这里 foreach 生成的就是(id1,id2,id3,~~~) 这种啦-->
<!--注意 collection="list" 这里意味着 mapper 的中接口的方法签名得是这样的 List<User> selectByIds(List<Integer> ids)
也就是说容器类型得是 list
-->
</select>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Mybatis select 查询
下一篇: 什么是进程?
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论