欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mybatis---动态SQL(拼接sql语句根据不同的条件生成不同的SQL语句进行复杂查询)

程序员文章站 2024-03-02 12:56:46
...

1.动态SQL

1.1 什么是动态SQL

动态SQL就是指根据不同的条件生成不同的SQL语句

1.2 环境搭建

1.数据库表

-- auto-generated definition
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 '浏览量'
);

2.导包

<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
    </dependencies>

3.编写核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入外部配置文件-->
    <properties resource="db.properties"/>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--开启自动驼峰规则-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <package name="edu/xalead/pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="edu.xalead.dao.BlogMapper"/>
    </mappers>
</configuration>

4. 编写实体类

package edu.xalead.pojo;

import lombok.Data;

import java.util.Date;

@Data
public class Blog {
    private String id;
    private  String title;
    private String author;
    private Date createTime;//属性名与字段名不一致(从_到驼峰)
    private int views;
}

5.编写实体类对应Mapper接口和Mapper.xml

6.添加一个工具类

  • 在com.it.utils中加入IDUtils类,作为可以生成随机id的类,代码:

    package edu.xalead.utils;
    import org.junit.jupiter.api.Test;
    import java.util.UUID;
    public class IDUtils {
        public static String getID(){
            return UUID.randomUUID().toString().replaceAll("-","...");
        }
        @Test
        public void test(){
            System.out.println(IDUtils.getID());
        }
    }
    
  • mapUnderscoreToCamelCase 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。
    代码:

12.3开始改造

1.IF

接口代码:

//查询博客
List<Blog> queryBlogIf(Map map);
  • 接口.xml代码:(在这里1=1为了sql正常后面会使用where标签)

    <select id="queryBlogIf" parameterType="map" resultType="blog">
            select * from mybatis_test.blog where 1=1
                <if test="title !=null">
                    and title = #{title}
                </if>
                <if test="author != null">
                    and author = #{author}
                </if>
        </select>
    
  • 测试代码:

     @Test
        public void test1(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
            Map map = new HashMap();
    //        map.put("title","vue");
            map.put("author","admin");
            List<Blog> blogs = mapper.queryBlogIf(map);
            for (Blog blog : blogs) {
                System.out.println(blog);
            }
            sqlSession.close();
        }
    

2.trim(where , set)

where :保证sql可以正常输出

<select id="queryBlogIf" parameterType="map" resultType="blog">
    select * from mybatis_test.blog
    <where>
        <if test="title !=null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </where>
</select>

set: update 中

<update id="updateBlog" parameterType="map">
    update mybatis_test.blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </set>
    where id = #{id};
</update>

trim :可以定制where,set的功能

3.choose(when,otherwise)

相当于switch-case

 <select id="queryBlogChoose" parameterType="map" resultType="blog">
        select * from mybatis_test.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>

总结:所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码

1.4 SQL片段(把sql提取出来)

有时候,我们可能会将一些工共的部分抽取出来,方便复用

  • 接口.xml代码:

     <sql id="if-title-author">
         <!--提取sql片段-->
            <if test="title !=null">
                and title = #{title}
            </if>
            <if test="author != null">
                and author = #{author}
            </if>
        </sql>
        
        <select id="queryBlogIf" parameterType="map" resultType="blog">
            select * from mybatis_test.blog
            <where>
                <!--引入sql片段-->
                <include refid="if-title-author"/>
            </where>
        </select>
    

注意事项:

  • 最好基于单表定义sql片段
  • 不要存在where标签

1.5 Foreach

处理大概这类问题

select * from user where 1=1 and (id=0 or id=2 or id=3)

查询id集合对应blog

接口.xml代码:

<!--查询where 1=1 and (id=0 or id=2 or id=3)用foreach-->
<!--类似集合的foreach循环。foreach标签内容分别为:给定一个集合的名字,将取出的内容给定一个名字,开始是的样子(,结尾的样子),分开分隔是or。id和#{id}对应-->
 <select id="queryBlogForeach" parameterType="map" resultType="blog">
        select * from mybatis_test.blog
        <where>
            <foreach collection="ids" item="id" open="(" close=")" separator="or">
                id = #{id}
            </foreach>
        </where>
    </select>
  • 测试代码:

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

动态Sql就是在拼接sql语句,我们只要保证sql的正确性,按照Sql的格式,去排列组合就可以了

欢迎访问我的个人博客:http://www.ayjup.cn

相关标签: mybatis sql