标签作用
- if 条件语句
- foreach 循环语句,可以添加前缀,后缀,分隔符,等
- where 自动将标签内,最前的and,or去除
- set 自动将变迁内最后逗号去除
- sql,include 标签,可以定义基础SQL,在其他标签内引入
- choose、when、otherwise标签,条件语句
- bind标签,声明变量
如何使用
<!--定义基础SQL标签,其他标签内可以 include-->
<sql id="baseSql">
select * from user
</sql>
<select id="findAll" resultType="user">
<!--引入基础定义标签-->
<include refid="baseSql"/>;
</select>
<!--
输出SQL:select * from user;
-->
<select id="listByCondition" resultType="user">
<!--引入基础定义标签-->
<include refid="baseSql"/>
<!--where 标签,可以自动删除 以 and | or 开头的 and|or-->
<where>
<!--if 标签,如果test表达式是true则拼接内容SQL,否则不拼接-->
<if test="id != null">AND id = #{id}</if>
<if test="username != null">AND username = #{username}</if>
<if test="password != null">AND password = #{password}</if>
</where>;
</select>
<!--
输出SQL:select * from user where id=? and username=?;
-->
<select id="listByIds" resultType="user">
<include refid="baseSql"/>
where id in
<!--foreach 标签 可以循环遍历数组,指定开始,结束符,分隔符
collection 这里填写集合参数
open 拼接到语句开始部分
close 拼接到语句结束部分
item 集合遍历元素变量名,写在#{}内
sperator 元素遍历,分隔符
-->
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>;
</select>
<!--
输出SQL:select * from user where id in (?,?);
-->
<update id="update" parameterType="user">
update user
<!--set标签,可以将输出文本末尾的逗号去除-->
<set>
<if test="id !=null">id = #{id},</if>
<if test="username !=username">username = #{username},</if>
<if test="password !=null">password = #{password},</if>
<if test="birthday !=null">birthday = #{birthday},</if>
</set>
where id =#{id};
</update>
<!--
输出SQL:update user set
username=?,
birthday=?
where id = ?;
-->
<select id="listByConditionWhen" resultType="com.wjy.polo.User">
<!--引入基础定义标签-->
<include refid="baseSql"/>
<!--where 标签,可以自动删除 以 and | or 开头的 and|or-->
<where>
<!--choose 标签,会判断when标签是否有true,如果有,则数据true标签内内容,如果都为false,则输出otherwise内容-->
<choose>
<when test="username != null">AND username = #{username}</when>
<when test="password != null">AND password = #{password}</when>
<otherwise>AND id = 1</otherwise>
</choose>
</where>;
</select>
<!--
当有when为true,输出
select * from user where username=?;
当when都不为true,输出
select * from user where id=1;
-->
<select id="listByUsernameLike" resultType="com.wjy.polo.User" parameterType="String">
<!--设置变量 基本类型参数-->
<bind name="userLike" value="'%' + _parameter + '%'"/>
<!--引入基础定义标签-->
<include refid="baseSql"/>
where username like #{userLike};
</select>
<!--
输出SQL:
select * from user where username like ?;
参数:
userLike=“%String%”
-->
<select id="listByUserUsernameLike" resultType="com.wjy.polo.User" parameterType="com.wjy.polo.User">
<!--设置变量 包装类型参数-->
<bind name="userLike" value="'%' + _parameter.getUsername() + '%'"/>
<!--引入基础定义标签-->
<include refid="baseSql"/>
where username like #{userLike};
</select>
<!--
输出SQL:
select * from user where username like ?;
参数:
userLike=“%user.username%”
-->
原理
Mybatis启动的时候会解析XML文件,此时会区分动态SQL和静态SQL分别存储,后续执行SQL的时候,会使用OGNL
表达式对动态SQL进行解析;
上图为Mybatis解析XML中的流程:
- 这一步是
XMLConfigBuilder
创建XMLMapperBuilder
来解析XXXMapper.xml
文件 - 这一步是
XMLMapperBuilder
创建XMLStatementBuilder
来解析XXXMapper.xml
中select,insert,update,delete
标签内容 XMLLanguageDriver
是用来解析select,insert,update,delete
标签包裹的SQL
3.1XMLLanguageDriver
检测SQL为动态SQL,创建DynamicSqlSource
3.2XMLLanguageDriver
检测SQL为静态SQL,创建RawSqlSource
3.3XMLLanguageDriver
检测SQL为<script>
标签包裹的SQL,创建XMLScriptBuilder
来进一步处理<script>
中的SQLXMLScriptBuilder
的作用和XMLLanguageDriver
一样,只不过他是最终处理