<if>元素
在实际开发中,可以通过多个条件来精确的查询数据。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.swjd.mapper.StudentMapper1">
<select id="findStudent" parameterType="cn.swjd.entries.Student" resultType="cn.swjd.entries.Student">
select * from student where 1=1
<if test="st_no !=null and st_no !=''">
and st_no=#{st_no}
</if>
<if test="st_name !=null and st_name !=''">
and st_name like concat('%',#{st_name},'%')
</if>
</select>
</mapper>
如上,如果<if>里的条件成立,就会动态拼接sql语句。以上配置文件可以实现根据学号查找学生信息,根据姓名模糊查找学生信息,根据学号姓名精确查找学生信息以及查询所有学生信息。
choose>(<when> <otherwise>)元素
使用<if>时,只要test里面的条件成立,就会拼接sql语句。
如果只需要从多个选择中执行一个呢?
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.swjd.mapper.StudentMapper2">
<select id="findStudent" parameterType="cn.swjd.entries.Student" resultType="cn.swjd.entries.Student">
select * from student where 1=1
<choose>
<when test="st_no !=null and st_no !=''">
and st_no=#{st_no}
</when>
<when test="st_name !=null and st_name !=''">
and st_name like concat('%',#{st_name},'%')
</when>
<otherwise>and tel is not null</otherwise>
</choose>
</select>
</mapper>
如上,会根据<choose>里面的<when>依次判断条件是否成立,成立就拼接里面的sql语句并结束拼接,如果<when>都不成立,就会拼接<otherwise>里面的sql语句。
<where>、<trim>元素
使用<where>就可以不在sql语句末为加”where 1=1”,只要<where>语句内的条件成立,才会在要拼接的sql语句末尾加where关键字,还会自动删除where后面多余的“and”或者“or”。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.swjd.mapper.StudentMapper3">
<select id="findStudent" parameterType="cn.swjd.entries.Student" resultType="cn.swjd.entries.Student">
select * from student
<where>
<if test="st_no !=null and st_no !=''">
and st_no=#{st_no}
</if>
<if test="st_name !=null and st_name !=''">
and st_name like concat('%',#{st_name},'%')
</if>
</where>
</select>
</mapper>
还可以使用<trim>元素达到同样的效果
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.swjd.mapper.StudentMapper4">
<select id="findStudent" parameterType="cn.swjd.entries.Student" resultType="cn.swjd.entries.Student">
select * from student
<trim prefix="where" prefixOverrides="and">
<if test="st_no !=null and st_no !=''">
and st_no=#{st_no}
</if>
<if test="st_name !=null and st_name !=''">
and st_name like concat('%',#{st_name},'%')
</if>
</trim>
</select>
</mapper>
如果<trim>里面有条件成立的话,就会自动在sql语句末加prefix 的属性值,
加了后如果prefix的属性值后面遇到了prefixOverrides的属性值,就会自动删除prefixOverrides的属性值。
<set>元素
如果要更新表里的某条记录时,就要发送所有的字段给持久化对象,然而实际应用中,只需要更新一个或几个字段。如果每次更新都把所有字段都更新一遍,那么执行效率是十分差的。那么有没有办法让程序只更新需要更新的字段呢?
使用<set>元素可以解决这个问题:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.swjd.mapper.StudentMapper5">
<!-- 更新学生信息 -->
<update id="updateStudent" parameterType="cn.swjd.entries.Student">
update student
<set>
<if test="st_name !=null and st_name !=''">
st_name=#{st_name},
</if>
<if test="sex !=null and sex !=''">
sex=#{sex},
</if>
<if test="tel !=null and tel !=''">
tel=#{tel},
</if>
<if test="address !=null and address !=''">
address=#{address},
</if>
</set>
where st_no=#{st_no}
</update>
</mapper>
上面使用了<set>和<if>元素相组合的方式来动态组装update语句,<set>元素会动态前置SET关键字,并且会消除句末的逗号。
<foreach>元素
在实际开发中,如果要我们查询id从a到b的所有记录,或者查询id=2,3,44,33时的记录时,该怎么做呢?一条一条查显然是不行的,效率低下。
这时,我们就可以使用<foreach>元素。
<!-- 根据多个学号查询学生信息 -->
<select id="findStudentByIds" parameterType="List" resultType="cn.swjd.entries.Student">
select * from student where st_no in
<foreach collection="array" item="st_no" open="(" separator="," close=")">
#{st_no}
</foreach>
</select>
属性说明:
item:配置循环的元素
collection:配置传入类型,可以是array、list、Map集合的键等。
open和close:配置以什么符号把集合元素包装起来。
separator:配置各个元素之间的分隔符。
测试代码:
public static void main(String args[]) throws Exception{
SqlSession sqlSession = MyBatisUtils.getSession();
int ids[]={2,3,5};
List<Student> students=sqlSession.selectList("cn.swjd.mapper.StudentMapper.findStudentByIds", ids);
for(Student s:students){
System.out.println(s);
}
}
运行结果:
<bind>元素
在进行模糊查询编写SQL语句时,如果使用“${}”进行字符串拼接,则无法防止sql注入问题;如果使用concat函数进行拼接,只针对MySQL和Sql Server数据库有效;如果使用的是Oracle数据库,则要使用连接符“||”。这样就不利于项目的移植。为此,MyBatis提供了<band>元素来进行字符串拼接。
<!-- 根据姓名模糊查询学生信息 -->
<select id="findStudentByName" parameterType="String" resultType="cn.swjd.entries.Student">
<bind name="name" value="'%'+_parameter+'%'"/>
select * from student where st_name like #{name}
</select>
参数说明:
_parameter:使用<select>的传入参数
运行结果: