动态SQL
1、if/where
<!--
test:判断表达式(OGNL自己去查怎么用)
test="id != null":从参数中取值进行判断
拼装的时候有的条件没带可能导致sql拼装会有问题
1、给where后面加上1=1,以后的条件都and
2、mybatis使用<where>标签来将所有查询条件包括,
mybatis就会将where标签中拼装的sql多出来的and或者or去掉
where只会去掉第一个多出来的and或者or
-->
<select id="getEmpsByConditionIfAndWhere" resultType="bean.Employee">
SELECT * FROM t_employee
<where>
<if test="id != null">
id=#{id}
</if>
<if test="lastName != null and lastName != ''">
AND last_name=#{lastName}
</if>
<if test="email != null and email.trim() != ''">
AND email=#{email}
</if>
<if test="gender==0 or gender==1">
AND gender=#{gender}
</if>
</where>
</select>
2、trim自定义字符串截取规则
<!--
若将and放在每个条件之后,<where>标签不能解决拼接的问题
trim:自定义字符串截取规则
prefix="":前缀:trim标签中是整个字符串拼串后的结果
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":前缀覆盖,去掉整个字符串前面多余的字符
suffix="":后缀:
suffix给拼串后的字符串加一个后缀
suffixOverrides="":后缀覆盖,去掉整个字符串后面多余的
-->
<select id="getEmpsByConditionTrim" resultType="bean.Employee">
SELECT * FROM t_employee
<trim prefix="where" suffixOverrides="and">
<if test="id != null">
id=#{id} AND
</if>
<if test="lastName != null and lastName != ''">
last_name=#{lastName} AND
</if>
<if test="email != null and email.trim() != ''">
email=#{email} AND
</if>
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</trim>
</select>
3、choose (when, otherwise):分支选择
<!--
如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个
-->
<select id="getEmpsByConditionChoose" resultType="bean.Employee">
SELECT * FROM t_employee
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null and lastName!=''">
last_name LIKE #{lastName}
</when>
<when test="email!=null and email!=''">
email=#{email}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
4、where-封装查询条件, set-封装修改的条件
<update id="updateEmp">
UPDATE t_employee
<set>
<if test="lastName!=null and lastName!=''">
last_name=#{lastName},
</if>
<if test="email!=null and email!=''">
email=#{email},
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</set>
<where>
id=#{id}
</where>
<!-- UPDATE t_employee
<trim prefix="set" suffixOverrides=",">
<if test="lastName!=null and lastName!=''">
last_name=#{lastName},
</if>
<if test="email!=null and email!=''">
email=#{email},
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</trim>
<where>
id=#{id}
</where>-->
</update>
5、foreach标签——批量处理
<!--
collection:指定要遍历的集合
list类型的参数会特殊处理封装在map中,map的key就是list
item:将当前遍历出的元素赋值给指定的变量
#{变量名}:就能取出变量的值,也就是当前遍历出的元素
separator:每个元素之间的分隔符
open/close:遍历出所有结果拼接一个开始和结束的字符(整个语句以什么开始和什么结束)
index:索引:遍历list的时候就是索引,item就是当前值
遍历map的时候就是map的key,item就是map的value
-->
<select id="getEmpsByConditionForeach" resultType="bean.Employee">
SELECT * FROM t_employee WHERE id IN
<foreach collection="list" item="item_id" separator="," open="(" close=")">
#{item_id}
</foreach>
</select>
<!--批量保存-->
<!--MySQL下批量保存,可以foreach遍历values-->
<!--<insert id="addEmps">
INSERT INTO t_employee(id,last_name,gender,email) VALUES
<foreach collection="emps" item="emp" separator=",">
(#{emp.id},#{emp.lastName},#{emp.gender},#{emp.email})
</foreach>
</insert>-->
<!--该种方法会有语法异常,需要开启sql语句间用“;”分隔的权限—allowMultiQueries=true-->
<insert id="addEmps">
<foreach collection="emps" item="emp" separator=";">
INSERT INTO t_employee(id,last_name,gender,email) VALUES
(#{emp.id},#{emp.lastName},#{emp.gender},#{emp.email})
</foreach>
</insert>
6、内置参数和bind
<!--
两个内置参数:
不只是方法传递过来的参数可以被用来判断、取值
mybatis默认还有两个内置参数:
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map,_parameter就是代表这个map
_databaseId:如果配置了DatabaseIdProvider标签
_databaseId就是代表当前数据库的别名
bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值
<bind name="_lastName" value="'%'lastName'%'"></bind>这样写了就可以不用在传入参数的时候写%号
-->
<select id="getEmpsTestInnerParameter" resultType="bean.Employee">
<bind name="_lastName" value="'%'lastName'%'"></bind>
<if test="_databaseId=='mysql'">
SELECT * FROM t_employee
<if test="_parameter!=null">
WHERE last_name LIKE #{_lastName}
</if>
</if>
<if test="_databaseId=='oracle'">
SELECT * FROM employee
<if test="_parameter!=null">
WHERE last_name=#{lastName}
</if>
</if>
</select>
7、可重用SQL——经常将要查询的列名或插入用的列名抽取出来方便引用
<!--
1、sql标签抽取可重用的sql片段,方便后面引用
里面还可以做动态判断,经常将查询和插入的列名抽取出来
2、include标签就是引用从外部定义的sql
3、include还可以自定义有些property,sql标签内部就能使用自定义的属性,取值的方式${pro},#{}不可以
-->
<sql id="insertColumn">
<if test="_databaseId=='mysql'">
id,last_name,gender,email
</if>
<if test="_databaseId=='oracle'">
--------
</if>
</sql>
<insert id="addEmps">
<foreach collection="emps" item="emp" separator=";">
INSERT INTO t_employee(
<include refid="insertColumn"></include>
) VALUES
(#{emp.id},#{emp.lastName},#{emp.gender},#{emp.email})
</foreach>
</insert>