MyBatis 实现动态 SQL

这篇具有很好参考价值的文章主要介绍了MyBatis 实现动态 SQL。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 MyBatis 中的动态 SQL 就是SQL语句可以根据不同的情况情况来拼接不同的sql。

本文会介绍 xml注解 两种方式的动态SQL实现方式。

XML的实现方式

先创建一个数据表,SQL代码如下:

DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo`  (
  `id` int(11) NULL DEFAULT NULL,
  `username` varchar(127) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `gender` tinyint(4) NULL DEFAULT NULL COMMENT '1-男 2-⼥ ',
  `delete_flag` tinyint(4) NULL DEFAULT 0 COMMENT '0-正常, 1-删除',
  `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

数据库表和JAVA对象的对应如下:

 MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

平时在注册账号时会有一些非必填项,而我们就可以使用 <if> 标签来跟据条件进行动态的SQL语句的添加。

接口定义:

@Mapper
public interface Userinfo {
    Integer addUserinfo(User user);
}

<if>标签

语法:

<if test = "条件"> 语句块 </if>

如果 test 后面的条件判断结果为 true,那么就将后面的语句块拼接到最终的 SQL 语句中。

XML的实现代码如下:

<insert id="addUserinfo">
    insert into userinfo(id, username,
                <if test="gender != null">
                    gender,
                </if>
                <if test="deleteFlag != null">
                    delete_flag
                </if>
    ) values (
                #{id},#{username},
                <if test="gender != null">
                  #{gender},
                </if>
                <if test="deleteFlag != null">
                    #{deleteFlag}
                </if>
    );
</insert>

注意:test中的gender和deleteFlag,是传入对象中的属性,不是数据库字段。

执行以下测试代码:

@Test
void addUserinfo() {
    User user = new User();
    user.setId(2);
    user.setUsername("zhangsan");
    user.setDeleteFlag(0);
    //此时gender为空
    userinfo.addUserinfo(user);
}

运行之后我们从日志中可以看出最终执行的SQL语句中并没有 gender

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

而当我们令gender不为空:

user.setGender(1);

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

但是此时我们的代码还有一个隐藏BUG,比如当deleteFlag为空时:

@Test
void addUserinfo() {
    User user = new User();
    user.setId(2);
    user.setUsername("zhangsan");
    //user.setDeleteFlag(0);
    user.setGender(1);
    //此时deleteFlag为空
    userinfo.addUserinfo(user);
}

此时代码报错了,我们可以从MyBatis打印的日志中看出SQL语句出现了多余的逗号。

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

此时就需要使用<trim>标签

<trim>标签

<trim>标签中有如下属性:

  • prefix:表示在整个语句块起始位置加上prefix的值作为前缀
  • suffix:表示在整个语句块结尾加上suffix的值作为后缀
  • prefixOverrides:如果整个语句块的前缀等于prefixOverrides的值,去掉prefixOverrides的值;
  • suffixOverrides:如果整个语句块的后缀等于suffixOverrides的值,去掉suffixOverrides的值。

我们利用<trim>标签来将上述SQL中结尾的 ‘,’ 去除

<insert id="addUserinfo">
    insert into userinfo 
    <trim prefix="(" suffix=")" suffixOverrides=",">
        id, username,
        <if test="gender != null">
            gender,
        </if>
        <if test="deleteFlag != null">
            delete_flag
        </if>
    </trim>
    values
    <trim prefix="(" suffix=");" suffixOverrides=",">    
        #{id},#{username},
        <if test="gender != null">
          #{gender},
        </if>
        <if test="deleteFlag != null">
            #{deleteFlag}
        </if>
    </trim>
</insert>

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

此时程序就可以正常执行了。

<where>标签

<where>标签一般应用于需要动态组装where条件的地方。

<where> 只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或
OR。

例如:我们此时根据 id 和 gender 来查找数据。

数据库中的数据如下:

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

接口定义:

User selectUser(Integer id, Integer gender);

xml实现:

<select id="selectUser" resultType="com.example.Spring_demo.mySQL.User">
    select * from userinfo
    <where>
        <if test="id != null">
            id=#{id}
        </if>
    
        <if test="gender != null">
            and gender=#{gender}
        </if>

    </where>
    ;
