<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集合的键等。

openclose配置以什么符号把集合元素包装起来。

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);
       }
   }

运行结果:

MyBatis动态SQL

<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>的传入参数

运行结果:

MyBatis动态SQL

相关文章: