有关Model:
- 基础概念
- 在 MyBatis - Plus 中,
Model
是一个很重要的抽象类。当实体类继承Model
类后,它会获得一系列方便操作数据库的功能。这些功能主要是基于 MyBatis - Plus 提供的强大的 CRUD(增删改查)操作增强。
- 在 MyBatis - Plus 中,
- 主要优势
- 数据库操作方法继承:继承
Model
类的实体类可以直接使用诸如insert()
、deleteById()
、selectById()
、updateById()
等方法。例如,假设你有一个User
实体类继承自Model
,你可以通过User user = new User();
创建一个用户对象,设置其属性后,直接使用user.insert()
方法将该用户信息插入到数据库中。这比手动编写 SQL 语句或者使用传统的 MyBatis 的 Mapper 接口方法更加简洁高效。 - 自动填充功能支持:如果你的数据库表中有一些字段需要自动填充,比如创建时间、更新时间等,
Model
提供了方便的自动填充机制。你只需要在实体类中通过注解(如@TableField(fill = FieldFill.INSERT_UPDATE)
)来指定字段的填充策略,MyBatis - Plus 就会在插入或更新操作时自动填充这些字段。 - 逻辑删除功能集成:逻辑删除是一种常见的数据库操作策略,通过在表中设置一个标志位(如
is_deleted
字段)来表示记录是否被删除,而不是真正从数据库中物理删除记录。Model
类支持逻辑删除功能,你可以在实体类中通过@TableLogic
注解来指定逻辑删除字段,这样在执行删除操作时,MyBatis - Plus 会自动更新逻辑删除字段的值,而不是执行真正的删除操作。 - 乐观锁功能配合:如果你的数据库操作需要使用乐观锁来处理并发问题,继承
Model
类也能很好地支持这一功能。通过在实体类中设置乐观锁字段(如version
字段),并使用@Version
注解进行标记,MyBatis - Plus 会在更新操作时自动检查和处理乐观锁相关的逻辑,确保数据的一致性。
- 数据库操作方法继承:继承
Model和自定义MetaObjectHandler实现类区别:
- 和
Model
类自动填充功能的相似点- 目的相同:
- 这个
MyMetaObjecthandle
类和Model
类的自动填充功能都是为了在数据库操作过程中自动设置某些字段的值。例如,在插入或更新操作时自动填充创建时间、更新时间等字段,以保证数据的完整性和一致性。它们都在一定程度上减少了手动设置这些字段的工作量,并且遵循相同的业务逻辑需求,即确保这些公共字段在合适的时候被正确赋值。
- 这个
- 目的相同:
- 和
Model
类自动填充功能的不同点- 实现方式不同:
Model
类自动填充(基于框架内部机制):当实体类继承Model
类后,MyBatis - Plus
框架会根据实体类上的注解(如@TableField(fill = FieldFill.INSERT_UPDATE)
)来自动识别需要填充的字段。框架内部有一套自己的机制来触发和执行填充操作,它紧密集成在Model
类以及整个MyBatis - Plus
的持久层操作流程中。MyMetaObjecthandle
自定义实现(手动设置):MyMetaObjecthandle
类是通过实现MetaObjectHandler
接口,然后手动在insertFill
和updateFill
方法中使用metaObject.setValue
方法来设置字段的值。这种方式相对更加灵活,因为你可以完全控制填充的逻辑和过程,但是需要更多的手动代码编写来实现和Model
类自动填充类似的功能。
- 集成程度不同:
Model
类自动填充(深度集成):Model
类的自动填充功能是MyBatis - Plus
持久层框架的一部分,它与Model
类的其他数据库操作功能(如插入、更新、查询等)以及框架的其他特性(如逻辑删除、乐观锁等)紧密结合。例如,在一个完整的MyBatis - Plus
的CRUD
操作中,自动填充功能会在合适的时机自动触发,不需要额外的配置就可以和其他功能协同工作。MyMetaObjecthandle
(相对独立):虽然MyMetaObjecthandle
类实现了自动填充功能,但它相对独立于Model
类。它需要在MyBatis - Plus
的配置中进行额外的配置,告知框架使用这个自定义的MetaObjectHandler
来进行自动填充。例如,需要在MyBatis - Plus
的配置类中添加类似于mybatisPlusInterceptor.addInnerInterceptor(new MetaObjectHandlerInterceptor(myMetaObjecthandle));
(假设MetaObjectHandlerInterceptor
是自定义的拦截器用于应用MetaObjectHandler
)这样的代码来使这个自动填充功能生效。
- 适用范围略有差异:
Model
类自动填充(以实体类为中心):Model
类的自动填充主要是针对继承Model
类的实体类的数据库操作。它的填充逻辑是基于实体类的字段和注解定义的,所以它的适用范围主要是在MyBatis - Plus
持久层中,对实体类相关的数据库操作进行自动填充。MyMetaObjecthandle
(更灵活的通用填充):MyMetaObjecthandle
由于是手动实现的自动填充逻辑,它可以更灵活地应用于一些特殊情况或者非Model
类继承的实体类。例如,如果有一些旧的实体类没有继承Model
类,但是也需要自动填充功能,就可以通过配置使用MyMetaObjecthandle
来实现自动填充。
- 实现方式不同:
Model和使用BaseMapper接口有什么区别:
- 功能特性方面
Model
类- 高级功能集成:当实体类继承
Model
后,它不仅可以进行基本的数据库操作,还集成了如自动填充、逻辑删除和乐观锁等高级功能。例如,对于逻辑删除功能,在实体类中通过@TableLogic
注解标记逻辑删除字段后,使用Model
类的deleteById
方法执行删除操作时,不会真正从数据库中删除记录,而是更新逻辑删除字段的值。 - 面向对象操作:以更面向对象的方式操作数据库。它的方法是基于实体类本身的,例如
model.insert()
方法,从对象层面理解就是将这个模型(实体)插入到数据库中。在这个过程中,会自动考虑实体类配置的各种规则,如自动填充相关字段。
- 高级功能集成:当实体类继承
BaseMapper
接口- 基本数据库操作封装:
BaseMapper
主要提供了基本的数据库操作方法,如insert
、selectById
、selectList
、updateById
、deleteById
等。这些方法更侧重于对 SQL 操作的简单封装,是比较底层的数据库交互方式。例如,selectById
方法会根据传入的主键值生成对应的 SQL 语句(如SELECT * FROM table_name WHERE id =?
)并执行查询操作,返回查询结果。 - 缺乏高级功能集成(原生):在没有额外配置的情况下,
BaseMapper
本身不具备自动填充、逻辑删除和乐观锁这些高级功能。它只是单纯地执行 SQL 操作对应的增删改查功能。不过,在一些复杂的项目中,可以通过自定义拦截器或者其他方式来为BaseMapper
的操作添加类似自动填充这样的功能,但这需要额外的开发工作。
- 基本数据库操作封装:
- 使用方式方面
Model
类- 直接在实体类上操作:因为
Model
类的方法是实体类继承后就可以直接使用的,所以在业务逻辑层(Service 层)可以很方便地直接在实体对象上调用方法。例如,在一个用户服务类中,可以直接通过user.insert()
来插入用户数据,这种方式更符合面向对象的编程习惯,代码看起来更直观。 - 与实体类配置紧密结合:使用
Model
类的方法时,需要关注实体类的配置,如字段上的注解(@TableField
、@TableLogic
等),因为这些配置会影响Model
类方法的执行行为。例如,如果实体类配置了自动填充字段,那么在调用insert
或update
方法时就会自动填充相应的字段。
- 直接在实体类上操作:因为
BaseMapper
接口- 依赖注入使用:
BaseMapper
接口需要在对应的服务类(如UserService
)中通过@Autowired
(或其他依赖注入方式)注入后才能使用。例如,@Autowired private UserMapper userMapper;
,然后通过userMapper.selectById(id)
这样的方式来调用方法。 - SQL 操作思维方式:在使用
BaseMapper
接口时,开发者更多地是从 SQL 操作的角度去思考。例如,在构建查询条件时,可能需要考虑如何使用Wrapper
(条件构造器)来组合条件,以便生成正确的 SQL 查询语句。这种方式相对来说更接近传统的 MyBatis 的使用方式,对于熟悉 SQL 操作的开发者来说比较容易理解。
- 依赖注入使用:
- 性能和效率方面(在简单场景下)
Model
类- 可能存在一定的性能损耗(相对):由于
Model
类的方法会处理很多额外的逻辑,如自动填充、逻辑删除检查等,在一些简单的数据库操作场景下,可能会引入少量的性能损耗。例如,每次插入操作都要检查是否有需要自动填充的字段,这会增加一定的执行时间。不过,在大多数企业级应用场景中,这种性能损耗通常是可以接受的,因为它带来的便利性和功能完整性更为重要。
- 可能存在一定的性能损耗(相对):由于
BaseMapper
接口- 相对高效(简单场景):在只需要执行基本的、没有复杂业务逻辑的数据库操作时,
BaseMapper
接口可能会更高效。因为它只是直接执行 SQL 操作,没有额外的逻辑处理步骤。例如,在一个只需要简单查询数据的接口中,使用BaseMapper
的selectList
方法可以快速地返回结果,而不需要像Model
类那样可能会涉及到自动填充字段的检查等操作。
- 相对高效(简单场景):在只需要执行基本的、没有复杂业务逻辑的数据库操作时,
最后自己总结:
model抽象类有自动填充、逻辑删除、乐观锁等,和自定义MeteObjectHandler差不多,但是没有自定义MeteObjectHandler灵活,填充的值不能设置。model类的方法和实现baseMapper接口相比model给实体类在service层有了对数据库的操作的方法,basemapper有一些相比于model可以填充等等功能的简单方法。减少了对对象的注入比如实现basemapper接口的类。