动态sql

动态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 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

动态sql

也就是说 如果直插入title属性,因为后面有逗号所以set会帮你去除。

trim

动态sql

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>

动态sql

测试:

@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。

上一篇:git记录查询


下一篇:IEEE 论文的参考文献格式(bib、latex)