【抽丝剥茧知识讲解】引入mybtis-plus后,mapper实现方式

发布于:2025-05-16 ⋅ 阅读:(21) ⋅ 点赞:(0)

前言

mapper文件,作为Mybatis框架中定义SQL语句和映射关系的配置文件,在引入mybtis-plus后,有了更多的实现方式,本文对此做一个对比总结。

一、传统 Mapper 接口方式

先重温一下原始Mybatis的实现方式,以下所有方式均以用户类 User 作为实体类

  • 定义Mapper接口 :为每个实体类创建对应的 Mapper 接口,接口中声明所需的数据库操作方法。例如,针对用户实体类 User,创建 UserMapper 接口。
@Mapper
public interface UserMapper {
    // 自定义方法
    List<User> selectAllUsers();
}
  • 实现Mapper接口 :通常使用 MyBatis 的注解或 XML 配置文件来实现接口中的方法。对于简单方法,可以使用注解;对于复杂查询,使用 XML 配置。
@Select("SELECT * FROM user")
List<User> selectAllUsers();

或者在 UserMapper.xml 文件中配置:

<select id="selectAllUsers" resultType="com.example.entity.User">
    SELECT * FROM user
</select>
  • 优点 :开发人员对数据库操作有较高的控制度,能够灵活地定义各种复杂的 SQL 查询;适合处理复杂的业务场景,尤其是涉及到多表关联等复杂操作时。
  • 缺点 :需要为每个实体类编写对应的 Mapper 接口和实现代码,当实体类较多时,工作量较大;代码重复性较高,对于简单的 CRUD 操作,需要重复编写类似的接口方法。
  • 适用场景 :适用于业务逻辑复杂、需要精确控制数据库操作的项目,尤其是涉及到大量自定义 SQL 查询的场景。

二、继承 BaseMapper 的方式

这是 MyBatis-Plus 提供的一种简化方式,利用其内置的通用 Mapper 接口来快速实现常见的数据库操作。

  • 定义Mapper接口 :让自定义的 Mapper 接口继承 MyBatis-Plus 提供的 BaseMapper 接口。这样就可以直接使用 BaseMapper 中定义的通用的增删改查方法。
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 可以添加自定义的其他方法
}
  • 使用通用方法 :通过继承 BaseMapper,可以直接使用如 insert()(插入)、deleteById()(根据 ID 删除)、updateById()(根据 ID 更新)、selectById()(根据 ID 查询)、selectList()(查询列表)等方法,无需自己实现。
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public void addUser(User user) {
        userMapper.insert(user);
    }

    public User getUserById(Long id) {
        return userMapper.selectById(id);
    }
}
  • 优点 :极大地简化了代码编写,减少了重复代码;对于简单的 CRUD 操作,开发效率显著提高。
  • 缺点 :对于一些复杂的查询和操作,可能需要结合自定义的 SQL 来实现,此时需要在继承 BaseMapper 的基础上扩展自定义方法。
  • 适用场景 :适用于对实体类进行简单的增删改查操作的场景,能够快速开发出基本的数据访问功能。

三、自定义通用 Mapper 的方式

如果对 MyBatis-Plus 的默认 BaseMapper 提供的方法不满意,或者需要在多个项目中复用自定义的通用 Mapper,可以自定义通用 Mapper。

  • 创建自定义通用Mapper接口 :定义一个接口,例如 MyBaseMapper,并根据需求定义通用的方法。
public interface MyBaseMapper<T> {
    int insertBatchSomeColumn(List<T> entityList);
    List<T> selectByCustomCondition(Map<String, Object> params);
}
  • 实现自定义通用Mapper :可以通过继承 MyBatis-Plus 的 BaseMapper 并实现自定义接口,或者完全自己实现通用方法。
public class MyBaseMapperImpl<T> extends BaseMapper<T> implements MyBaseMapper<T> {
    @Override
    public int insertBatchSomeColumn(List<T> entityList) {
        // 自定义实现逻辑
    }

    @Override
    public List<T> selectByCustomCondition(Map<String, Object> params) {
        // 自定义实现逻辑,可以使用 MyBatis 的注解或 XML 配置
    }
}
  • 使用自定义通用Mapper :让具体的 Mapper 接口继承自定义的通用 Mapper 接口。
