目录
项目的创建和之前一样,具体的看之前的文章,整体结构就是这样
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。 语法: 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>
测试
@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(); }
此时即使数据库中,无论年纪多大的都会被查出来,所以就有了下面的标签
标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1 的子句。因为,若 where 后 的所有条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会 严重影响查询效率
使用标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加where 子句。需要注意的是,第一个标签中的 SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and 去掉。但其它中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错
接口方法
// 动态的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 collection=" 集合类型" open=" 开始的字符" close=" 结束的字符" item=" 集合中的成员" separator=" 集合成员之间的分隔符"> #{item 的值} </foreach>
例子,查询学号1001、1002、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);
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='[email protected]', 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 语句中的任何部分,所以子标签可以放在动态 SQL的任何位置
接口方法:
List<Student> selectStudentSqlFragment(List<Student> stuList);
<!-- 创建 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语句之后
标签里面多个if标签,如果有一个if判断为true,就会在sql的后面加入where关键字,而还会自动的去掉无用的and、or等字符
循环数组,list集合,主要看语法格式
复用常用的sql语句
原文链接:https://www.cnblogs.com/mengd/p/13455476.html