MyBatis:动态sql语句

简介: MyBatis:动态sql语句

1. 动态sql语句


1.1 动态sql语句概述


Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。


参考的官方文档,描述如下:



官网地址:https://mybatis.org/mybatis-3/zh/dynamic-sql.html


1.2 动态 SQL之 if标签


我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。


如下图:


<select id="findByCondition" parameterType="student" resultType="student">
    select * from student
    <where>
        <if test="id!=0">
            and id=#{id}
        </if>
        <if test="username!=null">
            and username=#{username}
        </if>
    </where>
</select>


当查询条件id和username都存在时,控制台打印的sql语句如下:


 //获得MyBatis框架生成的StudentMapper接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student condition = new Student();
condition.setId(1);
condition.setUsername("lucy");
Student student = mapper.findByCondition(condition);



当查询条件只有id存在时,控制台打印的sql语句如下:


//获得MyBatis框架生成的UserMapper接口的实现类
StudentMapper mapper = sqlSession.getMapper( StudentMapper.class);
Student condition = new Student();
condition.setId(1);
Student student = mapper.findByCondition(condition);



总结语法:


<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
  <if>:条件判断标签。
  <if test=“条件判断”>
    查询条件拼接
  </if>
</where>


1.3 动态 SQL之 foreach标签


循环执行sql的拼接操作,例如:SELECT * FROM student WHERE id IN (1,2,5)。


<select id="findByIds" parameterType="list" resultType="student">
    select * from student
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>


测试代码片段如下:


//获得MyBatis框架生成的UserMapper接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
int[] ids = new int[]{2,5};
List<Student> sList = mapper.findByIds(ids);
System.out.println(sList);


总结语法:


<foreach>:循环遍历标签。适用于多个参数或者的关系。
<foreach collection=“”open=“”close=“”item=“”separator=“”>
获取参数
</foreach>


参数说明


image.png


1.4 SQL片段抽取 sql标签


Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的


<!--抽取sql片段简化编写-->
<sql id="selectStudent" >SELECT * FROM student</sql>
<select id="findById" parameterType="int" resultType="student">
    <include refid="selectStudent"></include> where id=#{id}
</select>
<select id="findByIds" parameterType="list" resultType="student">
    <include refid="selectStudent"></include>
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>


总结语法:


我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。


<sql>:抽取 SQL 语句标签。 
<include>:引入 SQL 片段标签。 
<sql id=“片段唯一标识”>抽取的 SQL 语句</sql> <include refid=“片段唯一标识”/>


1.5 动态sql之 choose标签


<select id="selectConditionWhen" resultType="student" parameterType="student">
    <include refid="select"/>
    <where>
        <choose>
            <when test="id != null">
                id = #{id}
            </when>
            <when test="name != null">
                AND name = #{name}
            </when>
            <when test="age != null">
                AND age = #{age}
            </when>
            <otherwise></otherwise>
        </choose>
    </where>
</select>


测试代码如下:


InputStream inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student stu =new Student();
stu.setId(2);
List<Student> list = mapper.selectCondition(stu);
for (Student student : list) {
    System.out.println(student);
}
sqlSession.close();
inputStream.close();


choose会实现如下功能:


  1. 多个 when 标签中,只能执行一个。也就是说:当一个 when 条件满足并执行后,其它的 when 将不再执行。


  1. 当所有 when 都不满足条件时,执行 otherwise 标签。


if 与 choose 的区别:if 相当于java中的if语句; choose相当于java中的switch语句。


1.6 trim标签


trim标签可以在自己包含的内容中加上某些前缀或后缀,与之对应的属性是:prefix、suffix。 还可以把包含内容的开始内容覆盖,即忽略。也可以把结束的某些内容覆盖,对应的属性是:prefixOverrides、suffixOverrides


<insert id="insertTrim" parameterType="student">
    insert into student
    <trim prefix="values(" suffix=")" suffixOverrides=",">
        <if test="id!=null and id!=''">
            id,
        </if>
        <if test="name!=null and name!=''">
            name,
        </if>
        <if test="age!=null and age!=''">
            age,
        </if>
    </trim>
</insert>


@Test
public void InsertTrim() throws Exception {
    InputStream inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student stu = new Student();
    stu.setId(2);
    stu.setName("taoge");
    stu.setAge(18);
    int num = mapper.insertTrim(stu);
    sqlSession.close();
    inputStream.close();
}



注意:


  1. prefix与suffix可以在sql语句中拼接出一对小括号。


  1. suffixOberrides可以将最后一个逗号去掉。


2. 项目链接


https://download.csdn.net/download/weixin_45525272/85883118

相关文章
|
4月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
326 18
|
9月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
8月前
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
1160 0
|
4月前
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
92 0
|
7月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
727 5
|
9月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
9月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
9月前
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
285 0
|
6月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
1216 1
Spring boot 使用mybatis generator 自动生成代码插件
|
9月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
777 0