SpringBoot MybatisPlus配置介绍,篇幅较长 坚持看下来 你肯定会有所收获!!!
以下配置项可以根据你的实际需求进行调整和配置。id-type请注意,其中一些配置项可能需要自定义的类或接口来实现相应的功能,如自定义的逻辑删除SQL注入器和元对象处理器
mybatis-plus: # 指定Mapper XML文件的位置,使用classpath通配符指定路径。 mapper-locations: classpath*:mapping/*Mapping.xml # 指定实体类的包路径,用于自动扫描并注册类型别名。 type-aliases-package: com.zskx.service.card.model.* # 全局配置 global-config: db-config: #id-type: ID_WORKER # 主键ID的生成策略,可选值包括:AUTO、NONE、INPUT、ID_WORKER、UUID id-type: AUTO #机器 ID 部分(影响雪花ID) workerId: 1 #数据标识 ID 部分(影响雪花ID)(workerId 和 datacenterId 一起配置才能重新初始化 Sequence) datacenterId: 18 # 字段验证策略,可选值包括:not_null、not_empty、default field-strategy: not_empty #驼峰下划线转换(将数据库字段的下划线命名规则转换为 Java 实体类属性的驼峰命名规则) db-column-underline: true #刷新mapper 调试神器 refresh-mapper: true #数据库大写下划线转换 #capital-mode: true #序列接口实现类配置 #key-generator: com.baomidou.springboot.xxx #逻辑删除配置(下面3个配置) logic-delete-field: deleted # 逻辑删除字段名 logic-delete-value: 1 # 逻辑删除字段的值表示已删除 logic-not-delete-value: 0 # 逻辑删除字段的值表示未删除 #自定义SQL注入器 #sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector #自定义填充策略接口实现 #meta-object-handler: com.baomidou.springboot.xxx configuration: # 将 Java 实体类属性的驼峰命名规则转换为数据库字段的下划线命名规则 map-underscore-to-camel-case: true # 是否开启二级缓存。 cache-enabled: false # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
id-type用于配置主键ID的生成策略,有效的选项是字符串类型,代表了不同的主键ID生成策略。以下是mybatis-plus.global-config.db-config.id-type的有效选项:
用于在 分布式环境 下生成唯一的主键ID
在雪花算法(Snowflake)中,主键生成的一部分是由机器ID组成的。这个机器ID用于在分布式环境中唯一标识不同的机器或节点。具体说明如下:
雪花算法是一种用于生成分布式环境下唯一ID的算法,它的生成规则如下:
其中,机器ID部分在雪花算法中是为了在分布式环境下保证每个机器生成的ID的唯一性。
在 MyBatis-Plus 中配置 workerId 的含义与雪花算法的机器ID部分保持一致。具体意义如下:
总而言之,配置 workerId 在 MyBatis-Plus 中是为了保证分布式系统中生成的ID具有全局唯一性、有序性和可扩展性。它确保每个节点生成的ID都是唯一的,可以按照时间顺序排序,并且能够适应系统的动态变化。
在雪花算法(Snowflake)中,数据标识ID(datacenterId)是用于区分不同数据中心或数据区域的标识符。它是雪花算法中生成的唯一ID的一部分。以下是对datacenterId的解释:
需要注意的是,datacenterId的分配需要保证在整个系统中是唯一的,并且每个数据中心或数据区域都应该有一个独特的标识符。这样可以确保生成的ID在分布式环境中是唯一且可识别的。
当配置 MyBatis-Plus 的字段验证策略时,你可以指定是否要验证实体类中的字段的非空约束。这个验证策略可以帮助确保在插入或更新数据时,特定字段的值不能为空。
以下是字段验证策略的选项及其含义:
通过设置字段验证策略,你可以根据业务需求决定是否对实体类中的特定字段进行非空约束的验证。这有助于在数据插入或更新过程中保持数据的完整性,避免插入或更新不完整的记录。
假设你有一个实体类User,其中包含了id、username和email三个字段,并且你想要对username和email字段进行非空约束的验证。
首先,在实体类中使用注解来标记字段的非空约束:
public class User { @TableId(type = IdType.AUTO) private Long id; @NotEmpty(message = "用户名不能为空") private String username; @NotEmpty(message = "邮箱不能为空") private String email; // 省略其他字段和方法 }
在上述示例中,我们使用了@NotEmpty注解来标记username和email字段的非空约束。
接下来,在 MyBatis-Plus 的配置文件中设置字段验证策略:
mybatis-plus: global-config: db-config: field-strategy: not_empty
在这个示例中,我们将字段验证策略设置为not_empty,表示对标记了非空约束的字段进行非空验证。如果插入或更新数据时,username和email字段为空或空字符串,将触发异常。
现在,当你使用 MyBatis-Plus 进行数据插入或更新操作时,会自动进行字段的非空约束验证。如果违反了非空约束,将会抛出异常,并提示相应的错误消息。
field-strategy是MyBatis-Plus中全局的字段策略配置,用于指定字段的验证策略,包括是否验证字段的非空约束。它和注解(此注解非彼注解@TableField)可以一起使用,但并不是必须的。
具体来说,field-strategy的配置值有以下三种选项:
当你在全局配置中设置了field-strategy后,它会成为默认的字段验证策略,适用于所有的实体对象和数据库操作。
然而,你也可以在具体的实体类中使用注解来覆盖全局配置。例如,使用@TableField注解的strategy属性可以指定该字段的验证策略,覆盖全局配置的field-strategy。
如果在实体类中使用了注解来设置字段的验证策略,则会优先使用注解中的配置。如果没有使用注解,则会使用全局配置中的field-strategy。
因此,field-strategy的全局配置和注解可以一起使用,但注解是可选的,并且可以用于覆盖全局配置,以实现更细粒度的字段验证策略。
map-underscore-to-camel-case 和 db-column-underline 是 MyBatis-Plus 中用于处理数据库字段和 Java 实体类属性之间命名规则的配置选项,它们有一定的区别与联系。
区别与联系:
它们的联系在于都涉及到数据库字段和 Java 实体类属性之间的命名规则转换,但转换方向和目的不同。
refresh-mapper是MyBatis-Plus的一个全局配置选项,用于控制是否在每次进行数据库操作时刷新Mapper。这个选项主要用于开发和调试阶段,可以帮助实时更新Mapper的SQL语句,方便调试和查看执行的SQL。
具体来说,当设置refresh-mapper为true时,每次执行数据库操作(如插入、更新、删除、查询)时,MyBatis-Plus会重新解析Mapper接口的SQL语句,并将最新的SQL语句应用到数据库操作中。这样可以确保在调试期间,使用最新的SQL语句进行数据库操作,而不会使用缓存的SQL语句。
假设你有一个UserMapper接口定义了数据库操作方法,例如:
public interface UserMapper extends BaseMapper{ // ... }
在配置文件中,你可以将refresh-mapper设置为true,如下所示:
mybatis-plus: global-config: refresh-mapper: true
当你进行数据库操作时,例如查询用户列表:
@Autowired private UserMapper userMapper; public ListgetUserList() { return userMapper.selectList(null); }
在开启了refresh-mapper的情况下,每次调用getUserList方法时,MyBatis-Plus会重新解析UserMapper接口的SQL语句,并使用最新的SQL语句执行查询操作。
在开发和调试阶段,如果你修改了Mapper接口的SQL语句,设置refresh-mapper为true可以确保使用最新的SQL语句进行数据库操作,方便调试和验证SQL语句的正确性。
需要注意的是,refresh-mapper在生产环境中应该设置为false,以避免不必要的性能开销。
当你使用 MyBatis-Plus 进行逻辑删除时,你可以通过配置逻辑删除字段名来指定用于逻辑删除的字段。
下面是一个使用示例:
假设你有一个实体类User,其中包含了id、username和status三个字段,并且你想要使用status字段作为逻辑删除字段,其中逻辑删除的值可以为1或2。
首先,在实体类中添加一个名为status的字段,并在该字段上使用注解来标记它作为逻辑删除字段:
public class User { @TableId(type = IdType.AUTO) private Long id; private String username; @TableLogic(value = "1,2") private Integer status; // 省略其他字段和方法 }
在上述示例中,我们在status字段上使用了@TableLogic注解,并通过value属性设置了逻辑删除的值为1,2,即1和2都表示逻辑删除。
接下来,在 MyBatis-Plus 的配置文件中配置逻辑删除字段的相关配置:
mybatis-plus: global-config: db-config: logic-delete-field: status logic-delete-value: 1,2 logic-not-delete-value: 0
在这个示例中,我们将逻辑删除字段名设置为status,并通过logic-delete-value属性设置逻辑删除的值为1,2,通过logic-not-delete-value属性设置未逻辑删除的值为0。
现在,当你使用 MyBatis-Plus 进行逻辑删除操作时,会自动更新status字段的值,以实现逻辑删除的效果。查询操作也会自动过滤掉被逻辑删除的记录。
假设你有一个名为UserMapper的 MyBatis 接口,使用 MyBatis-Plus 提供的方法进行逻辑删除和查询操作。
public interface UserMapper extends BaseMapper{ }
在这个示例中,UserMapper继承了BaseMapper
现在,假设你要执行逻辑删除操作,可以通过调用 MyBatis-Plus 提供的方法来实现:
@Autowired private UserMapper userMapper; public void logicDeleteUser(Long id) { //逻辑删除方法 int rows = userMapper.deleteById(id); System.out.println("逻辑删除了 " + rows + " 条记录"); }
在上述示例中,通过调用userMapper.deleteById(id)方法,MyBatis-Plus 会自动更新逻辑删除字段的值,并将指定id的记录标记为逻辑删除(更新成为逻辑删除的值)。
对于查询操作,MyBatis-Plus 会自动过滤掉被逻辑删除的记录。例如,如果你执行以下查询方法:
public ListgetAllUsers() { QueryWrapper queryWrapper = new QueryWrapper<>(); List userList = userMapper.selectList(queryWrapper); return userList; }
在上述示例中,selectList(queryWrapper)方法会返回所有未被逻辑删除的User对象的列表。即使在数据库中存在已被逻辑删除的记录(值为配置文件指定的逻辑删除值),它们不会包含在返回的列表中。
这个示例演示了当使用 MyBatis-Plus 进行逻辑删除操作时的效果。通过调用相应的方法,MyBatis-Plus会自动更新逻辑删除字段的值,并在查询操作中自动过滤掉被逻辑删除的记录,简化了逻辑删除的实现过程。
logic-delete-field 是 MyBatis-Plus 的全局配置选项,用于指定用于逻辑删除的字段名。它表示在数据库表中用于标识逻辑删除的字段。
logic-delete-field 需要和注解一起使用,以告知 MyBatis-Plus 在进行逻辑删除操作时应该使用哪个字段来标识被逻辑删除的数据。
一般情况下,你需要在实体类的相应字段上使用注解来标识逻辑删除字段,例如使用 @TableLogic 注解。同时,在 MyBatis-Plus 的全局配置中设置 logic-delete-field 为该字段的名称。
示例:
import com.baomidou.mybatisplus.annotation.TableLogic; public class User { private Long id; @TableLogic private Integer deleted; // 省略其他属性和方法 }
在上述示例中,User 类中的 deleted 字段使用了 @TableLogic 注解来标识逻辑删除字段。而在 MyBatis-Plus 的全局配置中,你需要设置 logic-delete-field 的值为 deleted。
mybatis-plus: global-config: db-config: logic-delete-field: deleted
通过以上配置,MyBatis-Plus 在进行逻辑删除操作时,会使用 deleted 字段作为逻辑删除字段。
**需要注意的是,logic-delete-field 配置项和注解需要配合使用,以确保 MyBatis-Plus 正确识别逻辑删除字段。**同时,你也可以通过其他的注解或配置方式来指定逻辑删除字段,具体根据你使用的注解或框架的要求而定。
log-impl 是 MyBatis-Plus 的全局配置选项,用于指定日志的实现类。具体而言,log-impl 的值用于指定用于日志记录的具体实现类。
在你提供的配置中,log-impl 的值为 org.apache.ibatis.logging.stdout.StdOutImpl,它表示将日志输出到控制台(标准输出)。这意味着 MyBatis-Plus 在执行数据库操作时,会将相应的日志信息打印到控制台上。
通过将日志输出到控制台,你可以方便地查看和监控 MyBatis-Plus 执行的数据库操作以及相关的日志信息。这在开发和调试过程中非常有用,可以帮助你追踪和分析数据库操作的执行情况。
示例配置:
mybatis-plus: global-config: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
通过以上配置,你告诉 MyBatis-Plus 使用 org.apache.ibatis.logging.stdout.StdOutImpl 作为日志实现类,从而将日志输出到控制台。
需要注意的是,你也可以使用其他的日志实现类来记录 MyBatis-Plus 的日志,例如使用 log4j、slf4j 等日志框架的实现类。根据你的实际需求和项目的日志配置,你可以选择适合的日志实现类来记录 MyBatis-Plus 的日志。
sql-injector 是 MyBatis-Plus 的全局配置选项,用于指定自定义的逻辑删除SQL注入器。逻辑删除是一种常见的数据删除方式,通过在数据库中设置一个特定的字段值来表示数据被逻辑删除而不是物理删除。
在 MyBatis-Plus 中,默认提供了一个逻辑删除的实现方式,但有时你可能需要根据自己的业务需求来自定义逻辑删除的行为。这时,你可以通过实现自定义的逻辑删除SQL注入器来达到目的。
自定义的逻辑删除SQL注入器需要实现 com.baomidou.mybatisplus.core.injector.ISqlInjector 接口,并提供相应的逻辑删除SQL语句。在配置文件中,你可以通过 sql-injector 配置项指定你自定义的逻辑删除SQL注入器。
示例配置:
mybatis-plus: global-config: sql-injector: com.example.MyLogicSqlInjector
在上述配置中,sql-injector 的值为 com.example.MyLogicSqlInjector,表示你自定义的逻辑删除SQL注入器的类名。
通过自定义逻辑删除SQL注入器,你可以定义自己的逻辑删除SQL语句,包括设置逻辑删除字段的值、更新逻辑删除字段的SQL操作等。这样,在执行逻辑删除操作时,MyBatis-Plus 将使用你提供的自定义逻辑删除SQL语句来实现逻辑删除的行为。
需要注意的是,自定义逻辑删除SQL注入器需要符合 MyBatis-Plus 的规范和接口要求,并提供正确的逻辑删除SQL语句。具体的实现方式和SQL语句根据你的业务需求而定。
meta-object-handler 是 MyBatis-Plus 的全局配置选项,用于指定自定义的元对象处理器(Meta Object Handler)。
元对象处理器是一种用于处理实体类的元对象(Meta Object)的回调接口,可以在插入、更新等数据库操作前后对实体类进行额外的处理。
通过实现 com.baomidou.mybatisplus.core.handlers.MetaObjectHandler 接口,你可以自定义元对象处理器,并在全局配置中指定该处理器的类名。
自定义的元对象处理器需要实现接口中的方法,包括 insertFill 和 updateFill 等方法,用于在插入和更新操作时对实体类的属性进行填充。
示例配置:
mybatis-plus: global-config: meta-object-handler: com.example.MyMetaObjectHandler
在上述配置中,meta-object-handler 的值为 com.example.MyMetaObjectHandler,表示你自定义的元对象处理器的类名。
通过自定义元对象处理器,你可以在进行数据库操作之前或之后对实体类进行一些额外的处理,例如自动填充创建时间和更新时间等属性,实现审计功能等。具体的处理逻辑和操作可以根据你的业务需求而定。
需要注意的是,自定义的元对象处理器需要符合 MyBatis-Plus 的规范和接口要求,并提供正确的处理逻辑。同时,在配置文件中指定的类名需要和你自定义的处理器类的完整路径一致
当你配置了自定义的元对象处理器(MyMetaObjectHandler)后,你可以在该处理器中实现对实体类属性的填充。以下是一个示例:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 在插入操作时进行属性填充 this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class); this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); } @Override public void updateFill(MetaObject metaObject) { // 在更新操作时进行属性填充 this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); } }
在上述示例中,我们定义了一个 MyMetaObjectHandler 类,实现了 MetaObjectHandler 接口。在 insertFill 和 updateFill 方法中,我们可以编写填充逻辑。
在 insertFill 方法中,使用 this.strictInsertFill 方法填充 createTime 和 updateTime 属性,将其设置为当前时间(使用 LocalDateTime::now 方法)。
在 updateFill 方法中,使用 this.strictUpdateFill 方法填充 updateTime 属性,同样设置为当前时间。
接下来,在全局配置文件中指定使用该自定义的元对象处理器:
mybatis-plus: global-config: meta-object-handler: com.example.MyMetaObjectHandler
通过以上配置,MyBatis-Plus 将使用 MyMetaObjectHandler 类作为元对象处理器,在插入和更新操作时自动填充相应的属性值。
需要注意的是,自定义的元对象处理器需要根据实际需求编写填充逻辑,可以根据业务需要设置不同的属性值。
在上述示例中,自定义的元对象处理器会对全局的数据库表生效。也就是说,对于所有的实体类,不管是哪个表,都会应用元对象处理器中定义的插入填充和更新填充逻辑。
**如果某个表中没有指定 createTime 和 updateTime 字段,MyBatis-Plus 会在执行插入和更新操作时跳过对这些字段的填充。**也就是说,它不会引发错误或异常,而是直接执行数据库操作而忽略那些未定义的字段。
这种行为是因为 MyBatis-Plus 的元对象处理器是对实体类进行填充操作的,而不是直接与数据库表进行关联。它会根据实体类中定义的字段与数据库表进行对应关系的映射,然后进行填充操作。如果某个字段在实体类中不存在或未定义,元对象处理器会自动跳过该字段的填充。
因此,在使用自定义的元对象处理器时,你可以根据不同的表和实体类来定义不同的填充逻辑。对于没有指定 createTime 和 updateTime 字段的表,MyBatis-Plus 会直接执行数据库操作,而不会进行填充操作。
当使用自定义的元对象处理器时,你可以针对不同的表和实体类定义不同的填充逻辑。这样,你可以根据具体的业务需求,在不同的表和实体类中实现特定的填充行为
下面是一个示例,展示如何根据不同的表和实体类定义不同的填充逻辑:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 获取当前实体类的类名 String className = metaObject.getOriginalObject().getClass().getSimpleName(); if ("User".equals(className)) { // 如果是 User 实体类,则进行特定的填充逻辑 this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class); this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); } else if ("Order".equals(className)) { // 如果是 Order 实体类,则进行另一种填充逻辑 this.strictInsertFill(metaObject, "createTime", LocalDate::now, LocalDate.class); } } @Override public void updateFill(MetaObject metaObject) { // 获取当前实体类的类名 String className = metaObject.getOriginalObject().getClass().getSimpleName(); if ("User".equals(className)) { // 如果是 User 实体类,则进行特定的填充逻辑 this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); } else if ("Order".equals(className)) { // 如果是 Order 实体类,则进行另一种填充逻辑 this.strictUpdateFill(metaObject, "updateTime", LocalDate::now, LocalDate.class); } } }
在上述示例中,我们通过获取当前实体类的类名,判断当前操作的是哪个实体类。然后根据不同的实体类来实现不同的填充逻辑。
对于 User 实体类,我们使用 LocalDateTime 类型的当前时间填充 createTime 和 updateTime 字段。而对于 Order 实体类,我们使用 LocalDate 类型的当前日期填充 createTime 字段。
通过这种方式,你可以根据不同的表和实体类来定义特定的填充逻辑,满足不同的业务需求。
根据不同的表和实体类定义不同的填充逻辑,从性能的角度来看,可能会产生一些微小的影响,但通常不会对数据库的性能产生显著的影响。
在填充逻辑中,主要涉及对实体类的属性进行赋值操作。这些赋值操作通常是基于内存中的对象进行的,而不涉及直接的数据库操作。因此,这些填充逻辑的性能开销通常较小,并不会对数据库的性能产生重大影响。
但是,如果你在填充逻辑中进行了复杂的业务计算或涉及大量的数据库查询操作,可能会对性能产生一定的影响。在这种情况下,建议进行性能测试和优化,以确保填充逻辑不会成为性能瓶颈。
此外,还要注意在使用自定义的元对象处理器时,合理选择填充的字段和操作的时机。避免在不必要的时候进行填充操作,以减少不必要的开销。
总的来说,对于一般的填充逻辑,根据不同的表和实体类定义不同的填充逻辑通常不会对数据库的性能产生显著的影响。但对于复杂的填充逻辑,需要谨慎设计和测试,以确保性能的可接受性。