Mybatis批量更新对象数据的两种实现方式

 更新时间:2024年08月05日 09:28:02   作者:何中应  
这篇文章主要介绍了Mybatis批量更新对象数据的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

说明:

遇到一次需要批量修改对象的场景。

传递一个对象集合,需要根据对象ID批量修改数据库数据,使用的是MyBatis框架。查了一些资料,总结出两种实现方式。

创建Demo

首先,创建一个简单的Demo;

(User,用户对象)

import lombok.Data;
import java.io.Serializable;

@Data
public class User implements Serializable {
    
    private String id;

    private String username;

    private String password;
}

(UserController,用户控制器)

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据ID查询用户
     * @param id
     * @return
     */
    @GetMapping("/getUser/{id}")
    public String getUser(@PathVariable("id") String id){
        return userMapper.getUser(id).toString();
    }
}

(UserMapper,用户数据访问接口)

import com.hezy.pojo.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {

    User getUser(String id);
}

数据库数据,tb_user

项目启动,测试一下接口,没得问题;

批量更新

创建一个新的接口,用于触发批量更新对象的代码,内容是传递一个List集合对象给Mapper处理;

    @GetMapping("/updateUser")
    public void updateUser(){
        ArrayList<User> users = new ArrayList<>();

        User user1 = new User();
        user1.setId("1");
        user1.setUsername("zhangsan_fix");

        User user2 = new User();
        user2.setId("2");
        user2.setUsername("lisi_fix");
        user2.setPassword("654321_fix");

        users.add(user1);
        users.add(user2);
        userMapper.updateUser(users);
    }

接下来,重点是Mapper.xml中的Statement要怎么写,继续往下看

方式一

首先,我们可以使用动态SQL,如下:

    <update id="updateUser">
        <foreach collection="users" item="user" separator=";">
            update tb_user
            <set>
                <if test="user.username != null and user.username != ''">
                    username = #{user.username},
                </if>
                <if test="user.password != null and user.password != ''">
                    password = #{user.password}
                </if>
            </set>
            where id = #{user.id}
        </foreach>
    </update>

我们把拼接后的SQL打印出来,会发现一个问题。SQL中,分号(;)表示一条语句的结束,使用上面的方式拼接出来的方式,是多条SQL。

因此产生了一个问题,Mybatis中一个Statement标签中可以有多条SQL吗?

答案是默认不可以,所以上面的代码报错了。

需要在数据库连接后面加上&allowMultiQueries=true配置,如下:

再次执行,修改成功了,这是第一种方式;

查看日志发现,Updates:1,就是说如果需要返回更新的记录条数,那么这种方式返回的更新条数会是1,不能体现出数据库真实发生变化的记录条数;

另外,将多条SQL合成一条执行,有SQL注入的风险

方式二

第二种方式是用一条SQL的方式来实现,如下:

	<update id="updateUser">
	    update tb_user
	    set
	    
	    username = case
	    <foreach collection="users" item="user">
	        when id = #{user.id}
	        <choose>
	            <when test="user.username != null and user.username != ''">then #{user.username}</when>
	            <otherwise>then username</otherwise>
	        </choose>
	    </foreach>
	    end,
	
	    password = case
	    <foreach collection="users" item="user">
	        when id = #{user.id}
	        <choose>
	            <when test="user.password != null and user.password != ''">then #{user.password}</when>
	            <otherwise>then password</otherwise>
	        </choose>
	    </foreach>
	    end
	
	    where
	    <foreach collection="users" item="user" separator="or">
	        id = #{user.id}
	    </foreach>
	</update>

看着有些复杂,拼接后的SQL如下:

	update tb_user
	set
	    username = case
	                   when id = '1' then 'zhangsan_fix'
	                   when id = '2' then 'lisi_fix'
	    end,
	
	    password = case
	                   when id = '1' then password
	                   when id = '2' then '654321_fix'
	    end
	where id = '1'
	   or id = '2';

这种方式不需要加额外的配置,执行测试;

查看数据库,没得问题,批量修改完成了;

总结

本文介绍了Mybatis框架下,批量更新对象的两种方法:

  • 方法一:将多条更新语句合成一条执行,需要在数据库链接后面增加配置,不能体现真实修改的记录条数,有SQL注入的风险;
  • 方法二:使用case then 关键字实现,SQL复杂,行数多,降低了可阅读性;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot调用第三方WebService接口的两种方法

    SpringBoot调用第三方WebService接口的两种方法

    本文主要介绍了SpringBoot调用第三方WebService接口的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 解决没有@RunWith 和 @SpringBootTest注解或失效问题

    解决没有@RunWith 和 @SpringBootTest注解或失效问题

    这篇文章主要介绍了解决没有@RunWith 和 @SpringBootTest注解或失效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • MyBatis详细讲解DAO代理的使用

    MyBatis详细讲解DAO代理的使用

    MyBatis允许只声明一个dao接口,而无需写dao实现类的方式实现数据库操作。前提是必须保证Mapper文件中的<mapper>标签的namespace属性值必须要和dao接口的类路径一致,MyBatis容器会自动通过动态代理生成接口的实现类
    2022-04-04
  • java之this关键字用法实例分析

    java之this关键字用法实例分析

    这篇文章主要介绍了java之this关键字用法实例分析,较为详细的讲述了Java中this关键字的用法及适用范围,并附带实例程序加以说明,需要的朋友可以参考下
    2014-09-09
  • Java中保留两位小数的四种方法实现实例

    Java中保留两位小数的四种方法实现实例

    今天小编就为大家分享一篇关于Java中保留两位小数的四种方法实现实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • Spring Boot 集成Elasticsearch模块实现简单查询功能

    Spring Boot 集成Elasticsearch模块实现简单查询功能

    本文讲解了Spring Boot集成Elasticsearch采用的是ES模板的方式实现基础查询,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2022-06-06
  • SpringBoot+Vue+Element-ui实现前后端分离

    SpringBoot+Vue+Element-ui实现前后端分离

    使用前后端分离的方式,可以减少代码耦合,本文主要介绍了SpringBoot+Vue+Element-ui实现前后端分离,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • java实现多数据源切换方式

    java实现多数据源切换方式

    本文介绍实现多数据源切换的四步方法:导入依赖、配置文件、启动类注解、使用@DS标记mapper和服务层,通过注解实现数据源动态切换,适用于实际开发中的多数据源场景
    2025-08-08
  • Java输出打印工具类封装的实例

    Java输出打印工具类封装的实例

    下面小编就为大家带来一篇Java输出打印工具类封装的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • mybatis 实现字段大小写赋值

    mybatis 实现字段大小写赋值

    这篇文章主要介绍了mybatis 实现字段大小写赋值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11

最新评论