12、mybatis-动态sql

什么是动态SQL:动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

  -------------------------------
  - if
  - choose (when, otherwise)
  - trim (where, set)
  - foreach

创建一个基础工程
1、导包
2、编写配置文件
3、编写实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
    private int id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

4、编写实体类对应的mapper接口和mapper.xml

//插入数据
    int addBook(Blog blog);
<insert id="addBook" parameterType="blog">
        insert into mybatis.blog(id, title, author, create_time, views)
        values (#{id}, #{title}, #{author}, #{createTime}, #{views})
    </insert>

5、测试

@Test
public void addInitBlog() {
    SqlSession session = MybatisUtils.getSqlSession();
    BlogMapper mapper = session.getMapper(BlogMapper.class);

    Blog blog = new Blog();
    blog.setId(IDUtils.getId());
    blog.setTitle("Mybatis如此简单");
    blog.setAuthor("zhy");
    blog.setCreateTime(new Date());
    blog.setViews(9999);

    mapper.addBook(blog);

    blog.setId(IDUtils.getId());
    blog.setTitle("Java如此简单");
    mapper.addBook(blog);

    blog.setId(IDUtils.getId());
    blog.setTitle("Spring如此简单");
    mapper.addBook(blog);

    blog.setId(IDUtils.getId());
    blog.setTitle("微服务如此简单");
    mapper.addBook(blog);

    session.close();
}

if语句

List<Blog> queryBlogIf(Map map);

<select id="queryBlogIf" resultType="blog" parameterType="map">
        select *
        from mybatis.blog
        where 1 = 1
        <if test="title!=null">
            title = #{title}
        </if>
        <if test="author!=null">
            and author = #{author}
        </if>
    </select>
测试
@Test
public void quertBlogIf() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap<>();
    //        map.put("title", "Java如此简单");
    map.put("author", "zhy");
    List<Blog> blogs = mapper.queryBlogIf(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

choose (when, otherwise)
相当于switch…case语句

List<Blog> queryBlogChoose(Map map);
   <select id="queryBlogChoose" resultType="blog" parameterType="map">
        select *
        from mybatis.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>
测试
    @Test
    public void quertBlogChoose() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap<>();
//        map.put("title", "Java如此简单");
        map.put("author", "狂神说");
        map.put("views", 9999);
        List<Blog> blogs = mapper.queryBlogChoose(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

trim (where, set)
where 元素只会在至少有一个子元素的条件返回SQL子句的情况下才去插入WHERE子句。而且,若语句的开头为AND’或OR ',where元素也会将它们去除。
当where标签内的if标签都失效时,会自动去掉where标签

where
select *
    from mybatis.blog
    <where>
        <if test="title!=null">
            and title = #{title}
        </if>
        <if test="author!=null">
            and author = #{author}
        </if>
    </where>

set 去逗号,当if标签内容为空时会去掉set标签产生语法错误
//更新博客

int updateBlog(Map map);
<update id="updateBlog" parameterType="map">
        update mybatis.blog
        <set>
            <if test="title !=null">
                title = #{title},
            </if>
            <if test="author !=null">
                author = #{author}
            </if>
            where id = #{id}
        </set>
    </update>
测试
    @Test
    public void updateBlog() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap<>();
//        map.put("title", "小明自黑");
        map.put("author", "小张");
        map.put("id", "16e3ab6be5d44e58a3898761b6e159c6");
        mapper.updateBlog(map);
        sqlSession.close();
    }

SQL片段
将一些相同功能的代码抽取出来复用
1、使用SQL标签抽取公共的部分

   <!--sql片段-->
    <sql id="if-title-author">
        <if test="title!=null">
            title = #{title}
        </if>
        <if test="author!=null">
            and author = #{author}
        </if>
    </sql>

2、在需要使用的地方使用include标签引用即可

<select id="queryBlogIf" resultType="blog" parameterType="map">
    select *
    from mybatis.blog
    <where>
        <include refid="if-title-author"></include>
    </where>
</select>

3、注意事项
● 最好基于单表定义SQL片段
● SQL片段不要存在where标签
foreach
总结,动态sql本质还是sql语句,只是我们可以在sql层面,去执行逻辑代码
批量新增,批量删除

//查询第1,2,3号记录的博客
    List<Blog> queryBlogByForeach(Map map);
<!--
现在传递一个map  ,给这个map传一个集合
-->
<select id="queryBlogByForeach" parameterType="map" resultType="blog">
  select * from mybatis.blog
  <where>
    <foreach collection="ids" item="id" open="and (" separator="or" close=")">
      id=#{id}
    </foreach>
  </where>
</select>

测试

@Test
public void quertBlogForeach() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap<>();
    List<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(2);
    map.put("ids", ids);
    List<Blog> blogs = mapper.queryBlogByForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,
去排列组合就可以了
● 建议:
○ ·现在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!

● 面试高频
○ Mysql引擎
○ lnnoDB底层原理
○ ·索引
○ 索引优化!

Mybatis-plus是在Mybatis基础上进行封装的一个框架,它简化了平时开发过程中对常用接口的调用,可以省去一些繁琐的操作。然而,对于一些更为复杂的查询,Mybatis-plus可能无法满足需求,此时就需要我们自定义SQL语句来实现。通过在入口类的MybatisSqlSessionFactoryBuilder#build方法中注入mybatis-plus自定义的动态配置xml文件,可以实现自定义SQL语句和动态SQL的功能。具体的实现步骤如下: 1. 在应用启动时,在入口类的MybatisSqlSessionFactoryBuilder#build方法中将mybatis-plus的自定义动态配置xml文件注入到Mybatis中。 2. 在自定义的动态配置xml文件中,可以使用各种Mybatis-plus提供的方法来实现动态SQL的功能,比如IF标签、CHOOSE标签、FOREACH标签等。 3. 在自定义SQL语句中,可以结合Mybatis-plus的Wrapper类来实现条件查询,例如使用LambdaQueryWrapper来构建查询条件。 总结起来,Mybatis-plus提供了简化开发的接口,但对于一些更为复杂的查询,仍然需要我们自定义SQL语句和动态SQL来实现。通过注入自定义的动态配置xml文件,并结合Mybatis-plus提供的方法和Wrapper类,可以实现更加灵活和高效的数据查询。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [mybatis-plus/mybatis 自定义 sql 语句、动态 sql](https://blog.csdn.net/CREATE_17/article/details/109117091)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Mybatis Plus实现动态SQL语句的原理,你知道吗?](https://blog.csdn.net/weixin_38405253/article/details/119880820)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值