mybatis 推荐用自定义 typehandler 映射状态枚举,避免硬编码和序号依赖,统一空值处理;需暴露 getcode() 等业务字段,重写四个方法并判空防 npe,优先全局注册,查无匹配值时抛异常而非返回 null。

MyBatis 通过枚举处理器转换状态字段,核心在于**避免硬编码、解耦序号依赖、统一空值处理**。默认的 EnumTypeHandler(按 name)和 EnumOrdinalTypeHandler(按 ordinal)都不够安全——前者易受枚举名变更影响,后者直接绑定定义顺序,一旦调整枚举项位置就会出错。
用自定义 TypeHandler 映射业务状态码
推荐为每个状态枚举实现专属处理器,关键点是让数据库存的是你定义的业务值(如 "DRAFT"、"PUBLISHED" 或数字 101、202),而不是 name 或序号。
- 枚举类需暴露可映射的字段,例如
getCode()或getValue() - 处理器继承
BaseTypeHandler<yourenum></yourenum>,重写四个方法 - 在
setNonNullParameter中写入业务值(如ps.setString(i, enum.getCode())) - 在三个
getNullableResult方法中先判空再查值,找不到时抛明确异常(如IllegalArgumentException("未知状态码: " + code))
注册方式要稳定可靠
别只靠注解临时生效,优先采用全局注册,减少遗漏风险。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- 在 MyBatis 配置类中通过
configuration.getTypeHandlerRegistry().register(YourEnum.class, YourEnumTypeHandler.class)注册 - 或在
mybatis-config.xml的<typehandlers></typehandlers>下声明,指定javaType和handler - 若仅局部使用,可在实体字段上加
@TypeHandler(YourEnumTypeHandler.class),但需确保所有同类型字段都覆盖到
查询结果空值必须主动防御
MyBatis 调用 getNullableResult 时,数据库字段可能为 NULL,而 setNonNullParameter 绝不会传 null —— 这个差异常被忽略,导致 NPE。
- 所有
getNullableResult方法开头加if (code == null) return null; - 查不到匹配枚举值时不要返回
null,而应抛异常,避免静默失败掩盖数据问题 - 如果业务允许数据库存 NULL 并映射为 Java 枚举的某个默认值(如
UNKNOWN),应在of()方法里显式处理
搭配通用接口提升复用性
当系统中枚举较多时,可定义统一接口约束行为,降低重复开发成本。
- 定义接口如
public interface StatusEnum { String getCode(); int getValue(); } - 所有状态枚举实现该接口
- 编写泛型处理器
StatusEnumTypeHandler<t extends statusenum></t>,复用核心逻辑 - 配合通用 Mapper 的
DictTypeHandler(要求实现Dict接口)也能快速落地
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










