MyBatis-Plus 中 TypeHandler 的注册问题

MyBatis-Plus 中 TypeHandler 的注册问题

TypeHandler 在 MyBatis-Plus 中不注册是可以的,但需要满足特定条件才能正常工作。以下是详细说明:

1. 不注册 TypeHandler 的可行情况

1.1 通过 @TableField 注解指定

如果只在实体类的特定字段上使用 @TableField(typeHandler = YourTypeHandler.class) 注解,可以不全局注册该 TypeHandler:

@TableName("user")
public class User {
    @TableField(typeHandler = EncryptTypeHandler.class)
    private String phone;
    // 其他字段...
}

1.2 通过 XML 映射文件指定

在 MyBatis XML 映射文件中直接指定 TypeHandler 也可以不注册:

<resultMap id="userResultMap" type="User">
    <result column="phone" property="phone" typeHandler="com.example.EncryptTypeHandler"/>
resultMap>

2. 必须注册 TypeHandler 的情况

以下情况必须显式注册 TypeHandler:

  1. 在 JDBC 类型和 Java 类型之间做全局映射

    // 需要注册才能全局生效
    @MappedTypes(String.class)
    @MappedJdbcTypes(JdbcType.VARCHAR)
    public class EncryptTypeHandler extends BaseTypeHandler<String> {
        // ...
    }
    
  2. 在 MyBatis 配置文件中作为默认处理器

    <typeHandlers>
        <typeHandler handler="com.example.EncryptTypeHandler"/>
    typeHandlers>
    
  3. 在动态 SQL 中通过 typeHandler 属性引用

    @Select("SELECT * FROM user WHERE phone = #{phone, typeHandler=com.example.EncryptTypeHandler}")
    User findByPhone(@Param("phone") String phone);
    

3. 最佳实践建议

  1. 局部使用优先

    • 如果只在少数字段使用,优先通过 @TableField 注解指定
    • 避免不必要的全局注册
  2. 需要全局使用时注册

    @Configuration
    public class MyBatisConfig {
        @Bean
        public ConfigurationCustomizer configurationCustomizer() {
            return configuration -> {
                configuration.getTypeHandlerRegistry().register(EncryptTypeHandler.class);
            };
        }
    }
    
  3. 混合使用策略

    • 通用型 TypeHandler 全局注册
    • 特殊用途的 TypeHandler 局部使用

4. 不注册时的注意事项

  1. 必须提供无参构造函数

    public class EncryptTypeHandler extends BaseTypeHandler<String> {
        public EncryptTypeHandler() {
            // 必须有无参构造
        }
        // ...
    }
    
  2. 依赖注入问题

    • 不注册的 TypeHandler 无法通过 Spring 依赖注入
    • 需要通过静态方式或其他模式获取依赖
  3. 性能影响

    • 不注册的 TypeHandler 每次使用时会创建新实例
    • 注册的 TypeHandler 可以复用实例

5. 示例:不注册但能工作的完整案例

// TypeHandler 实现(有无参构造)
public class EncryptTypeHandler extends BaseTypeHandler<String> {
    private Encryptor encryptor;
    
    public EncryptTypeHandler() {
        // 通过静态方法获取Encryptor
        this.encryptor = EncryptorHolder.getEncryptor();
    }
    // 实现方法...
}

// 实体类使用
@TableName("user")
public class User {
    @TableField(typeHandler = EncryptTypeHandler.class)
    private String phone;
    // ...
}

// 不需要任何注册配置

总结:MyBatis-Plus 中的 TypeHandler 可以不注册,但需要满足特定使用条件。根据实际场景选择是否注册,通常推荐局部使用时无需注册,全局使用时才需要注册。

你可能感兴趣的:(面试题随机刷,mybatis,java)