根据不同的条件生成不同的sql语句,本质还是sql语句,只是我们可以在sql层面执行逻辑代码
环境搭建
blog表
id
title
author
creat_time
views
实体类:Blog
配置文件
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.hmx.mapper.BlogMapper"/>
</mappers>
</configuration>
if
这条语句提供了可选的查找文本功能
传入哪个就按哪个查找,如果不传入,就按select里的原始sql语句查找
测试
接口类
public interface BlogMapper {
List<Blog> queryBlogIf(Map map);
}
接口类的实现类
<mapper namespace="com.hmx.mapper.BlogMapper">
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from blog
<!--
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句
而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
-->
<where>
<!--
test里面是判断条件
表达式为true,把if中的语句拼接到select中的sql上
表达式为false,忽略此语句
-->
<if test="title != null">
and title = #{title}
</if>
<if test="author !=null" >
and author = #{author}
</if>
</where>
</select>
</mapper>
测试实现
public static void queryBlogIf() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
//查询title为"Mybatis如此简单"的记录
map.put("title", "Mybatis如此简单");
//查询author为"Andy"的记录
//map.put("author","Andy");
List<Blog> blogs = blogMapper.queryBlogIf(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
choose,when,otherwise
从多个条件中选择一个使用
传入了哪个就按哪个查找,第一个when优先级最高,都没有传入,就按otherwise里的查找
测试
接口类
public interface BlogMapper {
List<Blog> queryBlogChoose(Map map);
}
接口的实现类
<mapper namespace="com.hmx.mapper.BlogMapper">
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author !=null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
</mapper>
测试实现
public static void queryBlogChoose() { SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); HashMap hashMap = new HashMap(); hashMap.put("title", "Mybatis如此简单"); //hashMap.put("author","洪梦霞"); //hashMap.put("views","888"); List<Blog> blogs = blogMapper.queryBlogChoose(hashMap); for (Blog blog : blogs) { System.out.println(blog); } sqlSession.close(); }
trim,where,set
where
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句,
而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
加入trim定制where元素的功能
<!--拼接sql语句时会加上WHERE,并且删除多余的AND和OR--> <trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
set
set 元素可以用于动态包含需要更新的列,忽略其它不更新的列,它会动态地在行首插入 SET 关键字,并会删掉额外的逗号,在update语句中会用到
加入trim定制set元素的功能
<!--拼接sql语句时会加上SET,并且删除多余的","--> <trim prefix="SET" suffixOverrides=","> ... </trim>
foreach
对集合进行遍历(尤其是在构建 IN 条件语句的时候)
测试:select * from blog where 1 = 1 and (id = 1 or id = 2 or id = 3)
接口类
public interface BlogMapper { List<Blog> queryBlogForEach(Map map); }
接口的实现类
<mapper namespace="com.hmx.mapper.BlogMapper"> <select id="queryBlogForEach" parameterType="map" resultType="Blog"> select * from blog <where> <!-- 从collection这个集合中遍历,是map中存在的集合 遍历出的每一项叫做item中的值 index为下标 开始为open里的值 结束为close里的值 separator为分隔符 --> <foreach collection="ids" item="id" open="and (" close=")" separator="or"> id = #{id} </foreach> </where> </select> </mapper>
测试
public static void queryBlogForEach() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
map.put("ids", ids);
List<Blog> blogs = blogMapper.queryBlogForEach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
sql片段
将一些公共的功能抽取出来,方便复用
注意:
最好基于单表来定义SQL片段
不要存在where标签
使用步骤
1、使用sql标签抽取公共的部分
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author !=null" >
and author = #{author}
</if>
</sql>
2、include标签引用
<include refid="if-title-author"></include>