MyBatis 动态SQL
来源:互联网 发布:中小学题库软件 编辑:程序博客网 时间:2024/06/16 02:27
有些时候,静态的SQL脚本并不能很好的满足我们的业务场景,我们需要根据用户捉摸不定的输入,来动态地拼接成一个SQL。例如,多条件组合查询时,我们需要根据用户输入的条件来动态的拼接一个where条件等。本篇来介绍mybatis对动态sql的支持。
数据准备
为了能够更好地演示我的示例代码,我先在mysql中创建一个数据表
CREATE TABLE `students2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `class` varchar(50) DEFAULT NULL, `name` varchar(50) DEFAULT NULL, `gender` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
然后加入几条初始数据
insert into `students2`(`class`,`name`,`gender`) values ('1501','张三',1),('1501','小红',2),('1502','小明',1),('1501','kite',1);
IF条件
假如我们现在要对Students2表进行多条件组合查询,条件包括班级(class),姓名(name)和性别(gender),我们先假设class是必填的,name和gender是选填的,我们针对这个情况,写一个动态sql。
首先,定义我们的实体类
public class Student2 { private int id; private String className; private String name; private int gender; // getters and setters ......}
然后是我们的sql映射文件
<resultMap type="Student2" id="Student2Result"> <id property="id" column="id"/> <result property="className" column="class"/> <result property="name" column="name"/> <result property="gender" column="gender"/></resultMap><select id="searchStudents" resultMap="Student2Result" parameterType="hashmap"> SELECT * FROM STUDENTS2 WHERE CLASS=#{className} <if test="name != null"> AND NAME LIKE #{name} </if> <if test="gender != null"> AND GENDER = #{gender} </if></select>
由于数据表有一列的名字为class,该名字是Java的保留字,我们为Student2类添加了一个名为className的字段。由于两者不一致,所以再resultMap中通过<result property="className" column="class"/>
进行关联。
接下来,我们定义一个映射接口
public interface StudentMapper { public List<Student2> searchStudents(Map<String, Object> map);}
然后,在Main方法中进行调用
public static void main(String[] args) { SqlSession sqlSession = MyBatisSqlSessionFactory.openSession(); try { StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class); Map<String, Object> map = new HashMap<String, Object>(); map.put("className", "1501"); //map.put("name", "%ki%"); map.put("name", "%三%"); //map.put("gender", 2); List<Student2> studts= studentMapper.searchStudents(map); System.out.println("查询结果总数:"+studts.size()); for(Student2 item :studts){ System.out.println("class:"+item.getClassName()+",name:"+item.getName()+ ",gender:"+item.getGender()); } } catch (Exception e) { e.printStackTrace(); }finally { sqlSession.close(); }}
运行这段java代码后,会打印出下面的结果
查询结果总数:1class:1501,name:张三,gender:1
map中有些条件注释掉了,读者可以多试几个条件。
如果查询条件中含有中文字符而不能查出结果的话,请在mysql连接字符串中加入字符集的参数,如下:
<dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/students?useUnicode=true&characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="root" /></dataSource>
WHERE条件
我在上面的组合条件中假设了班级为必填,如果所有条件都可以选填的话,当用户不输入任何条件时,会造成sql语句中包含一个空的WHERE条件。mybatis提供了WHERE关键字,当所有的where查询参数都为空时,将自动去掉where部分,而不造成语法错误。
修改后,sql映射文件中的<select>
部分将变为
<select id="searchStudents" resultMap="Student2Result" parameterType="hashmap"> SELECT * FROM STUDENTS2 <where> <if test="className != null"> CLASS=#{className} </if> <if test="name != null"> AND NAME LIKE #{name} </if> <if test="gender != null"> AND GENDER = #{gender} </if> </where></select>
当然,这种方式比较优雅,我还有比较偷懒的方式,就是:
<select id="searchStudents" resultMap="Student2Result" parameterType="hashmap"> SELECT * FROM STUDENTS2 WHERE 1=1 <if test="className != null"> AND CLASS=#{className} </if> <if test="name != null"> AND NAME LIKE #{name} </if> <if test="gender != null"> AND GENDER = #{gender} </if></select>
foreach循环
如果sql语句包含in
子句,并且这个参数是动态的,可以使用foreach来实现。来看两段示例代码体会一下
<select id="searchCoursesByTutors" parameterType="map" resultMap="CourseResult"> SELECT * FROM COURSES <if test="tutorIds != null"> <where> <foreach item="tutorId" collection="tutorIds"> OR tutor_id=#{tutorId} </foreach> </where> </if></select>
tutorIds是map参数中的一个元素,foreach会动态地生成sql。还有下面这个例子
<select id="searchCoursesByTutors" parameterType="map" resultMap="CourseResult"> SELECT * FROM COURSES <if test="tutorIds != null"> <where> tutor_id IN <foreach item="tutorId" collection="tutorIds" open="(" separator="," close=")"> #{tutorId} </foreach> </where> </if></select>
set条件
写update语句时,有时会传递过来一个对象和map,我们希望将对象中不为null的属性写入set子句中,通过set可以实现。
<update id="updateStudent" parameterType="Student"> update students <set> <if test="name != null">name=#{name},</if> <if test="email != null">email=#{email},</if> <if test="phone != null">phone=#{phone},</if> </set> where stud_id=#{id}</update>
如果读者发现foreach和set部分的示例代码中属性的名字跟最初的建的表的列名不一致,我想告诉你,不要在意这些细节!如果你能通过这篇博客学会mybatis中的动态sql的语法,我的目的就达到了!快跑!
- mybatis动态SQL语句
- MyBatis动态SQL
- MyBatis 动态SQL
- Mybatis 动态SQL
- MyBatis动态SQL
- MyBatis动态SQL完整版
- mybatis动态sql
- mybatis动态SQL语句
- mybatis动态SQL语句
- MyBatis的动态SQL
- MyBatis动态SQL
- MyBatis动态SQL
- MyBatis 动态SQL语句
- MyBatis动态SQL
- Mybatis组建动态SQL
- MyBatis 动态sql
- mybatis 动态SQL语句
- MyBatis动态SQL详解
- Android多点触摸交互处理-图片缩放
- python基础教程共60课-第13课字符串
- JVM最多能创建多少个线程: unable to create new native thread
- LeetCode(224) Basic Calculator
- 搭建maven+springmvc+mybatis
- MyBatis 动态SQL
- 时间都去哪儿了—兄弟连IT教育
- 使用Xshell调用linux的图形界面!
- OpenGL ES 入门 (一)
- Swift method的internalname和externalname
- 常用vi编辑器命令行
- 【Qt中的定时器】
- GTK+重拾--04 菜单栏使用
- VS2013定义了重复的 system.web.extensions/scripting/scriptResourceHandler