Mybatis Plus 增删改查方法(一、增)
先定义一个简单的测试表,执行脚本如下:
create table user(
id bigint primary key auto_increment,
name varchar(255) not null,
age int not null default 0 check (age >= 0)
);
根据Spingboot+mybatisplus的结构根据表自行构建结构,大致如下:
增
Mapper Interface(Mapper层)
insert
// 插入一条记录
int insert(T entity);
/**
* Mapper层 提供的新增方法 insert() 方法:int insert(T entity)
*/
public void insert_test(User user) {
int insert = userMapper.insert(user);
// 受影响行数
System.out.println("insert:" + insert);
// 获取插入数据的主键 ID
Long id = user.getId();
System.out.println("id:" + id);
}
功能描述: 插入一条记录。
返回值: int,表示插入操作影响的行数,通常为 1,表示插入成功。
参数说明:
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Service Interface(Service层)
save
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
/**
*Service 层 提供的新增方法 save() 方法:boolean save(T entity)
*/
public void save_test(User user) {
boolean save = this.save(user);
//是否保存成功
System.out.println("save:" + save);
// 返回主键ID
Long id = user.getId();
System.out.println("主键 ID: " + id);
}
/**
* Service 层 提供的批量新增方法 saveBatch() 方法:boolean saveBatch(Collection<T> entityList)
* 伪批量插入,命名虽然包含了批量的意思,但这不是真的批量插入
* @param userList
*/
public void savaBatch_test(List<User> userList) {
boolean saveBatch = this.saveBatch(userList);
System.out.println("saveBatch:" + saveBatch);
}
/**
* 伪批量插入,int 表示批量提交数,默认为 1000
* savaBatch(Collection<T>, int) : boolean
* int 表示批量提交数,即多少 SQL 操作执行一次,默认为 1000
* @param userList
*/
public void savaBatch_test2(List<User> userList) {
boolean saveBatch = this.saveBatch(userList, 2);
System.out.println("saveBatch:" + saveBatch);
}
功能描述: 插入记录,根据实体对象的字段进行策略性插入。
返回值: boolean,表示插入操作是否成功。
参数说明:
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
注意:savaBatch 伪批量插入,命名虽然包含了批量的意思,但这不是真的批量插入。
批量新增源码分析
这里用到了insert方法,再往executeBatch里看:
public static <E> boolean executeBatch(Class<?> entityClass, Log log, Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
// 断言需要批处理数据集大小不等于1
Assert.isFalse(batchSize < 1, "batchSize must not be less than one", new Object[0]);
// 判空数据集,若不为空,则开始执行批量处理
return !CollectionUtils.isEmpty(list) && executeBatch(entityClass, log, (sqlSession) -> {
int size = list.size();
// 将批处理大小与传入的操作集合大小进行比较,取最小的那个
int idxLimit = Math.min(batchSize, size);
int i = 1;
// 迭代器循环
for(Iterator var7 = list.iterator(); var7.hasNext(); ++i) {
// 获取当前需要执行的数据库操作
E element = var7.next();
// 回调 sqlSession.insert() 方法
consumer.accept(sqlSession, element);
// 判断是否达到需要批处理的阀值
if (i == idxLimit) {
// 开始批处理,此方法执行并清除缓存在 JDBC 驱动类中的执行语句
sqlSession.flushStatements();
idxLimit = Math.min(idxLimit + batchSize, size);
}
}
});
}
相比较自己手动 for
循环执行插入,Mybatis Plus 这个伪批量插入性能会更好些,内部会将每次的插入语句缓存起来,等到达到 1000 条的时候,才会统一推给数据库,虽然最终在数据库那边还是一条一条的执行 INSERT,但还是在和数据库交互的 IO 上做了优化。
saveOrUpdate(增或改)
// TableId 注解属性值存在则更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
功能描述: 根据实体对象的主键 ID 进行判断,存在则更新记录,否则插入记录。
返回值: boolean,表示插入或更新操作是否成功。
参数说明:
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Wrapper<T> | updateWrapper | 实体对象封装操作类 UpdateWrapper |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
例子:
/**
* Service 层 提供的新增或更新方法 saveOrUpdate() 方法:boolean saveOrUpdate(T entity)
* 保存或者更新。即当你需要执行的数据,数据库中不存在时,就执行插入操作
* 如设置了主键 ID,因为主键 ID 必须是唯一的,Mybatis Plus 会先执行查询操作,判断数据是否存在,存在即执行更新,否则,执行插入操作
* TableId 注解属性值存在则更新记录,否插入一条记录
* @param user
*/
public void saveOrUpdate_test(User user){
boolean saveOrUpdate = this.saveOrUpdate(user);
System.out.println("saveOrUpdate:" + saveOrUpdate);
}
/**
* Service 层 提供的新增或更新方法 boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
* updateWrapper 条件构造器
* 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
* @param user
*/
public void saveOrUpdate_test2(User user){
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getName, user.getName());
boolean saveOrUpdate = this.saveOrUpdate(user, wrapper);
System.out.println("saveOrUpdate:" + saveOrUpdate);
}
/**
* Service 层 提供的批量新增或更新方法 saveOrUpdateBatch() 方法:boolean saveOrUpdateBatch(Collection<T> entityList)
* @param userList
*/
public void saveOrUpdateBatch_test(List<User> userList){
boolean saveOrUpdateBatch = this.saveOrUpdateBatch(userList);
System.out.println("saveOrUpdateBatch:" + saveOrUpdateBatch);
}
/**
* Service 层 提供的批量新增或更新方法 saveOrUpdateBatch() 方法:boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize)
* int 表示批量提交数,即多少 SQL 操作执行一次,默认为 1000
* @param userList
*/
public void saveOrUpdateBatch_test2(List<User> userList){
boolean saveOrUpdateBatch = this.saveOrUpdateBatch(userList, 3);
System.out.println("saveOrUpdateBatch:" + saveOrUpdateBatch);
}