MyBatis日常笔记记录08--动态sql
一、什么是动态SQL
动态SQL,通过MyBatis提供的各种标签队条件作出判断以实现动态拼接SQL语句。这里的条件判断使用的表达式为OGNL表达式。常用的动态SQL标签有<if>、<where>、<choose/>、<foreach>等。
二、动态SQL的好处
动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行
查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行
排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题。
三、常用的动态SQL标签方法演示
1.动态sql-if
<if>是判断条件的,
语法<if test="判断java对象的属性值">
部分sql语句
</if>
a.在接口中定义一个方法
//动态sql-if,使用java对象作为参数 List<Student> selectStudentIf(Student student);
b.在mapper文件中编写映射信息
<!--if <if test="使用参数java对象的属性值作为判断条件, 语法 属性=xxx值"> --> <select id="selectStudentIf" resultType="com.example.domain.Student"> select id, name, email, age from student where id>0 /*id > 0:避免第一条判断不执行时,sql语句会发生错误,如where and age>?(错误语法)*/ <if test="name !=null and name !=''"> and name = #{name} </if> <if test="age>0"> and age > #{age} </if> </select>
c.编写测试类
@Test public void testSelectStudentsIf() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Student student = new Student(); student.setName("李四"); student.setAge(18); List<Student> students = dao.selectStudentIf(student); for(Student stu : students){ System.out.println("if=="+stu); } }
2.动态sql-where
<where>标签用来包含多个<if>的,当多个if有一个成立时,<where>会自动增加一个where关键字,并去掉if中多余的 and,or等
a.在接口中定义一个方法
//动态sql-where List<Student> selectStudentWhere(Student student);
b.在mapper文件中编写映射信息
<!-- where:<where><if></if>...<where> --> <select id="selectStudentWhere" resultType="com.example.domain.Student"> select id, name, email, age from student <where> <if test="name !=null and name !=''"> and name = #{name} </if> <if test="age>0"> and age > #{age} </if> </where> </select>
c.编写测试类
@Test public void testSelectStudentsWhere() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Student student = new Student(); //student.setName("李四"); student.setAge(18); List<Student> students = dao.selectStudentWhere(student); for(Student stu : students){ System.out.println("where=="+stu); } }
3.动态sql-foreach
<foreach>循环Java中的数值,list集合的,主要用在sql的in语句中
sql中语句是: select * from student where id in(1001,1002,1003);
在开始foreach前先了解然后通过字符串拼接的方法来得到上面的语句
@Test public void testfor(){ List<Integer> list = new ArrayList<>(); list.add(1001); list.add(1002); list.add(1003); //select * from student where id in(1001,1002,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=="+sql); }
foreach本质上用到上面的字符串拼接的方法
<foreach collection="" item="" open="" close="" separator="">
</foreach>
collection : 表示接口中的方法参数的类型,如果是数值使用array,如果是List集合使用list
item : 自定义的,表示数组和集合成员变量
open : 循环开始时的字符
close : 循环结束时的字符
separator : 集合成员之间的分隔符
a.在接口中定义方法
//foreach用法1 List<Student> selectForeachOne(List<Integer> idList); //foreach用法2 List<Student> selectForeachTwo(List<Student> stuList);
b.在mapper文件中编写映射信息
<!--foreach使用1,List<Integer>--> <select id="selectForeachOne" resultType="com.example.domain.Student"> select * from student where id in <foreach collection="list" item="myid" open="(" close=")" separator=","> #{myid} </foreach> </select> <select id="selectForeachTwo" resultType="com.example.domain.Student"> select * from student where id in <foreach collection="list" item="stu" open="(" close=")" separator=","> #{stu.id} </foreach> </select>
c.编写测试类
@Test public void testSelectStudentsForEachOne() { 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> students = dao.selectForeachOne(list); for(Student stu : students){ System.out.println("foreach--one"+stu); } } @Test public void testSelectStudentsForEachTwo() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> stuList = new ArrayList<>(); Student s1 = new Student(); s1.setId(1001); stuList.add(s1); Student s2 = new Student(); s2.setId(1005); stuList.add(s2); List<Student> students = dao.selectForeachTwo(stuList); for(Student stu : students){ System.out.println("foreach--two"+stu); } }
4.动态sql-代码片段
sql代码片段,就是复用一些语法
步骤:1.先定义 <sql id="自定义名称唯一"> sql语句 ,表名 , 字段等</sql>
2.再使用,<include refid="id的值">
演示:
<!--定义sql片段--> <sql id="studentSql"> select id, name, age, email from student </sql> <!--if <if test="使用参数java对象的属性值作为判断条件, 语法 属性=xxx值"> --> <select id="selectStudentIf" resultType="com.example.domain.Student"> /*select id, name, email, age from student*/ <include refid="studentSql"/> where id>0 /*id > 0:避免第一条判断不执行时,sql语句会发生错误,如where and age>?(错误语法)*/ <if test="name !=null and name !=''"> and name = #{name} </if> <if test="age>0"> and age > #{age} </if> </select>