Mybatis-Flex之增、删、改
方法全解
(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之增、删、改的更多相关文章
- C# ADO.NET (sql语句连接方式)(增,删,改)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- 好用的SQL TVP~~独家赠送[增-删-改-查]的例子
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...
- iOS FMDB的使用(增,删,改,查,sqlite存取图片)
iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...
- iOS sqlite3 的基本使用(增 删 改 查)
iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...
- ADO.NET 增 删 改 查
ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存中供程序调用 ADO.NET所有数据访 ...
- MVC EF 增 删 改 查
using System;using System.Collections.Generic;using System.Linq;using System.Web;//using System.Data ...
- 第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据
第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据 ADO.NET 为什么要学习? 我们要搭建一个平台(Web/Winform ...
- django ajax增 删 改 查
具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...
- StringBuilder修改字符串内容,增,删,改,插
package seday01;/** * 字符串不变对象特性只针对字符串重用,并没有考虑修改操作的性能.因此String不适合频繁修改内容. * 若有频繁修改操作,使用StringBuilder来完 ...
- python基础中的四大天王-增-删-改-查
列表-list-[] 输入内存储存容器 发生改变通常直接变化,让我们看看下面列子 增---默认在最后添加 #append()--括号中可以是数字,可以是字符串,可以是元祖,可以是集合,可以是字典 #l ...
随机推荐
- 《CTFshow-Web入门》06. Web 51~60
@ 目录 web51 题解 web52 题解 原理 web53 题解 原理 web54 题解 原理 web55 题解 原理 web56 题解 原理 web57 题解 原理 web58 题解 原理 we ...
- 《SQL与数据库基础》13. 视图
目录 视图 简介 语法 检查选项 视图更新 视图作用 本文以 MySQL 为例 视图 简介 视图(View)是一种虚拟存在的表.视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的 ...
- 通过提示大语言模型进行个性化推荐LLM-Rec: Personalized Recommendation via Prompting Large Language Models
论文原文地址:https://arxiv.org/abs/2307.15780 本文提出了一种提示LLM并使用其生成的内容增强推荐系统的输入的方法,提高了个性化推荐的效果. LLM-Rec Promp ...
- Hugging News #0912: Hugging Face 2 人入选时代周刊全球百大 AI 人物
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- 万字长文教你实现华为云IoT+OpenHarmony智能家居开发
本文分享自华为云社区<华为云IoT+OpenHarmony的智能家居开发>,作者:袁睿. 一.选题说明 1. 选题为基于OpenHarmony的智能家居,应用场景为户用,受益人群为住户. ...
- PyCharm配置autopep8(自动格式化Python代码)
PyCharm配置autopep8(自动格式化Python代码) 1. 关于PEP 8 PEP 8,Style Guide for Python Code,是Python官方推出编码约定,主要是为 ...
- Iksevi 题解
Iksevi 题目大意 \(n\) 次询问,每次给定一个点 \((x,y),x\ge 0, y\ge 0\),问有多少种对角线长为偶数的正方形使得在用该正方形正密铺第一象限的情况下该点位于正方形顶点上 ...
- LibOciLib使用说明(2017-1-26更新)
LibOciLib使用说明 整理者:赤勇玄心行天道 QQ:280604597 Email:280604597@qq.com 大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的! ...
- 小景的工具使用--Java诊断工具Arthas的使用说明
小景最近在做程序和数据库的压测工作,期间监控压测数据,分析程序原因变成了一个待解决的问题,根据公司小伙伴的建议,接触了阿尔萨斯这个诊断工具,下面小景分别基于Linux操作系统和Windows操作系统, ...
- Python自动化处理Excel数据
需求描述:数据格式如下所示,需要分离出2023年7月1号之后的数据明细 数据核对与处理:从Excel文件中提取特定日期后的签收数据 1. 引言 在实际数据处理和分析过程中,经常会遇到需要从大量数据中提 ...