Skip to content

MyBatis-Plus ⚠️

MyBatis-Plus 是 Spring Boot 生态中最接近 Eloquent 的 ORM。但注意:Java 主流 ORM 设计模式是 Data Mapper,不是 Active Record


Eloquent vs MyBatis-Plus 核心差异

特性EloquentMyBatis-Plus
模式Active RecordData Mapper
模型类继承 Model,自带 CRUD纯数据类(Entity)+ 独立的 Mapper 接口
查询User::where('age', '>', 18)->get()userMapper.selectList(wrapper)
关联$user->posts()(模型上定义)@TableField(exist = false) + 手动查询
保存$user = new User(); $user->save();userMapper.insert(user)
更新$user->update(['name' => 'foo'])userMapper.updateById(user)
删除$user->delete()userMapper.deleteById(id)

三步使用

1. 添加依赖

xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.7</version>
</dependency>

2. 定义 Entity(数据类)

java
@TableName("users")              // 类比 protected $table = 'users'
public class User {

    @TableId(type = IdType.AUTO) // 类比 $incrementing = true
    private Long id;

    private String name;

    private String email;

    private Integer age;

    @TableField("created_at")    // 字段名映射(类名下划线→驼峰可省略)
    private LocalDateTime createdAt;

    @TableField("updated_at")
    private LocalDateTime updatedAt;

    // getter / setter(必须写,或用 @Data)
}

3. 定义 Mapper(类比 Repository)

java
@Mapper                               // 标记为 MyBatis Mapper
public interface UserMapper extends BaseMapper<User> {
    // BaseMapper 已经提供了 CRUD 方法,不需要写 SQL
    // 类比 Laravel 中继承 Model 后就有的 create/find/update/delete
}

// 使用
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User findById(Long id) {
        return userMapper.selectById(id);   // 类比 User::find($id)
    }
}

CRUD 操作对照

java
// 查询单个
User user = userMapper.selectById(1L);                                  // User::find(1)
User user = userMapper.selectOne(wrapper);                               // User::where()->first()

// 查询列表
List<User> users = userMapper.selectList(null);                          // User::all()
List<User> users = userMapper.selectList(wrapper);                       // User::where()->get()

// 分页
Page<User> page = userMapper.selectPage(new Page<>(1, 10), wrapper);    // User::paginate(10)

// 插入
userMapper.insert(user);                                                 // User::create($data) 或 $user->save()

// 更新
userMapper.updateById(user);                                             // $user->update()
userMapper.update(user, wrapper);                                        // User::where()->update()

// 删除
userMapper.deleteById(1L);                                               // User::destroy(1)
userMapper.delete(wrapper);                                              // User::where()->delete()

// 计数
Long count = userMapper.selectCount(wrapper);                            // User::where()->count()

条件构建器(Wrapper)

java
// ⚠️ Java 的条件构建器相当于 Eloquent 的 where 链式调用,但用对象封装

// 1. 简单查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("email", "foo@bar.com");               // where email = 'foo@bar.com'
User user = userMapper.selectOne(wrapper);

// 2. 多条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "张")                         // where name like '%张%'
       .gt("age", 18)                              // and age > 18
       .orderByDesc("created_at")                  // order by created_at desc
       .last("limit 10");                          // 直接追加 SQL
List<User> users = userMapper.selectList(wrapper);

// 3. Lambda 写法(推荐,避免硬编码字段名)
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getEmail, "foo@bar.com")          // 用方法引用代替字符串
       .ge(User::getAge, 18);

⚠️ 常见坑

1. Entity 必须有无参构造器

java
// MyBatis 通过反射创建 Entity 实例,需要无参构造器
// 如果你定义了有参构造器,必须同时加上无参构造器
public User() {}  // 必须存在

2. 字段名映射规则

MyBatis-Plus 默认开启下划线转驼峰created_atcreatedAt。 如果数据库字段和 Java 属性不是这种对应关系,需要加 @TableField

3. 分页需要额外配置

java
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

不配的话,selectPage 不会返回总记录数。

4. 插入后获取自增 ID

java
userMapper.insert(user);
Long id = user.getId();    // MyBatis-Plus 会自动把自增 ID 写回 Entity
// 不需要像 PHP 那样 $user->id

5. ⭐ 和 Eloquent 最根本的区别

  • Eloquent:一个 Model 类既有数据又有操作方法。$user->name 读属性,$user->save() 写数据库,都在一个类上。
  • MyBatis-Plus:Entity 只有数据(字段 + getter/setter),CRUD 操作在 Mapper 上。数据和操作分离

这个区别来自于设计模式:Eloquent 是 Active Record(一个对象 = 一行数据 + 操作),MyBatis-Plus 是 Data Mapper(数据对象和持久化逻辑分离)。没有谁更好,只是不同的设计哲学。

面向 PHP 开发者的 Spring Boot 文档