6.1动态sql
sql的内容是变化的,可以根据条件获取到不同的sql语句(主要是where部分发生变化)
动态sql的实现,使用的是mybatis提供的标签,<if>
,where>
,<foreach>
-
<if>
判断条件
语法:<if test="判断java对象的属性值"> 部分sql语句 </if>
mapper文件
test中的name等代表对象的属性名,要注意语句中的or,and等关键词不要少了,缺了就不是一个完整的sql语句<select id="selectSqlIf" resultType="com.mybatis.domain.Student"> select id,name,email,age from student where <if test="name !=null and name!='' "> name=#{name} </if> <if test="age > 0"> or age > #{age} </if> </select>
如果我们没有设置name值,执行程序则会报错(因为第二个判断语句最前面有个or),但是我们可以在where后面加一个 1=1(或者其他恒等形式但不对后面的语句造成影响),就可以解决这个问题;此外还有解决以上问题的方法---`<where>`
-
<where>
用来包含 多个<if>
的,当多个if有一个成立的,<where>
会自动增加一个where关键字,并去掉 if中多余的 and ,or等mapper文件
<select id="selectSqlWhere" resultType="com.mybatis.domain.Student"> select id,name,email,age from student <where> <if test="name !=null and name!='' "> name=#{name} </if> <if test="age > 0"> or age > #{age} </if> </where> </select>
实现类
@Test public void test01ByWhere(){ SqlSession sqlSession= MyBatisUtils.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); Student student=new Student(); student.setName("中文"); student.setAge(4); List<Student> l=dao.selectSqlWhere(student); for (Student s : l) { System.out.println(s); } }
接下来我们分别注释掉
student.setAge(4)
和student.setName("中文")
,最后把这两个同时注释掉结果图
可以看到,
<where>
已经帮我加上了where关键词和会把多余的and,or之类的关键字除去,当判断条件都没有时,where也一并消失了 -
<foreach>
循环java中的数组,list集合的。 主要用在sql的in语句中;如学生id是 1001,1002,1003的三个学生==>select * from student where id in (1001,1002,1003)
方法一
接口
public interface StudentDao { List<Student> selectForEach(List<Integer> myid); }
mapper文件
<select id="selectForEach" resultType="com.mybatis.domain.Student"> select * from student where id in <foreach collection="list" item="myid" open="(" close=")" separator=","> #{myid} </foreach> </select>
- collection:表示接口中的方法参数的类型, 如果是数组使用array , 如果是list集合使用list
- item:自定义的,表示数组和集合成员的变量
- open:循环开始是的字符
- close:循环结束时的字符
- separator:集合成员之间的分隔符
调用类
@Test public void test01ByForEach(){ SqlSession sqlSession= MyBatisUtils.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); List<Integer> list=new ArrayList<>(); list.add(1001); list.add(1002); list.add(1003); List<Student> student=dao.selectForEach(list); for (Student s: student ) { System.out.println(s); } }
[图片上传失败...(image-d08124-1595058507674)]
方法二(当循环目标是对象时)
接口
public interface StudentDao { List<Student> selectForEachStu(List<Student> mystu); }
mapper文件
<select id="selectForEachStu" resultType="com.mybatis.domain.Student"> select * from student where id in <foreach collection="list" item="stu" open="(" close=")" separator=","> #{stu.id} </foreach> </select>
@Test public void test01ByForEachStu(){ SqlSession sqlSession= MyBatisUtils.getSqlSession(); StudentDao dao=sqlSession.getMapper(StudentDao.class); List<Student> stulist=new ArrayList<>(); Student s1=new Student(); s1.setId(1003); stulist.add(s1); s1=new Student(); s1.setId(1005); stulist.add(s1); List<Student> student=dao.selectForEachStu(stulist); for (Student s: student ) { System.out.println(s); } }
对于一些经常用且可以进行服用的语句,我们可以定义起来,需要时直接调用
步骤
1. 先定义 <sql id="自定义名称唯一"> sql语句, 表名,字段等 </sql>
2. 再使用, <include refid="id的值" />
例子(mapper文件)
<sql id="sqlone">select * from student</sql>
<select id="selectSqlIf" resultType="com.mybatis.domain.Student">
<include refid="sqlone"></include>
where
<if test="name !=null and name!='' ">
name=#{name}
</if>
<if test="age > 0">
or age > #{age}
</if>
</select>