- 简介
- 1. if
- 2. choose, when, otherwise 多个条件判断
- 3. where、set
- 4. trim 标记=格式化标记,是一个更加智能化的标记。可以与其他标记组合完成where与set标记的功能
- 5. foreach 标记
- 6. bind
- 7. 多数据库支持
- 8. 动态 SQL 中的可插拔脚本语言
简介
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
1. if
if判断使用
<select id="selectOne" resultType="int">
select * from product where 1 = 1
<if test="money != null">
and money > #{money}
</if>
</select>
注意:第一个money代表实体类的属性名称,第二个money代表表字段名称,第三个是参数
2. choose, when, otherwise 多个条件判断
<choose>
<when test="userName != null">
and userName like ${userName}
</when>
<when test="id != null">
and id = #{id}
</when>
<otherwise>
and password is not null
</otherwise>
</choose>
3. where、set
where会只能添加或者消减逻辑运算符
select * from product
<where>
<if test = "userName != null">
and userName link ${userName}
</if>
<if test="id != null">
and id = #{id}
</if>
</where>
set标记用于update操作,能够智能赋值
update product
<set>
<if test="productName != null">
productName = #{productName},
</if>
<if test="id != null">
id = #{id},
</if>
</set>
4. trim 标记=格式化标记,是一个更加智能化的标记。可以与其他标记组合完成where与set标记的功能
属性 | 属性说明 |
---|---|
prefix | 增加前缀 |
suffix | 增加后缀 |
prefixOverrides | 自动判断前置 |
suffixOverrides | 自动判断后置 |
用trim替换set
<trim prefix="set" suffixOverrides=",">
<if test="userName != null and userName != '' ">
userName = #{userName}
</if>
</trim>
用trim代替where
select * from product
<trim prefix="where" prefixOverrides="and|or">
<if test="userName != null">
and userName like ${userName}
</if>
<if test="id != null">
and id = #{id}
</if>
</trim>
5. foreach 标记
foreach 标记 表示循环
属性 | 说明 |
---|---|
item | 每一次迭代结果 |
collection | 循环集合或指定类型 |
separator | 元素之间的分割符号,可选 |
open | 开始符号,可选 |
close | 关闭符号,可选 |
index | list和数组的序号,可选 |
<insert id="addUserInfoAll" parameterType="java.util.List">
INSERT into userinfo(userName,PASSWORD,email) values
<foreach collection="list" item="lt" separator=",">
(#{lt.userName},#{lt.password},#{lt.email})
</foreach>
</insert>
6. bind
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
7. 多数据库支持
一个配置了“_databaseId”变量的 databaseIdProvider 可用于动态代码中,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:
<insert id="insert">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
<if test="_databaseId == 'oracle'">
select seq_users.nextval from dual
</if>
<if test="_databaseId == 'db2'">
select nextval for seq_users from sysibm.sysdummy1"
</if>
</selectKey>
insert into users values (#{id}, #{name})
</insert>
8. 动态 SQL 中的可插拔脚本语言
MyBatis 从 3.2 开始支持可插拔脚本语言,这允许你插入一种脚本语言驱动,并基于这种语言来编写动态 SQL 查询语句。
可以通过实现以下接口来插入一种语言:
public interface LanguageDriver {
ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql);
SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType);
SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType);
}
一旦设定了自定义语言驱动,你就可以在 mybatis-config.xml 文件中将它设置为默认语言:
<typeAliases>
<typeAlias type="org.sample.MyLanguageDriver" alias="myLanguage"/>
</typeAliases>
<settings>
<setting name="defaultScriptingLanguage" value="myLanguage"/>
</settings>
除了设置默认语言,你也可以针对特殊的语句指定特定语言,可以通过如下的 lang 属性来完成:
<select id="selectBlog" lang="myLanguage">
SELECT * FROM BLOG
</select>
或者,如果你使用的是映射器接口类,在抽象方法上加上 @Lang 注解即可:
public interface Mapper {
@Lang(MyLanguageDriver.class)
@Select("SELECT * FROM BLOG")
List<Blog> selectBlog();
}
**注意 **可以将 Apache Velocity 作为动态语言来使用,更多细节请参考 MyBatis-Velocity 项目。
你前面看到的所有 xml 标签都是由默认 MyBatis 语言提供的,而它由别名为 xml 的语言驱动器 org.apache.ibatis.scripting.xmltags.XmlLanguageDriver 所提供。