mybatis中特征之一是支持动态SQL
通过标签的形式来动态编写SQL,根据业务逻辑来动态的进行SQL拼接功能
mybatis提供九种动态SQL标签:trim/if/where/set/foreach/choose/when/otherwise/bind
执行原理:使用OGNL从SQL参数对象中动态计算表达式的值,根据表达式的值动态拼接SQL,以此完成动态SQL的功能
一、标签
1.1 if标签
动态SQL通常作为where子句的一部分
常用于查询、插入、更新等操作
场景:根据姓名、性别、姓名和性别查询相应的数据
<if test="Sname!=null">
Sname=#{Sname}
</if>
if 表达式中判断参数是否传递:if test属性,该属性必填,为true或者false,test使用OGNL表达式处理,返回为true则进入if标签中的SQL,返回为false则不会进入标签中
<!--
第一种条件:name和Sex都传递:select * from student where Sname=XX and Ssex=XXX
第二种条件:只传递name:select * from student where Sname=XX
第三种条件:只传递Sex:select * from student where Ssex=XXX
第四种条件:不传递参数:select * from student
-->
<select id="selectStudentByNameOrSex" parameterType="student" resultMap="studentMap">
select * from student where 1=1
<if test="Sname!=null">
and Sname=#{Sname}
</if>
<if test="Ssex!=null">
and Ssex=#{Ssex}
</if>
</select>
第一种条件:传递两个参数:
第二种:只传递Sname属性
第三种条件:只传递Ssex属性
第四种条件:不传递属性
1.2 where标签
where标签作用:
<select id="selectStudentByNameOrSex" parameterType="student" resultType="student">
select * from student
<where>
<if test="Sname!=null">
and Sname=#{Sname}
</if>
<if test="Ssex!=null">
and Ssex=#{Ssex}
</if>
</where>
</select>
第一种条件:传递两个参数:
第二种条件:只传递Sname属性
第三种条件:只传递Ssex属性
第四种条件:不传递属性
where表达式一般和if表达式一块使用,如果条件一个都不满足,则不拼接where条件,如果有一个或者多个表达式成立,where会直接拼接在SQL语句上,并且紧随的where表达式的and/or会忽略掉
1.3 trim标签
mybatis提供trim标签一般适用于去除SQL语句中多余的and关键字,逗号,或者给SQL语句拼接“where”、“set”以及values等,可用于选择性插入、更新、删除或者条件查询等操作,where和set标签都可以通过trim标签来实现
trim属性:
trim标签可以和上面的where实现相同的功能
<select id="selectStudentByNameOrSex" parameterType="student" resultType="student">
select * from student
<trim prefix="where" prefixOverrides="and">
<if test="Sname!=null">
and Sname=#{Sname}
</if>
<if test="Ssex!=null">
and Ssex=#{Ssex}
</if>
</trim>
</select>
1.4 foreach标签
适用于批量操作
场景1:通过一批id来查询student
select * from student where SID in(1,2,3,4,5);
List<Student> selectBatchQueryStudent(List<Integer> idx);
<!--
select * from student where SID in(1,2,3,4,5);
foreach表达式
collection属性:必填,指定参数入参类型
参数类型可以是 (列表:List 数组:array HashMap:map)
item属性:起名字,给集合中单个元素起名称
open属性:开始字符串
close属性:结束字符串
separator属性:分隔符
index属性:索引的属性名,在集合数组下值为当前的索引值
-->
<select id="selectBatchQueryStudent" resultType="student">
select * from student where SID in
<foreach collection="List" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
执行结果SQL
select * from student where SID in ( ? , ? , ? , ? , ? , ? )
二、模糊匹配
需求:查询student表中Sname含有w的的信息
select * from student where Sname like "%w%";
mybatis模糊匹配如何写?
方式一:直接在参数上进行模糊匹配
接口方法:
List<Student> selectStudentBySname(String name);
XML配置文件:
<select id="selectStudentBySname" parameterType="String" resultType="student">
select * from student where Sname like #{name}
</select>
测试方法:
@Test
public void selectStudentBySname(){
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectStudentBySname("%r%");
for(Student s:students){
System.out.println(s);
}
sqlSession.commit();
}
执行结果:
方式二:mysql中提供的方法concat()拼接
XML配置文件:
<select id="selectStudentBySname" parameterType="String" resultType="student">
select * from student where Sname like concat('%',#{name},'%')
</select>
测试方法:
public void selectStudentBySname(){
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectStudentBySname("w");
for(Student s:students){
System.out.println(s);
}
sqlSession.commit();
}
执行结果:
方式三:bind表达式处理
接口方法:
List<Student> selectStudentBySname(Student Sname);
XML配置文件:
<select id="selectStudentBySname" parameterType="Student" resultType="student">
<bind name="ln" value="'%'+Sname+'%'"/>
select * from student where Sname like #{ln}
</select>
注意:bind表达式中参数必须具有getter方法,底层是通过OGNL表达式进行解析的,该表达式通过属性的getter方法进行获取值
执行结果: