准备系列-Mybatis(八) TKmybatis-springboot 项目的增删改查及批量处理

143 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情

在之前的几篇中,我们已经介绍了项目配置及项目启动,Druid,tkMybatis的配置信息 及各种各样的查询信息, 今天我们讲一下 其他操作 除查询外的增/删/改等操作及涉及到的批量处理

本文主要介绍TKmybatis的使用,增删改查及如何批量操作

另外介绍大家比较迷惑的 xxxSelective 及 Example 更新操作的区别

  • updateByExampleSelective 和 updateByExample
  • updateByPrimaryKeySelective 和 updateByPrimaryKey

配置及数据准备

1.准备mysql数据
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (1, '11', 'aa', 1, '北京', '[1, 2, 3]', '{\"deptId\": 1, \"deptName\": \"部门1\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (2, '22', 'bb', 2, '上海', '[4, 5, 6]', '{\"deptId\": 1, \"deptName\": \"部门1\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (3, '33', 'cc', 31, '广州', '[7, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (4, '44', 'dd', 14, '深圳', '[9, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (5, '55', 'ee', 25, '上海', '[8, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (6, '66', 'ff', 34, '西安', '[10, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (7, '77', 'gg', 41, '郑州', '[8, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (8, '88', 'hh', 4, '武汉', '[8, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (9, '99', 'ii', 14, '武汉', '[8, 5, 6]', '{\"deptId\": 2, \"deptName\": \"部门2\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (10, '10', 'jj', 26, '武汉', '[18, 5, 6]', '{\"deptId\": 3, \"deptName\": \"部门3\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (11, '126', 'kk', 49, '深圳', '[18, 15, 6]', '{\"deptId\": 3, \"deptName\": \"部门3\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (12, '5896', 'll', 14, '北京', '[28, 35, 36]', '{\"deptId\": 4, \"deptName\": \"部门4\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (13, '456', 'mm', 14, '上海', '[28, 25, 26]', '{\"deptId\": 4, \"deptName\": \"部门4\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
INSERT INTO `test`.`user_info` (`id`, `user_id`, `user_name`, `age`, `address`, `order_ids`, `goods`, `sort_order`, `is_del`, `addtime`, `modtime`) VALUES (14, '456', 'nn', 34, '上海', '[18, 15, 16]', '{\"deptId\": 4, \"deptName\": \"部门4\", \"deptLeaderId\": 4}', 0, 0, 0, 0);
1.2 修改表结构字段信息

设置其他字段可空, 测试update信息

ALTER TABLE user_info MODIFY user_id char(32) NULL DEFAULT NULL COMMENT '用户ID';
ALTER TABLE user_info MODIFY user_name char(32) NULL DEFAULT NULL COMMENT '用户ID';
ALTER TABLE user_info MODIFY age int NULL DEFAULT NULL COMMENT '年龄';
ALTER TABLE user_info MODIFY address varchar(200) NULL DEFAULT NULL COMMENT '地址';
ALTER TABLE user_info MODIFY is_del tinyint NULL DEFAULT '0' COMMENT '是否删除';
ALTER TABLE user_info MODIFY modtime int NULL DEFAULT '0' COMMENT '修改时间';
ALTER TABLE user_info MODIFY addtime int NULL DEFAULT '0' COMMENT '创建时间';

2.插入及批量插入请求

2.1 单个数据插入

单个数据 直接调用 Mapper文件中的 insert即可

@Override
public void insertUser() {
    UserInfoPO userInfoPO = new UserInfoPO();
    userInfoPO.setUserId(UUIDUtil.uuid());
    userInfoPO.setUserName("xxx");
    userInfoPO.setAge(1);
    userInfoPO.setAddress("郑州");
    userInfoPO.setOrderIds("1");
    userInfoPO.setSortOrder(0);
    userInfoPO.setIsDel(new Byte("0"));
    userInfoPO.setAddtime(1);
    userInfoPO.setModtime(1);

    mapper.insert(userInfoPO);
}

插入成功 image.png

2.2 批量数据插入
@Override
public void batchInsert() {
    UserInfoPO userInfoPO1 = new UserInfoPO();
    userInfoPO1.setUserId(UUIDUtil.uuid());
    userInfoPO1.setUserName("xxx1");
    userInfoPO1.setAge(1);
    userInfoPO1.setAddress("郑州1");
    userInfoPO1.setOrderIds("1");
    userInfoPO1.setSortOrder(0);
    userInfoPO1.setIsDel(new Byte("0"));
    userInfoPO1.setAddtime(1);
    userInfoPO1.setModtime(1);

    UserInfoPO userInfoPO2 = new UserInfoPO();
    userInfoPO2.setUserId(UUIDUtil.uuid());
    userInfoPO2.setUserName("xxx2");
    userInfoPO2.setAge(1);
    userInfoPO2.setAddress("郑州2");
    userInfoPO2.setOrderIds("1");
    userInfoPO2.setSortOrder(0);
    userInfoPO2.setIsDel(new Byte("0"));
    userInfoPO2.setAddtime(1);
    userInfoPO2.setModtime(1);

    List<UserInfoPO> userList = new ArrayList<>();
    userList.add(userInfoPO1);
    userList.add(userInfoPO2);
    mapper.insertList(userList);
}

插入2条数据成功 image.png

3.删除数据及批量删除

3.1 按照主键删除

// 删除主键id为15的数据
userService.deleteUser(15L);


@Override
public void deleteUser(String userid) {
    UserInfoPO userInfoPO = new UserInfoPO();
    //删除主键id为15的数据
    userInfoPO.setId(15L);
    mapper.deleteByPrimaryKey(userInfoPO);
}

数据库数据 image.png 删除数据主键为15的数据

image.png

数据库 没有主键15的数据,删除成功 image.png

3.2 Example批量数据删除
// 删除一批user id的信息
List<String> userIdList = new ArrayList<>();
userIdList.add("ce8a39349a08487485573e0c3e8de2b0");
userIdList.add("963577a300dd4480833fe1db0c4f4914");
userService.deleteExample(userIdList);


@Override
public void deleteExample(List<String> userIdList) {
    Example example = new Example(UserInfoPO.class);

    //删除 id 在集合中的数据
    example.createCriteria()
            .andIn("userId",  userIdList);

    mapper.deleteByExample(example);
}

数据库数据 image.png

删除数据 image.png

数据库没有 userId = ce8a39349a08487485573e0c3e8de2b0 或者 963577a300dd4480833fe1db0c4f4914 的数据,删除成功 image.png

4.修改数据及批量修改

4.1 慎用 单个数据 updateByPrimaryKey 修改

数据库现有数据

  • id:18
  • userId:9f7b4299734f446da1121aece84283d9
  • name:xxx
  • age:1

image.png

/**
 * 探活接口
 */
@RequestMapping("/temp/update")
@ResponseBody
public Object update() {

    UserInfoPO userInfoPO = new UserInfoPO();
    //设置主键
    userInfoPO.setId(18L);
    //设置 新名字
    userInfoPO.setUserName("aaa");
    //把年龄设置为空, 看空值是否更新
    userInfoPO.setAge(null);
    userService.updateUser(userInfoPO);
    return "pong";
}


@Override
public void updateUser(UserInfoPO userInfoPO) {
    mapper.updateByPrimaryKey(userInfoPO);
}

执行结果

image.png

!!! updateByPrimaryKey 会把 没有设置的字段 或者 设置为null的字段 !!! updateByPrimaryKey 会把 没有设置的字段 或者 设置为null的字段 !!! updateByPrimaryKey 会把 没有设置的字段 或者 设置为null的字段

我本来只想 更新一个Name 字段, 结果 却把其他所有字段全都重置 为null了

全部更新到 DB中 image.png

  • id: 18
  • userId:9f7b4299734f446da1121aece84283d9 变为null
  • name:xxx 变为null
  • age:1 变为null

如果我只想 更新 name字段 该如何操作???

4.2 updateByPrimaryKeySelective 非空数据修改

数据库现有数据

image.png

我们采用 updateByPrimaryKeySelective 有选择性的, 来更新非空数据


UserInfoPO userInfoPO = new UserInfoPO();
//设置主键
userInfoPO.setId(23L);
//设置 新名字
userInfoPO.setUserName("aaa");
//把年龄设置为空, 看空值是否更新
userInfoPO.setAge(null);
userService.updateUserSelective(userInfoPO);


@Override
public void updateUserSelective(UserInfoPO userInfoPO) {
    mapper.updateByPrimaryKeySelective(userInfoPO);
}

执行结果 可以看到 只更新了 非空的name字段, 其他字段age及其他字段为空 全部没处理,保留了原始数据

image.png

DB数据 只有aaa name字段被更新了, 其他字段为空, 全都不处理, selective选择性处理非空的字段数据

image.png

4.3 updateByExampleSelective和updateByExample的区别

知道了 updateByPrimaryKey 及 updateByPrimaryKeySelective 的区别

那我们updateByExampleSelective和updateByExample的区别也知道了

  • updateByExampleSelective 选择性的更新非空数据
  • updateByExample PO传入是啥就是啥,全部更新, null没设置也更新为null