MyBatis学习笔记(六)动态sql
2015-08-31 19:59
591 查看
在一些情况下,如查询参数不确定时,需要用到动态sql
例子,根据动态输入的查询条件查询student.
一.if语句
1.StudentTMapper
map参数是查询条件
2.StudentTMappler.xml
3.测试
二.choose,when ,otherwise
自己的例子:
三.trim, where, set元素
1.当没有条件时,有可能会生成这样的sql
如果不在后边加入 1=1,则应该加上where标签
2.还有这种情况
同样,update set语句也会出现多余的","的问题
也可以使用trim修改
这是一个非常有用的动态sql元素,用来遍历集合,常应用于IN语句中,例:
foreach元素非常强大,它允许你指定一个集合,声明item和index变量,在元素内部使用.生成有"开始/结尾/分隔符"的字符串,这个元素非常智能,它不会不小心添加额外的分隔符.
记住,你可以把一个List实例或者一个数组当作参数传递到MyBatis.当你这样做了,MyBatis会自动放到一个Map里.List实例会以"list"作为Key值,数组实例会以"array"作为Key值.
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名.
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置.
open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符.
close表示以什么结束.
上面的例子生成的sql相当于
SELECT *
FROM POST P
WHERE ID in (?,?,?)
例子,根据动态输入的查询条件查询student.
一.if语句
1.StudentTMapper
package com.skymr.mybatis.mappers; import java.util.List; import java.util.Map; import com.skymr.mybatis.model.Student; public interface StudentTMapper { public List<Student> searchStudents(Map<String,Object> map); }
map参数是查询条件
2.StudentTMappler.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:Mapper映射 --> <!-- 这个文件感觉就像StudentMapper接口的实现一样,只是从java文件变成了xml文件 充当了Dao类的功能 --> <mapper namespace="com.skymr.mybatis.mappers.StudentTMapper"> <resultMap type="Student" id="stuMap"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <association property="address" column="address_id" select="com.skymr.mybatis.mappers.AddressMapper.getAddress"> </association> <association property="grade" column="grade_id" select="com.skymr.mybatis.mappers.GradeMapper.getGrade"></association> </resultMap> <select id="searchStudents" resultMap="stuMap" parameterType="map"> select * from mybatis_student where 1=1 <if test="name!=null"> and name like #{name} </if> <if test="age!=null"> and age=#{age} </if> </select> </mapper>
3.测试
package com.skymr.mybatis.service; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.session.SqlSession; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.skymr.mybatis.mappers.StudentTMapper; import com.skymr.mybatis.model.Student; import com.skymr.mybatis.util.MybatisUtil; public class StudentTest4 { private Logger logger = LoggerFactory.getLogger(StudentTest4.class); private SqlSession session; @Before public void beforeTest(){ session = MybatisUtil.openSession(); } @After public void afterTest(){ session.close(); } @Test public void testSearch(){ logger.info("测试查询学生"); StudentTMapper mapper = session.getMapper(StudentTMapper.class); Map<String,Object> map = new HashMap<String, Object>(); map.put("name", "%aaa%"); map.put("age", 111); List<Student> list = mapper.searchStudents(map); logger.info(list.toString()); } }
二.choose,when ,otherwise
Sometimes we don’t want all of the conditionals to apply, instead we want to choose only one case among many options. Similar to a switch statement in Java, MyBatis offers a choose element. Let’s use the example above, but now let’s search only on title if one is provided, then only by author if one is provided. If neither is provided, let’s only return featured blogs (perhaps a strategically list selected by administrators, instead of returning a huge meaningless list of random blogs).有些时候我们不想所有的条件都使用到,只想在所有条件中选择一个条件.与java的switch语种相似,Mybatis提供了一个元素.让我们做个例子.
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>上面的例子是引用Mybatis文档.
自己的例子:
<select id="searchStudents2" resultMap="stuMap" parameterType="map"> select * from mybatis_student where 1=1 <choose> <when test="searchBy=='name'"> and name like #{name} </when> <when test="searchBy=='gradeId'"> and grade_id=#{gradeId} </when> <otherwise> and age=#{age} </otherwise> </choose> </select>
三.trim, where, set元素
1.当没有条件时,有可能会生成这样的sql
SELECT * FROM BLOG WHERE
如果不在后边加入 1=1,则应该加上where标签
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <if test="state != null"> state = #{state} </if> </where> </select>改成这样就可以避免以上情况.
2.还有这种情况
SELECT * FROM BLOG WHERE需要去年多余的and /or
AND title like ‘someTitle’
<select id="searchStudents3" resultMap="stuMap" parameterType="map"> select * from mybatis_student <trim prefix="WHERE" prefixOverrides="AND|OR"> <if test="name!=null"> and name like #{name} </if> <if test="age!=null"> and age=#{age} </if> </trim> </select>
同样,update set语句也会出现多余的","的问题
<update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update>
也可以使用trim修改
<update id="updateAuthorIfNecessary"> update Author <trim prefix="SET" suffixOverrides=","> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </trim> where id=#{id} </update>四.foreach元素
这是一个非常有用的动态sql元素,用来遍历集合,常应用于IN语句中,例:
IN condition. For example: <select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>
foreach元素非常强大,它允许你指定一个集合,声明item和index变量,在元素内部使用.生成有"开始/结尾/分隔符"的字符串,这个元素非常智能,它不会不小心添加额外的分隔符.
记住,你可以把一个List实例或者一个数组当作参数传递到MyBatis.当你这样做了,MyBatis会自动放到一个Map里.List实例会以"list"作为Key值,数组实例会以"array"作为Key值.
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名.
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置.
open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符.
close表示以什么结束.
上面的例子生成的sql相当于
SELECT *
FROM POST P
WHERE ID in (?,?,?)
相关文章推荐
- MySQL存储过程之特征子句
- Kafka->Mongodb->Es
- MongoDB学习十一 --MongoDB的Replication实践
- Powerdesigner15-用jdbc链接MySQL实现逆向工程步骤
- MySQL命令行导入导出数据
- Getting Started with Redis
- mysql 主从配置
- mysql的text字段长度
- 解决mysql出现几个l的问题
- MySQL 架构 - MVCC多版本并发控制
- mysql 赋予远程访问权限
- MySQL取整函数
- Redis 专题二: RDB 与 AOF 持久化
- 全表扫描的COST计算
- mysql查看历史执行的sql
- redis 强制关闭并重启方法
- 通用权限管理设计 之 数据库结构设计
- 从源hbase集群中复制出HBase数据库表到本地目录
- sqlite基本数据类型
- 查看sql语句执行的消耗