if、choose(when,otherwise)、trim(where,set)、foreach
if标签:
<!--public List<StudentBean> getStudentsForIf(StudentBean student);-->
<select id="getStudentsForIf" resultType="com.learncmzy.pojo.StudentBean">
select * from t_student where 1=1
<!-- test中使用的是OGNL表达式,从参数中取的值 -->
<if test="id != null and id != ''">
and id=#{id}
</if>
<if test="cnname != null and cnname.trim() != ''">
and cnname=#{cnname}
</if>
<if test="sex != null and sex!= ''">
and sex=#{sex}
</if>
</select>
where标签:
使用上述方式是手动在where 后面添加1=1条件,免得如果第一个参数不存在,sql语法错误。还可以使用where标签,同时使用where 标签它只能去除and在条件前面的,不能在后面的,如下形式:
<select id="getStudentsForIf" resultType="com.learncmzy.pojo.StudentBean">
select * from t_student
<where>
<!-- test中使用的是OGNL表达式,从参数中取的值 -->
<if test="id != null and id != ''">
id=#{id}
</if>
<if test="cnname != null and cnname.trim() != ''">
and cnname=#{cnname}
</if>
<if test="sex != null and sex!= ''">
and sex=#{sex}
</if>
</where>
</select>
<!--下面这种方式是可能会引起sql语法错误的,where标签无法可能无法去除多余的and-->
<select id="getStudentsForIf" resultType="com.learncmzy.pojo.StudentBean">
select * from t_student
<where>
<!-- test中使用的是OGNL表达式,从参数中取的值 -->
<if test="id != null and id != ''">
id=#{id} and
</if>
<if test="cnname != null and cnname.trim() != ''">
cnname=#{cnname} and
</if>
<if test="sex != null and sex!= ''">
sex=#{sex}
</if>
</where>
</select>
trim标签:
prefix:前缀,trim标签体中整个字符串拼接完后,给拼接完后的字符串添加一个前缀
prefixOverrides:前缀覆盖,去掉整个字符串前面多余指定的字符串
suffix:给拼接完后的整个字符换添加一个后缀
suffixOverrides:后缀覆盖,去掉整个字符串后面多余的指定字符串
<select id="getStudentsForTrim" resultType="com.learncmzy.pojo.StudentBean">
select * from t_student
<trim prefix="where" suffixOverrides="and">
<!-- test中使用的是OGNL表达式,从参数中取的值 -->
<if test="id != null and id != ''">
id=#{id} and
</if>
<if test="cnname != null and cnname.trim() != ''">
cnname=#{cnname} and
</if>
<if test="sex != null and sex!= ''">
sex=#{sex}
</if>
</trim>
</select>
choose标签:分支选择
<select id="getStudentsForChoose" resultType="com.learncmzy.pojo.StudentBean">
select * from t_student
<where>
<choose>
<when test="id != null and id != ''">
where id=#{id}
</when>
<when test="cnname != null and cnname.trim() != ''">
where cnname=#{cnname}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
set标签:用于更新操作sql,可以自动处理set标签中的sql语句,将多余的逗号自动清理,当然也可以用trim标签实现同样的功能。
<update id="updateStudent">
update t_student
<set>
<if test="cnname != null and cnname.trim() != ''">
cnname=#{cnname},
</if>
<if test="note != null and note != ''">
note=#{note}
</if>
</set>
<where>
id=#{id}
</where>
</update>
foreach标签:
collection :传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时 候,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键。
item:将遍历出的元素赋值给指定的变量,使用#{变量名}就能取出变量的值,也就是当前遍历出的元素。
separator:每个元素之间的分隔符
open:遍历出所有结果拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
index:索引,遍历list的时候index就是索引,item就是当前值
遍历map的时候index表示的就是map的key,item就是map的值
public List<StudentBean> getStudentsForForeach(List<Integer> ids);
<select id="getStudentsForForeach" resultType="com.learncmzy.pojo.StudentBean">
select * from t_student where id in
//注意因为是List类型,所以collection中的值是mybatis自动封装了的,就是list,index中的值也是封装的,就是index
<foreach collection="list" item="item_id" separator="," open="(" close=")" index="index">
#{item_id}
</foreach>
</select>
使用foreach批量保存:
<insert id="addStudents">
insert into t_student(cnname,sex,note,class_info) values
//这里separator设置用于区分多条()之间的逗号。
<foreach collection="list" item="student" separator=",">
(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id})
</foreach>
</insert>
上面的语句在执行的时候实际上是转换成下面的sql,mysql支持插入多条的语法:
insert into t_student(cnname,sex,note,class_info) values (?,?,?,?) , (?,?,?,?)
Preparing: insert into t_student(cnname,sex,note,class_info) values (?,?,?,?) , (?,?,?,?)
==> Parameters: name1(String), FMALE(String), aaaaa(String), 1(Integer), name2(String), FMALE(String), bbbbb(String), 1(Integer)
mysql批量保存还有下面这种形式:这种方式需要数据库连接属性allowMultiQueries设置为true,以支持同时执行多条sql语句。分号分隔也可以用于批量更新,删除。
<insert id="addStudents">
<foreach collection="list" item="student" separator=";">
insert into t_student(cnname,sex,note,class_info) values
(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id})
</foreach>
</insert>
oralce的批量插入方式:
begin
insert into tableName() values();
insert into tableName() values();
insert into tableName() values();
end;
<insert id="addStudentsOracle" databaseId="oralce">
begin
<foreach collection="list" item="item" >
insert into t_student(cnname,sex,note,class_info) values(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id});
</foreach>
end;
</insert>
oracle可以利用中间表批量插入
两个内置参数:
不只是方法传递过来的参数可以被用来判断,取值等,mybatis默认还有两个内置参数
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map,_parameter就是代表这个map
_databaseId:如果全局配置中配置了databaseIdProvider标签。_databaseId就是代表当前数据库的别名。
使用_databaseId来判断数据库,从而执行相应数据库sql语句,在没有使用_databaseId的情况下,通常需要写两个方法,在映射sql语句中配置databaseId指明该映射sql使用哪种数据库,当使用_databaseId可以直接用于判断。
<select id="getStudentsForForeach" resultType="com.learncmzy.pojo.StudentBean">
<if test="_databaseId == mysql">
select * from t_student
</if>
<if test="_databaseId == oralce">
select * from students
</if>
</select>
由于_parameter默认是代表参数,所以可以根据这个来判断参数的情况,从而执行相应的查询如下:
<select id="getStudentsForForeach" resultType="com.learncmzy.pojo.StudentBean">
<if test="_databaseId == mysql">
select * from t_student
<if test="_parameter != null">
where cnname=#{cnname}
</if>
</if>
<if test="_databaseId=oralce">
select * from students
<if test="_parameter != null">
where cnname=#{cnname}
</if>
</if>
</select>
bind标签:可以讲OGNL表达式的值绑定到一个变量中,方便后面引用这个变量的值,如使用like查询的时候,需要在查询条件加%,可以如下使用:
<select id="getStudentsForBind" resultType="com.learncmzy.pojo.StudentBean">
<bind name="_cnname" value="'%'+cnname+'%'"/>
select * from t_student where cnname like #{_cnname}
</select>
sql标签:抽取可重用的sql,方便后面引用,同时在sql标签中使用判断语句,引用_parameter和_databaseId默认参数。
sql抽取,经将要查询的列明,或者插入用的列明抽取出来方便应用
通过include标签引用,iinclude还可以自定义一些property,sql标签内部就能使用自定义的属性,在sql标签内部就可以使用${prop},prop就是include标签中property的name值,#{}这种方式是不能在sql标签中使用的,sql标签中是不能预编译的。
如下所示
<sql id="sqlTest">
<if test="_parameter != null">
cnname,sex,note,class_info,${prop}
</if>
</sql>
<insert id="addStudents">
insert into t_student(
<include refid="sqlTest">
<property name="prop" value="addColName"/>
</include>
) values
<foreach collection="list" item="student" separator=",">
(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id})
</foreach>
</insert>