注意:本教程使用的数据库脚本、数据模型和环境信息请参考 “MyBatis Plus环境准备” 章节,点击下载示例源码。
查看 IService 接口你会发现,该接口提供了多个名为 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);
参数说明:
entity:实体对象
updateWrapper:实体对象封装操作类 UpdateWrapper
entityList:实体对象集合
batchSize:插入批次数量
其中,saveOrUpdate(T entity) 方法的实现代码如下:
/** * TableId 注解存在更新记录,否插入一条记录 * * @param entity 实体对象 * @return boolean */ @Transactional(rollbackFor = Exception.class) @Override public boolean saveOrUpdate(T entity) { if (null != entity) { TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass); Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!"); String keyProperty = tableInfo.getKeyProperty(); Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!"); Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty()); return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity); } return false; }
上面方法将判断实体 @TableId 注解修饰的 ID 字段记录是否存在。如果不存在,则执行 save 方法,保存数据;如果存在,则执行 update 方法,更新数据。
如果没有 MyBatis Plus 提供的 saveOrUpdate 方法,我们自己实现该逻辑,大致如下:
public void saveOrUpdate(T entity) { if(null == selectById(entity.getId())) { save(entity); } else { update(entity); } }
(1)更新或新增单个实体,如果 ID 为 9991 的用户信息不存在,则新增用户信息;如果存在,则修改用户信息。代码如下:
package com.hxstrive.mybatis_plus.simple_service.save_or_update; import com.hxstrive.mybatis_plus.model.UserBean; import com.hxstrive.mybatis_plus.service.UserService; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest class SaveOrUpdate1Test { @Autowired private UserService userService; @Test void contextLoads() { UserBean entity = new UserBean(9991, "name-update", "男", 40); boolean flag = userService.saveOrUpdate(entity); System.out.println("flag=" + flag); } }
(2)根据 Wrapper 查询对象批量更新数据。代码如下:
@Test void contextLoads() { UserBean entity = new UserBean(); entity.setName("name-update"); UpdateWrapper<UserBean> wrapper = new UpdateWrapper<>(); wrapper.gt("user_id", 9992); wrapper.le("user_id", 9999); boolean flag = userService.saveOrUpdate(entity, wrapper); System.out.println("flag=" + flag); }
(3)批量插入或更新数据,代码如下:
@Test void contextLoads() { List<UserBean> userBeanList = new ArrayList<>(); userBeanList.add(new UserBean(9992, "username-update")); userBeanList.add(new UserBean(9993, "username-update")); userBeanList.add(new UserBean(9994, "username-update")); boolean flag = userService.saveOrUpdateBatch(userBeanList); System.out.println("flag=" + flag); }
(4)批量插入或更新数据,并且指定每个批次大小为 3。代码如下:
@Test void contextLoads() { List<UserBean> userBeanList = new ArrayList<>(); userBeanList.add(new UserBean(9992, "username-update")); userBeanList.add(new UserBean(9993, "username-update")); userBeanList.add(new UserBean(9994, "username-update")); userBeanList.add(new UserBean(9995, "username-update")); userBeanList.add(new UserBean(9996, "username-update")); userBeanList.add(new UserBean(9997, "username-update")); userBeanList.add(new UserBean(9998, "username-update")); userBeanList.add(new UserBean(9000, "username-save")); boolean flag = userService.saveOrUpdateBatch(userBeanList, 3); System.out.println("flag=" + flag); }