动态sql
文章目录
动态sql是?有什么用?怎么用?
能够帮你解决拼串的麻烦
具体
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
搭建环境
1.创建数据库表
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2.创建module 、配置maven
3.新建实体类
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
4.建立Mapper接口及Mapper.xml文件 并在mabatis文件中配置Mapper
5.在mybatis中setting一个驼峰转化
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
6.创建一个获取id的工具类
public class IDUtils {
public static String getId(){
String s = UUID.randomUUID().toString().replaceAll("-", ".");
return s;
}
}
编写代码
接口方法
int addBlog(Blog blog);
Mapper配置方法
<insert id="addBlog" parameterType="com.underdog.pojo.Blog">
insert into blog values (#{id},#{title},#{author},#{createTime},#{views})
</insert>
测试
@Test
public void test1(){
String id = IDUtils.getId();
SqlSession sqlsession = MybatisUtils.getSqlsession();
BlogMapper mapper = sqlsession.getMapper(BlogMapper.class);
Date date = new Date();
int i = mapper.addBlog(new Blog(id, "我是谁", "比尔盖茨", date, 1111));
System.out.println(i);
sqlsession.close();
}
记得关连接。
if
需求
根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
select * from blog where title =#{title} and author=#{author}
缺点:使用上面的这个,当缺少某个参数时就查不到了
<select id="queryBlogIf" parameterType="map" resultType="com.underdog.pojo.Blog">
select * from blog where
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author=#{author}
</if>
</select>
使用这个,当确实某个参数时,仍能够查出来。
用法:
- if标签中的test是限制条件
choose、when、otherwise
<select id="queryBlogChoose" parameterType="map" resultType="com.underdog.pojo.Blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author =#{author}
</when>
</choose>
</where>
</select>
相当于switch case ,当条件满足是进入(选择一个,优先从上而下)
trim、where、set
where标签
<select id="queryBlogChoose" parameterType="map" resultType="com.underdog.pojo.Blog">
select * from blog where
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author =#{author}
</when>
</choose>
</select>
如果只输入author进行查询的话
语句变成了:select * from blog where and author =? ,报错
所以引出where
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u6FfLBX0-1615641961951)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210313181646534.png)]
官方的这句话,大概为如果开头的句有and,自动去掉。
where改后
<select id="queryBlogChoose" parameterType="map" resultType="com.underdog.pojo.Blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author =#{author}
</when>
</choose>
</where>
</select>
同样进行测试:只插入作者着参数,仍可以搜索到。
set
<update id="updateBlog" parameterType="map">
update blog set title = #{title} ,author=#{author} where id =#{id}
</update>
当插入只插入author是就会出错。
使用set标签
<update id="updateBlog" parameterType="map">
update blog
<set >
<if test="title != null">
title = #{title},
</if>
<if test="author !=null">
author = #{author},
</if>
</set>
<where>
id =#{id}
</where>
</update>
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
也就是说 如果直插入title属性,因为后面有逗号所以set会帮你去除。
trim
SQL片段
<sql id="title-author" >
<if test="title != null">
title = #{title},
</if>
<if test="author !=null">
author = #{author},
</if>
</sql>
<update id="updateBlog" parameterType="map">
update blog
<set >
<include refid="title-author"></include>
</set>
<where>
id =#{id}
</where>
</update>
通过sql标签进行把公共部分归类在一起然后通过include标签进行引用,有点像javaScript的引用外部文件一样。方便简化
sql片段中不要含有where
- 最好基于单表实现,提高重用性。
forEach
接口方法;
List<Blog> queryBlogForeach(Map map);
xml配置
<select id="queryBlogForeach" parameterType="map" resultType="com.underdog.pojo.Blog">
select * from blog
<where>
<foreach collection="ids" close=")" item="id" separator="or" open="and (">
id=#{id}
</foreach>
</where>
</select>
测试:
@Test
public void test3(){
SqlSession sqlsession = MybatisUtils.getSqlsession();
BlogMapper mapper = sqlsession.getMapper(BlogMapper.class);
Map map = new HashMap();
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
map.put("ids",list);
List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs){
System.out.println(blog);
}
总结
动态sql本质上还是sql。