<!--
为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。
id: 代码块的名称
用<include>标签来调用 <include refid="sql标签的idming">
-->
<sql id="Example_Where_Clause">
<!--
where 标签会知道如果它包含的标签中有返回值的话,
它就插入一个‘where’。
此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
-->
<where>
<!--
当传入参数为数组或者集合时需要通过<foreach></foreach>标签进行遍历
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
-->
<foreach collection="oredCriteria" item="criteria" separator="or">
<!--if 用来执行判断 test:判断条件-->
<if test="criteria.valid">
<!--
trim标记是一个格式化的标记,可以完成set或者where的功能;
prefix :添加前缀,在trim开始部分添加内容;
suffix:添加后缀,在trim 结束部分添加内容;
prefixOverrides:去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定.
suffixOverrides:去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定。
-->
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<!--
choose (when, otherwise)标签
有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。
而使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。
MyBatis 提供了 choose 元素。
if标签是与(and)的关系,而 choose 是或(or)的关系。
当 when 中有条件满足的时候,就会跳出 choose,即所有的 when 和 otherwise 条件中,只有一个会输出
-->
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
<!--
#{ }:解析为一个 JDBC 预编译语句(prepared statement)的参数标记符。
${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换.
用法:
1、能使用 #{ } 的地方就用 #{ }
首先这是为了性能考虑的,相同的预编译 sql 可以重复利用。其次,${ } 在预编译之前已经被变量替换了,这会存在 sql 注入问题。
2. 表名作为变量时,必须使用 ${ }
这是因为,表名是字符串,使用 sql 占位符替换字符串时会带上单引号 '',这会导致 sql 语法错误
-->
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
sql预编译
1. 定义:
sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。
2. 为什么需要预编译
JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优化 sql 的执行。预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。预编译语句对象可以重复利用。把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。mybatis 默认情况下,将对所有的 sql 进行预编译。