@Mapper
public interface UserMapper extends MyBaseMapper<User> {
}
  • 优点 :可以根据项目需求灵活定制通用的数据库操作方法,提高代码的可复用性和可维护性。
  • 缺点 :需要花费一定的时间进行自定义通用 Mapper 的设计和实现,增加了开发的初始工作量;如果设计不合理,可能会影响后续的使用和扩展。
  • 适用场景 :适用于有特殊数据库操作需求,或者需要在多个项目中共享通用 Mapper 的情况。

四、使用 MyBatis-Plus 的 ActiveRecord 模式

这种方式让实体类本身承担数据访问的职责,无需编写 Mapper 接口。

  • 实体类继承 Model :实体类继承 MyBatis-Plus 的 Model 类,并实现相关的主键指定方法。
public class User extends Model<User> {
    private Long id;
    private String name;
    private Integer age;
}
  • 使用实体类进行数据操作 :通过实体类的实例直接调用数据访问方法,如 insert()delete()update()selectById() 等。
@Service
public class UserService {
    public void addUser(User user) {
        user.insert();
    }

    public User getUserById(Long id) {
        return User.selectById(id);
    }
}
  • 优点 :减少了 Mapper 接口的编写工作,使代码更加简洁;对于简单的 CRUD 操作,开发效率较高。
  • 缺点 :实体类承担了过多的数据访问职责,导致类的职责不清晰;在处理复杂的业务逻辑和多表关联时,代码的可维护性和可读性较差。
  • 适用场景 :适用于小型项目或快速原型、本地应用开发,主要用于简单的数据操作场景。

五、使用 MyBatis-Plus 的 IService 接口

这种方式结合了 MyBatis-Plus 的 Mapper 和 Service 层的通用接口,提供更丰富的预设方法。

  • 定义Mapper接口继承 BaseMapper :和前面提到的继承 BaseMapper 的方式一样,为实体类创建对应的 Mapper 接口。
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
  • 定义 Service 接口继承 IService :让自定义的 Service 接口继承 MyBatis-Plus 提供的 IService 接口,IService 提供了一些常用的业务逻辑方法。
public interface UserService extends IService<User> {
    // 自定义业务逻辑方法
}
  • 实现 Service 接口 :在 Service 实现类中,注入对应的 Mapper 接口,并使用 IService 提供的方法以及自定义的业务逻辑。
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Override
    public void customMethod() {
        // 使用 IService 提供的方法或自定义逻辑
    }
}
  • 优点 : IService中提供的丰富的通用方法,提高开发效率。
  • 缺点 :造成设计层面sql对service的入侵。
  • 适用场景 :适用于小型项目或快速开发项目。

六、使用建议

  1. 小型项目或快速开发项目
    例如个人毕设,单接口服务,简单的管理系统,这种类似一次性开发的项目,当然是怎么快怎么方便怎么来,这时候就十分推荐使用MyBatis-Plus的Model+BaseMapper+IService,可以给开发节省很多时间。
  2. 本地应用或脚本
    例如在本地做数据处理,开发数据引擎,这时候实际上是没有mvc那一说法的,因为大量的操作就是操作数据,使用ActiveRecord模式不会有太大的负面印象,复杂的操作使用QueryWrapperLambdaQueryWrapper,Model类里面也有对应的方法。
  3. 中型项目但是人少
    国内大部分是中小企业,开发人员就五六个,相比于耦合带来的问题,开发进度更重要一些,使用BaseMapper+IService就好,AR模式对业务的侵入还是大了些。
  4. 大型项目最优实践
    创建自己的MyBaseMapper,继承MyBatis-Plus的BaseMapper,在这里编写公共方法,例如IService提供的一些批量处理方法,所有的mapper接口再继承MyBaseMapper

关于sql怎么写:
单表的简单操作直接用BaseMapper提供的方法
单表的复杂操作使用QueryWrapperLambdaQueryWrapper进行组装
多表的简单联查使用mybatis的注解在mapper接口中
多表的复杂联查在mapper.xml中编写


网站公告

今日签到

点亮在社区的每一天
去签到