方法全解

(1) INSERT

BaseMapper 的接口提供了 insert 和 insertBatch 方法,用于新增数据;

  • insert(entity):插入实体类数据,不忽略 null 值。
  • insertSelective(entity):插入实体类数据,但是忽略 null 的数据,只对有值的内容进行插入。这样的好处是数据库已经配置了一些默认值,这些默认值才会生效。
  • insert(entity, ignoreNulls):插入实体类数据。
  • insertWithPk(entity):插入带有主键的实体类,不忽略 null 值。
  • insertSelectiveWithPk(entity):插入带有主键的实体类,忽略 null 值。
  • insertWithPk(entity, ignoreNulls):带有主键的插入,此时实体类不会经过主键生成器生成主键。
  • insertBatch(entities):批量插入实体类数据,只会根据第一条数据来构建插入的字段内容。
  • insertBatch(entities, size):批量插入实体类数据,按 size 切分。
  • insertOrUpdate(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都不会忽略 null 值。
  • insertOrUpdateSelective(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都会忽略 null 值。
  • insertOrUpdate(entity, ignoreNulls):插入或者更新,若主键有值,则更新,若没有主键值,则插入。
① insert
/**
* insert(entity):插入实体类数据,不忽略 null 值。
* insert(entity, ignoreNulls):插入实体类数据。
*/
@Test
public void testInsert() {
/**
* 默认不忽略null值
* INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?)
*/
int row = accountMapper.insert(new Account().setUserName(null).setBirthday(new Date()).setAge(25));
Assertions.assertEquals(row, 1); /**
* ignoreNulls true:忽略null , false:不忽略null
* INSERT INTO `tb_account`(`user_name`) VALUES (?)
*/
int row2 = accountMapper.insert(new Account().setUserName("ly3").setBirthday(null).setAge(null), true);
Assertions.assertEquals(row2, 1);
}
② insertSelective
/**
* insertSelective(entity):插入实体类数据,但是忽略 null 的数据,只对有值的内容进行插入。这样的好处是数据库已经配置了一些默认值,这些默认值才会生效。
*/
@Test
public void testInsertSelective() {
/**
* INSERT INTO `tb_account`(`user_name`) VALUES (?)
*/
int row = accountMapper.insertSelective(new Account().setUserName("陈远航").setAge(null));
Assertions.assertEquals(row, 1);
}
③ insertWithPk
/**
* insertWithPk(entity):插入带有主键的实体类,不忽略 null 值。
*/
@Test
public void testInsertWithPk() {
/**
* INSERT INTO `tb_account`(`id`, `user_name`, `age`, `birthday`) VALUES (?, ?, ?, ?)
*/
int row = accountMapper.insertWithPk(new Account().setUserName("廖楷瑞").setId(5L).setBirthday(null));
Assertions.assertEquals(row, 1);
}
④ insertBatch
/**
* insertBatch(entities):批量插入实体类数据,只会根据第一条数据来构建插入的字段内容。
* insertBatch(entities, size):批量插入实体类数据,按 size 切分。
*/
@Test
public void testInsertBatch() {
List<Account> accounts = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
Account account = new Account().setUserName("ly" + i).setBirthday(new Date()).setAge(20 + i);
accounts.add(account);
}
/**
* 批量插入,可以指定每次插入的数据大小size
* size=2 : INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?), (?, ?, ?)
* size=3 : INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?)
* ......
*/
int rows = accountMapper.insertBatch(accounts, 2);
System.out.println("rows = " + rows);
}
⑤ insertOrUpdate
/**
* insertOrUpdate(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都不会忽略 null 值。
* insertOrUpdateSelective(entity):插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都会忽略 null 值。
* insertOrUpdate(entity, ignoreNulls):插入或者更新,若主键有值,则更新,若没有主键值,则插入。
*/
@Test
public void testInsertOrUpdate() {
Account account = new Account().setUserName("ly-update2").setId(3L).setBirthday(new Date()).setAge(21);
/**
* UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
*/
int row = accountMapper.insertOrUpdate(account);
Assertions.assertEquals(row, 0, 1); account = new Account().setUserName("ly-update2").setBirthday(null).setAge(21);
/**
* INSERT INTO `tb_account`(`user_name`, `age`) VALUES (?, ?)
*/
int row2 = accountMapper.insertOrUpdateSelective(account);
Assertions.assertEquals(row2, 0, 1);
}

(2) DELETE

BaseMapper 的接口提供了 deleteById、deleteBatchByIds、deleteByMap、deleteByQuery 方法,用于删除数据;

  • deleteById(id):根据主键删除数据。如果是多个主键的情况下,需要传入数组,例如:new Integer[]{100,101}。
  • deleteBatchByIds(ids):根据多个主键批量删除数据。
  • deleteBatchByIds(ids, size):根据多个主键批量删除数据。
  • deleteByMap(whereConditions):根据 Map 构建的条件来删除数据。
  • deleteByCondition(whereConditions):根据查询条件来删除数据。
  • deleteByQuery(queryWrapper):根据查询条件来删除数据。
① deleteById
/**
* deleteById(id):根据主键删除数据。
* ??? 如果是多个主键的情况下,需要传入数组,例如:new Integer[]{100,101}。 ??? 怀疑态度
*/
@Test
public void testDeleteById() {
/**
* DELETE FROM `tb_account` WHERE `id` = ?
*/
int row = accountMapper.deleteById(9L);
Assertions.assertTrue(row > 0);
}
② deleteBatchByIds
/**
* deleteBatchByIds(ids):根据多个主键批量删除数据。
* deleteBatchByIds(ids, size):根据多个主键批量删除数据。
*/
@Test
public void testDeleteBatchByIds() {
List<Integer> ids = List.of(5, 6, 7, 8);
/**
* DELETE FROM `tb_account` WHERE `id` = ? OR `id` = ? OR `id` = ? OR `id` = ?
*/
int rows = accountMapper.deleteBatchByIds(ids);
Assertions.assertTrue(rows > 0); /**
* 分批删除
* size=2 : DELETE FROM `tb_account` WHERE `id` = ? OR `id` = ?
*/
int rows2 = accountMapper.deleteBatchByIds(ids, 2);
Assertions.assertTrue(rows2 > 0);
}
③ deleteByMap
/**
* deleteByMap(whereConditions):根据 Map 构建的条件来删除数据。
*/
@Test
public void testDeleteByMap() {
/**
* DELETE FROM `tb_account` WHERE `tb_account`.`age` = ?
*/
int rows = accountMapper.deleteByMap(Map.of("age", 25));
Assertions.assertTrue(rows > 0);
}
④ deleteByCondition
 /**
* deleteByCondition(whereConditions):根据查询条件来删除数据。
*/
@Test
public void testDeleteByCondition() {
QueryCondition condition = QueryCondition.createEmpty().and("age = 27");
/**
* DELETE FROM `tb_account` WHERE age = 27
*/
int rows = accountMapper.deleteByCondition(condition);
Assertions.assertTrue(rows > 0); /**
* DELETE FROM `tb_account` WHERE `id` > ?
*/
int rows2 = accountMapper.deleteByCondition(ACCOUNT.ID.gt(35));
Assertions.assertTrue(rows2 > 0);
}
⑤ deleteByQuery
/**
* deleteByQuery(queryWrapper):根据查询条件来删除数据。
*/
@Test
public void testDeleteByQuery() {
/**
* DELETE FROM `tb_account` WHERE `age` >= ?
*/
QueryWrapper wrapper = QueryWrapper.create().where(ACCOUNT.AGE.ge(32));
int rows = accountMapper.deleteByQuery(wrapper);
Assertions.assertTrue(rows > 0);
}

(3) UPDATE

BaseMapper 的接口提供了 update、updateByMap、updateByQuery 方法,用于更新数据;

  • update(entity):根据主键来更新数据,若实体类属性数据为 null,该属性不会新到数据库。
  • update(entity, ignoreNulls):根据主键来更新数据到数据库。
  • updateByMap(entity, whereConditions):根据 Map 构建的条件来更新数据。
  • updateByMap(entity, ignoreNulls, whereConditions):根据 Map 构建的条件来更新数据。
  • updateByCondition(entity, whereConditions):根据查询条件来更新数据。
  • updateByCondition(entity, ignoreNulls, whereConditions):根据查询条件来更新数据。
  • updateByQuery(entity, queryWrapper):根据查询条件来更新数据。
  • updateByQuery(entity, ignoreNulls, queryWrapper):根据查询条件来更新数据。
① update
 @Test
public void testUpdate() {
Account account = new Account().setId(5L)
.setAge(39)
.setUserName("测试修改")
.setBirthday(new Date(2023, Calendar.SEPTEMBER, 6, 12, 12, 12));
/**
* UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
*/
int rows = accountMapper.update(account);
Assertions.assertTrue(rows > 0);
} @Test
public void testUpdateIgnoreNulls() {
Account account = new Account().setId(6L)
.setAge(null)
.setUserName(null)
.setBirthday(new Date(2023, Calendar.SEPTEMBER, 6, 12, 12, 12));
/**
* 不忽略null值
* UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
*/
int rows = accountMapper.update(account, false);
System.out.println("rows = " + rows);
}
② updateByMap
@Test
public void testUpdateByMap() {
Account account = new Account()
.setId(7L) // 不生效
.setUserName("updateByMap")
.setAge(24)
.setBirthday(null);
// 注意:这样更新实体类的id是不生效的
Map<String, Object> whereCondition = Map.of("id", 13); /**
* 忽略null
* UPDATE `tb_account` SET `user_name` = ? , `age` = ? WHERE `id` = ?
*/
accountMapper.updateByMap(account, whereCondition); /**
* 不忽略null
* UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
*/
accountMapper.updateByMap(account, false, whereCondition);
}
③ updateByCondition
/**
* updateByCondition(entity, whereConditions):根据查询条件来更新数据。
* updateByCondition(entity, ignoreNulls, whereConditions):根据查询条件来更新数据。
*/
@Test
public void testUpdateByCondition() {
Account account = new Account()
.setId(8L)
.setUserName("updateByCondition")
.setBirthday(DateUtil.toDate(LocalDateTime.now()));
QueryCondition condition = QueryCondition.create(new QueryColumn("id"),
SqlConsts.EQUALS, 8);
/**
* 忽略null
* UPDATE `tb_account` SET `user_name` = ? , `birthday` = ? WHERE `id` = ?
*/
accountMapper.updateByCondition(account, condition); /**
* 不忽略null
* UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ?
*/
accountMapper.updateByCondition(account, false, condition);
}
④ updateByQuery
/**
* updateByQuery(entity, queryWrapper):根据查询条件来更新数据。
* updateByQuery(entity, ignoreNulls, queryWrapper):根据查询条件来更新数据。
*/
@Test
public void testUpdateByQuery() {
Account account = new Account().setUserName("updateByQuery"); /**
* UPDATE `tb_account` SET `user_name` = ? WHERE `id` = ?
*/
accountMapper.updateByQuery(account,
QueryWrapper.create().where(ACCOUNT.ID.eq(9L)));
}
⑤ UpdateEntity部分字段更新
@Test
public void testUpdateEntity1() {
Account account = UpdateEntity.of(Account.class, 10L);
/**
* 官方说明:通过 UpdateEntity 创建的对象,只会更新调用了 setter 方法的字段,若不调用 setter 方法,不管这个对象里的属性的值是什么,都不会更新到数据库。
*/
account.setAge(66)
.setUserName("UpdateEntity")
.setBirthday(null);
accountMapper.update(account);
} @Test
public void testUpdateEntity2() {
Account account = new Account()
.setId(10L)
.setUserName("UpdateEntity2");
UpdateWrapper wrapper = UpdateWrapper.of(account);
// wrapper.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1)); wrapper.setRaw("age", "age + 1");
accountMapper.update(account);
} @Test
public void testUpdateEntity3() {
Account account = new Account()
.setId(10L)
.setUserName("UpdateEntity2");
UpdateWrapper wrapper = UpdateWrapper.of(account); // wrapper.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1)); wrapper.setRaw(ACCOUNT.AGE, "select * from t_account where id = 3");
// accountMapper.updateByCondition(account, wrapper);
}
⑥ UpdateChain
@Test
public void testUpdateChain() {
/**
* UPDATE `tb_account` SET `birthday` = ? , `age` = age + 1 WHERE `age` = ?
*/
UpdateChain.of(Account.class)
.set(Account::getBirthday, new Date())
.setRaw(Account::getAge, "age + 1")
.where(ACCOUNT.AGE.eq(11)).update();
}

set() 和 setRaw() 的区别

在 Row、UpdateWrapper、UpdateChain 中,都提供了 set() 和 setRaw() 两个方法用于设置数据。 那么,他们有什么区别呢?

  • set() 方法用于设置参数数据。
  • setRaw() 用于设置 SQL 拼接数据。

Mybatis-Flex之增、删、改的更多相关文章

  1. C# ADO.NET (sql语句连接方式)(增,删,改)

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  2. 好用的SQL TVP~~独家赠送[增-删-改-查]的例子

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化.  本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...

  3. iOS FMDB的使用(增,删,改,查,sqlite存取图片)

    iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...

  4. iOS sqlite3 的基本使用(增 删 改 查)

    iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...

  5. ADO.NET 增 删 改 查

    ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存中供程序调用 ADO.NET所有数据访 ...

  6. MVC EF 增 删 改 查

    using System;using System.Collections.Generic;using System.Linq;using System.Web;//using System.Data ...

  7. 第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据

    第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据 ADO.NET 为什么要学习? 我们要搭建一个平台(Web/Winform ...

  8. django ajax增 删 改 查

    具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...

  9. StringBuilder修改字符串内容,增,删,改,插

    package seday01;/** * 字符串不变对象特性只针对字符串重用,并没有考虑修改操作的性能.因此String不适合频繁修改内容. * 若有频繁修改操作,使用StringBuilder来完 ...

  10. python基础中的四大天王-增-删-改-查

    列表-list-[] 输入内存储存容器 发生改变通常直接变化,让我们看看下面列子 增---默认在最后添加 #append()--括号中可以是数字,可以是字符串,可以是元祖,可以是集合,可以是字典 #l ...

随机推荐

  1. 《Linux基础》01. 概述

    @ 目录 1:Linux的应用领域 1.1:个人桌面领域的应用 1.2:服务器领域 1.3:嵌入式领域 2:Linux介绍 3:Linux和Unix的关系 4:Linux基本规则 Linux介绍 1: ...

  2. MySQL到SelectDB的实时同步策略

    随着数据分析在业务决策中变得日益重要,数据实时同步和分析成为企业提升竞争力的关键.MySQL 作为广泛使用的关系型数据库,其数据存储丰富,但无法满足大规模数据分析和高并发查询的需求.而 SelectD ...

  3. Codeforces 1254B1 - Send Boxes to Alice (Easy Version)

    题意 有\(n(1\leq n\leq 10^5)\)个盒子,每个盒子有\(a_i(0\leq a_i \leq 1)\)个糖果,你每一次可以将第\(i\)个盒子里的糖果放到第\(i-1\)或\(i+ ...

  4. jquery实现表格导出Excel

    使用jQuery,jszip.js,FileSaver.js,excel-gen.js插件直接将网页中的table表格导出到本地Excel文件,而不需要经过后台. 导出结果: 实现步骤: 1.进入相关 ...

  5. Codechef - Maximize Colours(IQ)

    题目大意   有红绿蓝三种颜色,三种颜色当中任意两个颜色混合都可以产生出一个新的颜色(然而混合产生的颜色不能与任何其它的颜色进行混合).输入三个整数,分别代表红色,绿色,蓝色的颜色个数(每次混合各消耗 ...

  6. 7. 用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP及TCP内网穿透原理及运行篇

    用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP及TCP内网穿透原理及运行篇 项目 ++wmproxy++ gite: https://gitee.com/tickbh/wmpr ...

  7. 关于 iPhone 上的相机功能

    关于 iPhone 上的相机功能 了解 iPhone 上的摄影风格.快录功能.超广角摄像头和其他相机功能.   通过摄影风格功能锁定您的风格 借助 iPhone 13 各款机型和 iPhone SE( ...

  8. Maximum Diameter 题解

    Maximum Diameter 题目大意 定义长度为 \(n\) 的序列 \(a\) 的权值为: 所有的 \(n\) 个点的第 \(i\) 个点的度数为 \(a_i\) 的树的直径最大值,如果不存在 ...

  9. 【matplotlib 实战】--气泡图

    气泡图是一种多变量的统计图表,可以看作是散点图的变形.与散点图不同的是,每一个气泡都表示三个维度的数据,除了像散点图一样有X,Y轴,气泡的大小可以表示另一个维度的数据.例如,x轴表示产品销量,y轴表示 ...

  10. Unity学习笔记--入门

    Unity引擎学习 入门: Unity中的坐标系: 左手坐标系(z轴正方向向里面) x轴:平行屏幕向右正方向 y轴:平行屏幕向上正方向 Z轴:垂直屏幕向内为正方向 [补]openGL是右手坐标系 Di ...