# mybatis-plus的IService.update修改

# 当前使用版本

V3.4.1

# 该问题是如何引起的?

调用IService接口default boolean update(Wrapper updateWrapper)方法时,自动填充字段无法更新。

# 重现步骤

基于此工程 (opens new window)

增加以下类:

package com.baomidou.samples.metainfo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.samples.metainfo.entity.User;
/**
 * @Description TODO
 * @Author 刘默远
 * @Email soul.lau0328@gmail.com
 * @Date 2021-01-06 21:10
 */
public interface UserService extends IService<User> {

}
package com.baomidou.samples.metainfo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.samples.metainfo.entity.User;
import com.baomidou.samples.metainfo.mapper.UserMapper;
import com.baomidou.samples.metainfo.service.UserService;
import org.springframework.stereotype.Service;

/**
 * @Description TODO
 * @Author 刘默远
 * @Email soul.lau0328@gmail.com
 * @Date 2021-01-06 21:12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

package com.baomidou.samples.metainfo;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.samples.metainfo.entity.User;
import com.baomidou.samples.metainfo.mapper.UserMapper;
import com.baomidou.samples.metainfo.service.UserService;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.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;

/**
 * @Description AutoFillUpdateTest
 * @Author 刘默远
 * @Email soul.lau0328@gmail.com
 * @Date 2021-01-06 21:15
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class AutoFillUpdateTest {

    @Autowired
    private UserService userService;

    @Test
    public void testUpdate() {

        User beforeUser = userService.getById(1L);
        log.info("before user:{}", beforeUser);
        UpdateWrapper updateWrapper = Wrappers.update();
        updateWrapper.set("age",14);
        updateWrapper.eq("id",1L);
        //此方法有bug。
        userService.update(updateWrapper);
        log.info("query user:{}", userService.getById(1L));

        //以下方法是正确的
        userService.update(new User(),updateWrapper);
        log.info("query user:{}", userService.getById(1L));
    }
}

# 报错信息

2021-01-06 21:18:07.093 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : ==>  Preparing: SELECT ID,NAME,AGE,EMAIL,OPERATOR FROM user WHERE ID=?
2021-01-06 21:18:07.122 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : ==> Parameters: 1(Long)
2021-01-06 21:18:07.152 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : <==      Total: 1
2021-01-06 21:18:07.153  INFO 33668 --- [           main] c.b.samples.metainfo.AutoFillUpdateTest  : before user:User(id=1, name=Jone, age=18, email=test1@baomidou.com, operator=test)

2021-01-06 21:18:07.203 DEBUG 33668 --- [           main] c.b.s.metainfo.mapper.UserMapper.update  : ==>  Preparing: UPDATE user SET age=? WHERE (id = ?)
2021-01-06 21:18:07.210 DEBUG 33668 --- [           main] c.b.s.metainfo.mapper.UserMapper.update  : ==> Parameters: 14(Integer), 1(Long)
2021-01-06 21:18:07.212 DEBUG 33668 --- [           main] c.b.s.metainfo.mapper.UserMapper.update  : <==    Updates: 1
2021-01-06 21:18:07.212 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : ==>  Preparing: SELECT ID,NAME,AGE,EMAIL,OPERATOR FROM user WHERE ID=?
2021-01-06 21:18:07.212 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : ==> Parameters: 1(Long)
2021-01-06 21:18:07.213 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : <==      Total: 1
2021-01-06 21:18:07.213  INFO 33668 --- [           main] c.b.samples.metainfo.AutoFillUpdateTest  : query user:User(id=1, name=Jone, age=14, email=test1@baomidou.com, operator=test)
//执行userService.update(updateWrapper)后,以上打印信息可看到operator并没有自动填充。
2021-01-06 21:18:07.216  INFO 33668 --- [           main] c.b.s.m.handler.MyMetaObjectHandler      : start update fill ....
2021-01-06 21:18:08.729  INFO 33668 --- [           main] c.b.s.m.handler.MyMetaObjectHandler      : end update fill!
2021-01-06 21:18:08.729 DEBUG 33668 --- [           main] c.b.s.metainfo.mapper.UserMapper.update  : ==>  Preparing: UPDATE user SET OPERATOR=?, age=? WHERE (id = ?)
2021-01-06 21:18:08.730 DEBUG 33668 --- [           main] c.b.s.metainfo.mapper.UserMapper.update  : ==> Parameters: Soul(String), 14(Integer), 1(Long)
2021-01-06 21:18:08.730 DEBUG 33668 --- [           main] c.b.s.metainfo.mapper.UserMapper.update  : <==    Updates: 1
2021-01-06 21:18:08.731 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : ==>  Preparing: SELECT ID,NAME,AGE,EMAIL,OPERATOR FROM user WHERE ID=?
2021-01-06 21:18:08.731 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : ==> Parameters: 1(Long)
2021-01-06 21:18:08.732 DEBUG 33668 --- [           main] c.b.s.m.mapper.UserMapper.selectById     : <==      Total: 1
2021-01-06 21:18:08.732  INFO 33668 --- [           main] c.b.samples.metainfo.AutoFillUpdateTest  : query user:User(id=1, name=Jone, age=14, email=test1@baomidou.com, operator=Soul)
//执行userService.update(new User(),updateWrapper)后,可看到operator并已经自动填充为Soul。

# 修改建议

IService接口的default boolean update(Wrapper updateWrapper)方法实现由

    default boolean update(Wrapper<T> updateWrapper) {
        return update(null, updateWrapper);
    }

修改为

    default boolean update(Wrapper<T> updateWrapper) {
        T entity = updateWrapper.getEntity();
        if (entity == null) {
            try {
                entity = this.getEntityClass().newInstance();
            } catch (InstantiationException e) {
            } catch (IllegalAccessException e) {
            }
        }
        return update(entity, updateWrapper);
    }

即可解决以上问题。