Skip to content

Day3

Mybatis-plus

3.22日补充:Mybatis-plus设计的初衷就是让服务层接口继承IService<T>,而数据访问层接口继承 BaseMapper<T>。至于原因,如果有大佬知道的话,可以指定我一下。

3.21日实习时遇到了一个十分奇怪的bug,下面先给大家复刻一下

项目结构

项目结构

UserController

java
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/create")
    public void createUser() {
        userService.save();
    }

}

User

java
@Data
@TableName("user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

UserMapper

java
public interface UserMapper extends IService<User> {
}

UserService

java
public interface UserService {
    void save();
}

UserServiceImpl

java
@Service
public class UserServiceImpl implements UserService {

    private static final String[] NAMES = {"Alice", "Bob", "Charlie", "David", "Eve"};
    private static final String[] EMAIL_DOMAINS = {"example.com", "test.com", "sample.org"};

    @Autowired
    private UserMapper userMapper;


    @Override
    public void save() {
        List<User> users = createUsers(3);
        userMapper.saveOrUpdateBatch(users);
    }


    private List<User> createUsers(int count) {
        List<User> users = new ArrayList<>(count);
        Random random = new Random();
        for (int i = 0; i < count; i++) {
            User user = new User();
            user.setId((long) i + 1);
            user.setName(NAMES[random.nextInt(NAMES.length)]);
            user.setAge(18 + random.nextInt(43));
            String email = user.getName().toLowerCase() + (i + 1) + "@" + EMAIL_DOMAINS[random.nextInt(EMAIL_DOMAINS.length)];
            user.setEmail(email);

            users.add(user);
        }

        return users;
    }
}

MbpApplication

java
@SpringBootApplication
@MapperScan(basePackages = "org.mbp.mapper")
public class MbpApplication {

    public static void main(String[] args) {
        SpringApplication.run(MbpApplication.class, args);
    }
}

application.yml

yaml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mbp?useUnicode=true&characterEncoding=utf-8
    username: root
    password: 123456


mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  global-config:
    db-config:
      field-strategy: not_empty
      db-type: mysql
  configuration:
    map-underscore-to-camel-case: true

运行结果

请求这个接口后,会出现以下错误

bash
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): org.mbp.mapper.UserMapper.saveOrUpdateBatch

产生原因

目前还不知道,后续跟进

解决办法

修改下列部分内容即可

UserService

java
public interface UserService extends IService<User> {
    void save();
}

UserServiceImpl

java
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService
    
@Override
public void save() {
    List<User> users = createUsers(3);
    // 在同一个类的内部方法调用中使用了@Transactional 注解,
    // 事务管理可能不会按预期生效。
    saveOrUpdateBatch(users);  
}

UserMapper

java
public interface UserMapper extends BaseMapper<User> {
}

缺点也很明显,这样会导致事务注解失效,不推荐这么使用,解决方法后续找到再更新