</select>

JAVA测试代码

@Test
void selectUser() {
    System.out.println(userinfo.selectUser(1, 1));
}

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

从打印的结果和日志中我们可以看出结果正确。

如果 id 和 gender 都为 null

@Test
void selectUser() {
    System.out.println(userinfo.selectUser(null, null));
}

虽然程序报错了,可是并不是因为SQL错了而是因为接收的参数报错。

此时可以看出 where 被去掉了。 

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

此时如果 gender 为空

@Test
void selectUser() {
    System.out.println(userinfo.selectUser(1, null));
}

<where>标签并不能去除句末的 and 

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

<set>标签

<set>标签用于动态更新数据

用于 update 语句中动态的在SQL语句中插入 set 关键字,并会删掉额外的逗号。

例如:根据传入的id属性,修改 username 和 gender 中不为null的属性。

接口定义:

Integer upData(Integer id, String username, Integer gender);

xml代码实现:

<update id="upData">
    update userinfo  
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="gender != null">
            gender = #{gender}
        </if>
    </set>
    where id = #{id};
</update>

JAVA测试代码

void upData() {
    //gender为空
    userinfo.upData(2, "xiaohong", null);
}

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库
可以看出删掉了额外的逗号(前后都会删掉)。

<foreach>标签

该标签可以在对集合进行遍历时使用。

标签有如下属性:

  • collection:绑定方法参数中的集合,如List,Set,Map或数组对象;
  • item:遍历时对象中的每个元素;
  • open:语句块开头的字符串;
  • close:语句块结束的字符串;
  • separator:每次遍历之间间隔的字符串。

例如:批量删除数据

接口定义:

Integer deleteUsers(List<Integer> ids);

xml代码实现:

<delete id="deleteUsers">
    delete from userinfo where id in
    <foreach collection="ids" item="id" open="(" close=");" separator=",">
        #{id}
    </foreach>
</delete>

注意:这两个地方的名称必须相同。

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

JAVA测试代码

@Test
void deleteUsers() {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    userinfo.deleteUsers(list);
}

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

<include>和<SQL>标签

这两个标签配合使用可以实现对重复的代码片段进行抽取,将其通过 <sql> 标签封装到一个SQL片段,然后再通过<include> 标签进行引用。用来降低代码的冗余度。

  • <sql> :定义可重用的SQL片段
  • <include> :通过属性refid,指定包含的SQL片段

例如:我们可以抽取下面xml中的部分代码。

<delete id="deleteUsers">
    delete from userinfo where id in
    <foreach collection="ids" item="id" open="(" close=");" separator=",">
        #{id}
    </foreach>
</delete>
<sql id="aaa">
    delete from userinfo where id in
</sql>

<delete id="deleteUsers">
    <include refid="aaa"></include>
    <foreach collection="ids" item="id" open="(" close=");" separator=",">
        #{id}
    </foreach>
</delete>

 JAVA测试代码

@Test
void deleteUsers() {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    userinfo.deleteUsers(list);
}

MyBatis 实现动态 SQL,java,spring,mybatis,mvc,sql,数据库

@注解的实现方式

注解的实现其实非常简单只需把xml标签中的SQL(包括标签),使用<script></script> 标签括起来就可以了。

例如下面的xml代码

