项目的建立和以前同样,具体的看以前的文章,总体结构就是这样java
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片段拼接到其所在的 SQL 语句中。
语法:<if test=”条件”> sql 语句的部分 </if>sql
接口方法:StudentDao数据库
// 动态的sql时,使用java对象做为参数 List<Student> selectStudentIf(Student student);
mapper文件:StudentDao.xml数组
<!--if的使用 <if test="使用的参数为java对象属性值做为判断条件"> 语法:属性=xxx值 --> <!-- 注意,当这样写的时候,name不知足而age知足的时候会出现问题 正常:select id,name,age,email from student where name = ? or age > ? 不正常: select id,name,age,email from student where or age > ? 这个时候会有语法错误 因此写的是时候要在where后面这样 where 1=1 这样写的话即便name不知足,后面的也不不会出现语法错误 select id,name,age,email from student where 1=1 or age > ? 但这样也会出现其余的bug,由于是or,而且1=1永远为true,因此age不管传入多大都会有数据的 --> <select id="selectStudentIf" resultType="com.md.domain.Student"> select id,name,age,email from student where 1=1 <if test="name != null and name != '' "> name = #{name} </if> <if test="age > 0" > or age > #{age} </if> </select>
测试mybatis
@Test public void testSelectStudentIf(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Student student = new Student(); student.setAge(20); List<Student> studentList = dao.selectStudentIf(student); studentList.forEach(stu-> System.out.println(stu)); sqlSession.close(); }
此时即便数据库中,不管年纪多大的都会被查出来,因此就有了下面的标签app
<if/>标签的中存在一个比较麻烦的地方:须要在 where 后手工添加 1=1 的子句。由于,若 where 后
的全部<if/>条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL
出错。因此,在 where 后,须要添加永为真子句 1=1,以防止这种状况的发生。但当数据量很大时,会
严重影响查询效率dom
使用<where/>标签,在有查询条件时,能够自动添加上 where 子句;没有查询条件时,不会添加where 子句。须要注意的是,第一个<if/>标签中的 SQL 片段,能够不包含 and。不过,写上 and 也不错,系统会将多出的 and 去掉。但其它<if/>中 SQL 片段的 and,必需要求写上。不然 SQL 语句将拼接出错测试
<where> 用来包含 多个<if>的, 当多个if有一个成立的, <where>会自动增长一个where关键字,并去掉 if中多余的 and ,or等ui
语法:<where> 其余动态 sql </where>3d
接口方法
// 动态的sql时,使用java对象做为参数 List<Student> selectStudentWhere(Student student);
mapper
<!--where的使用 select id,name,age,email from student WHERE name = ? or age > ? select id,name,age,email from student WHERE age > ? 这样就避免了上面的bug --> <select id="selectStudentWhere" resultType="com.md.domain.Student"> select id,name,age,email 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 testSelectStudentWhere(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Student student = new Student(); student.setName("白昊天"); student.setAge(20); List<Student> studentList = dao.selectStudentWhere(student); studentList.forEach(stu-> System.out.println(stu)); sqlSession.close(); }
此时就不会出现以前的bug了
<foreach/>标签用于实现对于数组与集合的遍历。对其使用,须要注意:
语法
<foreach collection=" 集合类型" open=" 开始的字符" close=" 结束的字符" item=" 集合中的成员" separator=" 集合成员之间的分隔符"> #{item 的值} </foreach>
例子,查询学号100一、100二、1003学生的信息
若是是用纯java来拼接这个查询sql语句
@Test public void testfor(){ List<Integer> list = new ArrayList<>(); list.add(1001); list.add(1002); list.add(1003); String sql = "select * from student where id in"; StringBuilder builder = new StringBuilder(""); // 添加开始 builder.append("("); for (Integer i : list){ builder.append(i).append(","); } // 由于最后多添加了一个逗号,因此在这里进行删除 builder.deleteCharAt(builder.length()-1); builder.append(")"); sql = sql + builder.toString(); System.out.println(sql); // select * from student where id in(1001,1002,1003) }
接口
// 传入的是普通list List<Student> selectForeachOne(List<Integer> idlist);
mapper
select id,name,age,email from student where id in ( ? , ? , ? )
<select id="selectForeachOne" resultType="com.md.domain.Student"> select id,name,age,email from student where id in <foreach collection="list" item="myid" open="(" close=")" separator=","> #{myid} </foreach> </select>
测试:
@Test public void testSelectForeachOne(){ 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> studentList = dao.selectForeachOne(list); studentList.forEach(stu-> System.out.println(stu)); sqlSession.close(); }
接口
// foreach 用法二 , 传入的是对象集合 List<Student> selectForeachTwo(List<Student> stulist);
mapper文件
因为传入的是对象,因此要用对象.属性
<select id="selectForeachTwo" resultType="com.md.domain.Student"> select id,name,age,email from student where id in <foreach collection="list" item="stu" open="(" close=")" separator=","> #{stu.id} </foreach> </select>
测试方法
@Test public void testSelectForeachTwo(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = new ArrayList<>(); Student stu1 = new Student(); stu1.setId(1003); students.add(stu1); List<Student> studentList = dao.selectForeachTwo(students); studentList.forEach(stu-> System.out.println(stu)); // select id,name,age,email from student where id in ( ? ) // Student{id=1003, name='白昊天', email='ht@qq.com', age=18} sqlSession.close(); }
固然了,对于mapper文件的sql语句还能够这样写
<!-- 直接在外面写小括号,只有能凑成完成的sql语句就行--> <select id="selectForeachTwo" resultType="com.md.domain.Student"> select id,name,age,email from student where id in ( <foreach collection="list" item="stu" separator=","> #{stu.id} </foreach> ) </select>
效果和上面的是同样的,能完成的拼凑出sql语句便可
<sql/>标签用于定义 SQL 片段,以便其它 SQL 标签复用。
而其它标签使用该 SQL 片段,须要使用<include/>子标签。该<sql/>标签能够定义 SQL 语句中的任何部分,因此<include/>子标签能够放在动态 SQL的任何位置
接口方法:
List<Student> selectStudentSqlFragment(List<Student> stuList);
mapper文件
<!-- 建立 sql 片断 id: 片断的自定义名称 --> <sql id="studentSql"> select id,name,email,age from student </sql> <select id="selectStudentSqlFragment" resultType="com.md.domain.Student"> <!-- 引用 sql 片断 --> <include refid="studentSql"/> <if test="list !=null and list.size > 0 "> where id in <foreach collection="list" open="(" close=")" item="stuobject" separator=","> #{stuobject.id} </foreach> < /if> </select>
测试方法
@Test public void testSelectSqlFragment() { List<Student> list = new ArrayList<>(); Student s1 = new Student(); s1.setId(1002); list.add(s1); s1 = new Student(); s1.setId(1005); list.add(s1); List<Student> studentList = studentDao.selectStudentSqlFragment(list); studentList.forEach( stu -> System.out.println(stu)); }
根据条件可以使用不一样的sql语句,使用mybatis标签
判断条件,条件为true,就会把if以前的sql加入到主sql语句以后
<where> 标签里面多个if标签,若是有一个if判断为true,就会在sql的后面加入where关键字,而还会自动的去掉无用的and、or等字符
循环数组,list集合,主要看语法格式
复用经常使用的sql语句