Sql语句在开发时很多时候都是不固定的,所以Mybatis应要求就有了动态sql语句。sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。动态sql的实现,使用的是mybatis提供的标签, <if> ,<where>,<foreach>
1、<if>标签的使用:<if>是判断条件的
语法:
<if test="判断java对象的属性值">
部分sql语句
</if>
Dao:
public List<Student> selectStudentIf(Student student);
mapper文件中:
注:test写的是判断的内容
<select id="selectStudentIf" resultType="com.gx.pojo.Student">
select * from student
where 1=1
<if test="name != null and name != ''">
and name=#{name}
</if>
<if test="age > 0">
or age>#{age}
</if>
</select>
测试:
public void testSelectStudentIf(){
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//使用mybatis动态代理
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
//准备参数
Student student = new Student();
student.setName("鲁班大师");
student.setAge(18);
//执行
List<Student> students = studentDao.selectStudentIf(student);
//关闭SqlSession
sqlSession.close();
//遍历输出
for(Student stu : students){
System.out.println("if查询的学生="+stu);
}
}
结果:
使用<if>存在缺陷,会造成sql语句错误,1=1是为了弥补缺陷的<where>标签也可以弥补该缺陷
例如:select student_id,name,sex,age,email from student or age> ?
2、<where>标签的使用:<where> 用来包含 多个<if>的, 当多个if有一个成立的, <where>会自动增加一个where关键字,并去掉 if中多余的 and ,or等。
语法:
<where>
多个<if>标签
</where>
Dao:
public List<Student> selectStudentWhere(Student student);
mapper文件中:
<select id="selectStudentWhere" resultType="com.gx.pojo.Student">
select * from student
<where>
<if test="name != null and name != ''">
name=#{name}
</if>
<if test="age>0">
or age>#{age}
</if>
</where>
</select>
测试:
public void testSelectStudentWhere(){
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//使用mybatis动态代理
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
//准备参数
Student student = new Student();
student.setName("鲁班大师");
student.setAge(18);
//执行
List<Student> students = studentDao.selectStudentWhere(student);
//关闭SqlSession
sqlSession.close();
//遍历输出
for(Student stu : students){
System.out.println("where查询的学生="+stu);
}
}
结果:
3、<foreach>标签的使用:
<foreach> 循环java中的数组,list集合的。主要用在sql的in语句中。
例如查询:学生id是 1001,1002,1003的三个学生。
语法:
注:
collection:指定循环的类型,数组类型用array,list集合类型用list
item:自定义,代表数组或集合的成员变量
open:循坏开始拼接的字符
close:循环结束拼接的字符
separator:成员之间的分隔符
也可以传入java对象,#{item值 . 属性名称}
<foreach collection="list" item="myId" open="(" close=")" separator=",">
#{myId}
</foreach>
Dao:
public List<Student> selectStudentForeachOne(List<Integer> idList);
mapper文件中:
<select id="selectStudentForeachOne" resultType="com.gx.pojo.Student">
select * from student where student_id in
<foreach collection="list" item="myId" open="(" close=")" separator=",">
#{myId}
</foreach>
</select>
测试:
public void testSelectStudentForeachOne(){
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//使用mybatis动态代理
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
//准备参数
List<Integer> idList = new ArrayList<>();
idList.add(1002);
idList.add(1003);
idList.add(1004);
//执行
List<Student> listStudent = studentDao.selectStudentForeachOne(idList);
//关闭SqlSession
sqlSession.close();
//遍历循环
for(Student stu : listStudent){
System.out.println("ForeachOne查询学生="+stu);
}
}
结果:
<foreach>标签可以使用的很灵活,例如不需要open="(" close=")" separator=","这三个属性,直接在sql语句中拼接也是可以的,脑洞有多大使用就有多广。