动态SQL
基于OGNL表达式
一.实现动态SQL的主要元素
if(条件)
trim(去除关键字)
where(用于简化条件判断)
set(于数据更新时设值)
choose()
foreach(通常用于迭代集合)
创建数据库表并插入数据
CREATE TABLE `t_blog` (
`id` INT (11),
`title` VARCHAR (765),
`content` VARCHAR (765),
`owner` VARCHAR (150)
);
INSERT INTO `t_blog` (`id`, `title`, `content`, `owner`) VALUES('1','java基础','详细描述','唐国强11');
INSERT INTO `t_blog` (`id`, `title`, `content`, `owner`) VALUES('2','中文','中国','ofo11');
INSERT INTO `t_blog` (`id`, `title`, `content`, `owner`) VALUES('3','html','html标签','样式');
INSERT INTO `t_blog` (`id`, `title`, `content`, `owner`) VALUES('6','html','www','eee');
INSERT INTO `t_blog` (`id`, `title`, `content`, `owner`) VALUES('9','中文','111','1111');
if语句
<select id="dynamicIfTest" parameterType="blog" resultType="blog">
SELECT * FROM t_blog WHERE 1=1
<if test="title!=null">
AND title=#{title}
</if>
<if test="content!=null">
AND content=#{content}
</if>
<if test="owner!=null">
AND owner=#{owner}
</if>
</select>
*其中<test ="title!=null">
是判断条件,如果字段titile的值不为null,那么就在WHERE 1=1 后加拼接sql语句AND title=#{title},如果title=null,那么就判断下一个条件<if test="content!=null">
,如果不加WHERE 1=1,那么当条件满足title!=null时,会直接在SELECT * FROM t_blog语句后拼接AND title=#{title},从而造成sql语句语法错误,所以使用if时需注意。
动态sql if测试
public static void main(String[] args) {
SqlSession session = UserMapperUtil.getSqlSession(true);
blog blog = new blog();
blog.setTitle("html");
List<blog> list= session.selectList("mapping.BlogMapper.dynamicIfTest",blog);
System.out.println(list);
}
测试结果
Choose语句
<select id="dynamicIfTest2" parameterType="blog" resultType="blog">
SELECT * FROM t_blog WHERE 1=1
<choose>
<when test="title!=null">
AND title=#{title}
</when>
<when test="content!=null">
AND content=#{content}
</when>
<otherwise >
AND owner="owner1"
</otherwise>
</choose>
</select>
动态sql里choose相当于java 语言中的 switch ,与 jstl 中的choose 很类似,choose中包含when与otherwise,如果<when test="title!=null">
条件成立时,拼接AND title=#{title},与if语句效果一样,不同之处在于choose中,如果title!=null条件不成立,就会判断下一个条件,如果条件成立,拼接AND title=#{title}后不会判断下面的条件,并且如果前面所有条件不成立时拼接otherwise中的sql语句。
动态sqlchoose测试
public static void main(String[] args) {
SqlSession session = UserMapperUtil.getSqlSession(true);
blog blog=new blog();
//blog.setTitle("html");
blog.setContext("中国");
List<blog> list = session.selectList("mapping.BlogMapper.dynamicIfTest2",blog);
System.out.println(list);
}
测试结果
trim语句
<select id="dynamicIfTest3" parameterType="blog" resultType="blog">
SELECT * FROM t_blog
<trim prefix="where" prefixOverrides="and|or">
<if test="title!=null">
title=#{title}
</if>
<if test="content!=null">
AND content=#{content}
</if>
<if test="owner!=null">
OR owner=#{owner}
</if>
</trim>
</select>
trim元素的用处时可以在包含的内容里加上前缀或后缀,prefix和suffix,可以忽略内容的首部或者尾部,prefixOverrides和suffixOverrides,在第一个条件满足时在语句 SELECT * FROM t_blog后加上where,如果第一个条件不成立,之后的条件成立的话,在语句SELECT * FROM t_blog后加上where,并忽略第二个条件成立时语句中的and,不然会出现sql语句语法错误。
WHERE语句
<select id="dynamicIfTest4" parameterType="blog" resultType="blog">
SELECT * FROM t_blog
<where>
<if test="title!=null">
title=#{title}
</if>
<if test="content!=null">
AND content=#{content}
</if>
<if test="owner!=null">
AND owner=#{owner}
</if>
</where>
</select>
where会在语句 SELECT * FROM t_blog自动加上一个where元素,where中可以不用考虑sql语句的空格,在where中Mybaits会智能的加上空格,如果where中所有判断条件不满足时,会查询t_blog里所有数据,如果第一个条件不满足而第二个条件满足时,where会去掉 AND content=#{content}中的AND,WHERE会智能忽略第一个条件满足时sql语句中的and或者or。