动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
建表:
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;
插入数据:
<insert id="addBlog" parameterType="blog"> insert into mybatis.blog(id, title, author, create_time, views) values (#{id},#{title},#{author},#{createTime},#{views}) </insert>
@Test public void addBlog(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); Blog blog = new Blog(); blog.setId(IDutils.getId()); blog.setTitle("Mybatis"); blog.setAuthor("狂神说"); blog.setCreateTime(new Date()); blog.setViews(9999); mapper.addBlog(blog); blog.setId(IDutils.getId()); blog.setTitle("Java"); mapper.addBlog(blog); blog.setId(IDutils.getId()); blog.setTitle("Spring"); mapper.addBlog(blog); blog.setId(IDutils.getId()); blog.setTitle("微服务"); mapper.addBlog(blog); sqlSession.close(); }
<select id="getBlog" parameterType="map" resultType="blog"> select * from mybatis.blog <where> <include refid="title-author"></include> </where> </select> <sql id="title-author"> <if test="title!=null"> title=#{title} </if> <if test="author!=null"> and author=#{author} </if> </sql>
where标签:会智能的添加where,并且去掉and和or
sql标签,就是将一段sql语句封装起来,后面用include标签引用,实现sql的复用。
<select id="getBlog2" parameterType="map" resultType="blog"> select * from mybatis.blog <where> <choose> <when test="title!=null"> title=#{title} </when> <when test="author!=null"> and author=#{author} </when> <otherwise> views=9999 </otherwise> </choose> </where> </select>
类似于java中的switch case,只选择一个,从上往下,如果有满足条件的就加上,只选择一个,如果都不满足就选择otherwise中的内容。
可通过trim自定义标签,实现不同的功能。prefixOverrided前缀覆盖,suffixOverrides后缀覆盖
where的原型:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
set的原型:
<trim prefix="SET" suffixOverrides=","> ... </trim>
set的使用:
<update id="updateBlogById" parameterType="map"> update mybatis.blog <set> <if test="title!=null"> title=#{title}, </if> <if test="author!=null"> author=#{author} </if> </set> where id=#{id} </update>
<!--查询1,2,3号博客用where(or)拼接--> <select id="getBlogs" parameterType="map" resultType="blog"> select * from mybatis.blog <where> <foreach collection="ids" item="id" open="(" separator="or" close=")"> id=#{id} </foreach> </where> </select>
传递来的map里的ids如果为空,则不会加上where标签,用id去遍历ids,开始"(",用","隔开,
结尾为")"。
<!--用where in拼接--> <select id="getBlogs2" parameterType="map" resultType="blog"> select * from mybatis.blog <where> <foreach collection="ids" item="id" open="id in(" separator="," close=")"> #{id} </foreach> </where> </select>