<insert id="insertUserByCondition">
INSERT INTO userinfo (
username,
`password`,
age,
<if test="gender != null">
gender,
</if>
phone)
VALUES (
#{username},
#{age},
<if test="gender != null">
#{gender},
</if>
#{phone})
</insert>

注解的实现方法:文章来源地址https://www.toymoban.com/news/detail-827162.html

@Insert("<script>" +
    "INSERT INTO userinfo (username,`password`,age," +
    "<if test='gender!=null'>gender,</if>" +
    "phone)" +
    "VALUES(#{username},#{age}," +
    "<if test='gender!=null'>#{gender},</if>" +
    "#{phone})"+
    "</script>")
Integer insertUserByCondition(UserInfo userInfo);

到了这里,关于MyBatis 实现动态 SQL的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring 篇】深入探讨MyBatis映射文件中的动态SQL

    MyBatis,这个名字在Java开发者的世界中犹如一道光芒,照亮着持久层操作的道路。而在MyBatis的映射文件中,动态SQL则是一个让人爱-hate的存在。有时候,你感叹它的灵活性,有时候,你可能会为它的繁琐而头痛。但别担心,我们将在本文中一起揭开动态SQL的神秘面纱,带你领

    2024年01月24日
    浏览(59)
  • MyBatis 实现动态 SQL

     MyBatis 中的动态 SQL 就是 SQL语句可以根据不同的情况情况来拼接不同的sql。 本文会介绍 xml 和 注解 两种方式的动态SQL实现方式。 先创建一个数据表,SQL代码如下: 数据库表和JAVA对象的对应如下:   平时在注册账号时会有一些非必填项,而我们就可以使用 if 标签来跟据条

    2024年02月19日
    浏览(48)
  • 【Spring Boot+Thymeleaf+MyBatis+mysql】实现电子商务平台实战(附源码)持续更新~~ 包括sql语句、java、html代码

    源码请点赞关注收藏后评论区留言和私信博主 开发环境:Web服务器使用Servlet容器,数据库采用mysql,集成开发环境为Spring Tool Suite(STS) 电子商务平台分为两个子系统 一个是后台管理系统 一个是电子商务系统,下面分别讲解着两个子系统的功能需要与模块划分 1:后台管理子

    2024年02月09日
    浏览(46)
  • (第六天)初识Spring框架-SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

    ​ 昨天我们已经把Mybatis框架的基本知识全部学完,内容有Mybatis是一个半自动化的持久层ORM框架,深入学习编写动态SQL,Mybatis的关联映射,一对一、一对多、多对多、Mybatis的缓存机制,一二级缓存的开启和设置,缓存命中率、如何使用idea链接数据库自动生成pojo类等。我们学

    2024年02月10日
    浏览(67)
  • Spring Boot:实现MyBatis动态创建表

    在有些应用场景中,我们会有需要动态创建和操作表的需求。 比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等。这个时候就需要我们动态的生成和操作数据库表了。 而我们都知道,以往我们使用MyBatis是需要提前生成包括

    2024年02月04日
    浏览(42)
  • MyBatis注解开发---实现增删查改和动态SQL

    目录 相关导读 1. 环境搭建 (1)创建持久层接口,并在接口方法上定义Sql语句  

    2023年04月18日
    浏览(45)
  • (第十一天)初识SpringMVC SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

    今天我们要来学习一下SSM框架的最后一个框架SpringMVC 一、初认SpringMVC 基本概念: ​ Spring MVC(Model-View-Controller)是一个用于构建Java Web应用程序的开源框架,它提供了一种基于MVC架构的方式来开发Web应用 。 ​ SpringMVC是Spring Framework的一部分,它是一种基于模型-视图-控制器(

    2024年02月07日
    浏览(72)
  • Spring、Spring-MVC、Mybatis、Mybatis-generator整合核心配置文件记录

    Spring、Spring-MVC、Mybatis、Mybatis-generator整合核心配置xml文件记录 spring-mybatis.xml

    2024年01月22日
    浏览(56)
  • Spring和Spring MVC和MyBatis面试题

    面试题1:请简述Spring、Spring MVC和MyBatis在整合开发中的作用? 答案: Spring :是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。它提供了强大的依赖注入功能,简化了企业级应用的开发。在整合开发中,Spring负责处理业务逻辑、事务管理、安全控制等。 Spring M

    2024年04月16日
    浏览(42)
  • MyBatis案例 | 使用映射配置文件实现CRUD操作——动态SQL优化条件查询

    本专栏主要是记录学习完JavaSE后学习JavaWeb部分的一些知识点总结以及遇到的一些问题等,如果刚开始学习Java的小伙伴可以点击下方连接查看专栏 本专栏地址:🔥JavaWeb Java入门篇: 🔥Java基础学习篇 Java进阶学习篇(持续更新中):🔑Java进阶学习篇 本系列文章会将讲述有关

    2024年02月02日
    浏览(87)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包