从数据库取出来的code转换成枚举

本文介绍了如何将从数据库获取的code值转换为枚举类型,包括三个步骤:首先创建CodeEnum类作为基础,然后定义具体的枚举类,最后实现工具类以方便在业务中进行转换操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.第一步:书写CodeEnum类

public interface CodeEnum{    
   Integer getCode();
}

2.第二步:书写枚举类

public enum OrderStatusEnum implements CodeEnum{

NEW(0,"新订单"),
FINISH(1,"完结"),
CANCEL(2,"已取消");

private Integer code;

private String message;

OrderStatusEnum(Integer code, String message) {
    this.code = code;
    this.message = message;
}

public Integer getCode() {
    return code;
}

public void setCode(Integer code) {
    this.code = code;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}
}

第三步:书写工具类

//通过code来获得枚举,T代表枚举,书写的公共类  <T extends CodeEnum>这表达类,表示不确定的东西,像Interface/class
public class EnumUtil {
    public static <T extends CodeEnum> T getByCode(Integer code, Class<T> enumClass) {
        for (T each : enumClass.getEnumConstants()) {
            if (code.equals(each.getCode())) {
                return each;
            }
        }
        return null;
    }

}


 

 

 

 

 

<think>我们正在处理一个关于将枚举code值(而不是label)插入数据库的问题。根据用户描述,当前插入的是枚举的label,而他们希望插入的是code。解决方案思路:1.枚举通常包含两个属性:code(通常用于存储和传输的编码)和label(用于显示的文本)。2.在Java中,我们可能会使用枚举类型,并在插入数据库时获取枚举code值。3.在MyBatis中,我们可以通过自定义类型处理器(TypeHandler)来处理枚举类型的转换,确保插入和读取时使用code值。步骤: a.创建一个枚举类型,例如:publicenum Role{ADMIN(1,"管理员"),USER(2,"普通用户");privatefinal intcode;privatefinal Stringlabel;Role(int code, Stringlabel){this.code= code;this.label= label;}public intgetCode() {returncode;}publicString getLabel(){return label;}} b.创建自定义的TypeHandler,用于处理枚举类型数据库字段的转换(将枚举code值存入数据库,从数据库读取时根据code值转换为枚举实例)。c.在MyBatis的映射文件中,指定使用该TypeHandler。具体实现:1.自定义TypeHandler(以Integer类型的code为例):```javaimportorg.apache.ibatis.type.BaseTypeHandler;importorg.apache.ibatis.type.JdbcType;importjava.sql.CallableStatement;import java.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclass EnumCodeTypeHandler<Eextends Enum<E>& CodeEnum>extends BaseTypeHandler<E>{private Class<E>type;publicEnumCodeTypeHandler(Class<E>type){if (type ==null){throw newIllegalArgumentException("Type argumentcannot benull");}this.type =type;}@Overridepublicvoid setNonNullParameter(PreparedStatementps,int i, Eparameter,JdbcType jdbcType) throwsSQLException{//获取枚举code值,并设置到PreparedStatement中ps.setInt(i,parameter.getCode());}@OverridepublicE getNullableResult(ResultSet rs, StringcolumnName) throwsSQLException{int code= rs.getInt(columnName);returnrs.wasNull() ?null :codeOf(type, code);}@Overridepublic EgetNullableResult(ResultSetrs,int columnIndex)throws SQLException {intcode =rs.getInt(columnIndex);return rs.wasNull()? null: codeOf(type, code);}@Overridepublic EgetNullableResult(CallableStatement cs, intcolumnIndex) throwsSQLException{int code= cs.getInt(columnIndex);returncs.wasNull() ?null :codeOf(type,code);}privateE codeOf(Class<E> enumClass,int code) {E[] enumConstants =enumClass.getEnumConstants();for(Ee :enumConstants) {if(e.getCode() ==code){return e;}}return null;}}```注意:这里我们假设枚举实现了`CodeEnum`接口,该接口定义如下:```javapublic interfaceCodeEnum{int getCode();}```然后让枚举实现这个接口:```javapublic enumRole implementsCodeEnum{// ...同上}```2.在MyBatis配置中注册该TypeHandler,或者在映射文件中指定。方式一:在MyBatis配置文件中注册(mybatis-config.xml):```xml<typeHandlers><typeHandler handler="com.example.EnumCodeTypeHandler" javaType="com.example.Role"/></typeHandlers>```方式二:在映射文件中指定(推荐,因为这样更灵活):```xml<resultMapid="roleMap" type="com.example.Role"><!--其他字段映射--><resultcolumn="role_code"property="role"typeHandler="com.example.EnumCodeTypeHandler"/></resultMap><!--在插入语句中指定typeHandler --><insert id="insertRole">INSERTINTO role_table (role_code)VALUES(#{role,typeHandler=com.example.EnumCodeTypeHandler})</insert>```3.这样,当执行插入操作时,MyBatis就会使用我们自定义的TypeHandler将枚举code值插入数据库,而不是使用枚举的名称(label)或默认的ordinal(序号)。另外,如果不想使用TypeHandler,也可以在获取枚举后直接使用其code值,然后在SQL中直接使用这个code值(比如在Java代码中获取枚举code,然后作为参数传入SQL)。但是这样每个需要的地方都要手动处理,而使用TypeHandler可以一劳永逸。根据引用[1]中的日志,我们看到每次insertRole方法调用都会创建一个新的SqlSession,这符合MyBatis的常规操作,不会影响我们的解决方案。引用[2]中提到的是Python中的操作,但用户的问题似乎是Java环境,所以我们主要提供Java的解决方案。如果用户使用的是SpringBoot +MyBatis,还可以通过配置扫描来注册TypeHandler,例如:```java@Configurationpublic classMyBatisConfig{@Beanpublic ConfigurationCustomizermybatisConfigurationCustomizer(){return configuration-> {configuration.getTypeHandlerRegistry().register(Role.class,new EnumCodeTypeHandler<>(Role.class));};}}```总结:通过自定义TypeHandler,我们可以控制枚举类型数据库中的存储形式(存储code值),从而满足需求。相关问题:1.如何自定义MyBatis的TypeHandler?2.在MyBatis中处理枚举类型有哪些方式?3.除了TypeHandler,还有哪些方法可以将枚举code值插入数据库?</think>### 解决方案:将枚举code值插入数据库 要解决枚举值插入数据库时使用编码(code)而非标签(label)的问题,可通过以下两种方法实现(以Java/MyBatis为例): #### 方法一:在代码层手动转换(推荐) **步骤:** 1. **获取枚举code值** 在调用数据库操作前,通过枚举的`getCode()`方法获取编码值 ```java // 枚举定义示例 public enum UserRole { ADMIN(1, "管理员"), USER(2, "普通用户"); private final int code; private final String label; UserRole(int code, String label) { this.code = code; this.label = label; } public int getCode() { return code; } public String getLabel() { return label; } } // 业务层调用 UserRole role = UserRole.ADMIN; int roleCode = role.getCode(); // 获取编码值 1 ``` 2. **将code值作为参数传入SQL** 在Mapper接口中直接使用`int`类型参数: ```xml <!-- MyBatis映射文件 --> <insert id="insertRole"> INSERT INTO user_roles(role_code) VALUES (#{roleCode}) <!-- 直接使用基础类型 --> </insert> ``` #### 方法二:自定义MyBatis类型处理器(TypeHandler) **步骤:** 1. **创建自定义TypeHandler** 继承`BaseTypeHandler`并重写方法: ```java public class EnumCodeTypeHandler<E extends Enum<E> & CodeEnum> extends BaseTypeHandler<E> { @Override public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) { ps.setInt(i, parameter.getCode()); // 写入code值到数据库 } // 其他重写方法(getNullableResult)处理查询结果... } // 枚举需实现接口 public interface CodeEnum { int getCode(); } ``` 2. **配置TypeHandler** 在MyBatis配置中注册处理器: ```xml <!-- mybatis-config.xml --> <typeHandlers> <typeHandler handler="com.example.EnumCodeTypeHandler" javaType="com.example.UserRole"/> </typeHandlers> ``` 3. **Mapper中直接使用枚举类型** MyBatis会自动转换: ```xml <insert id="insertRole"> INSERT INTO user_roles(role_code) VALUES (#{role}) <!-- 自动调用TypeHandler --> </insert> ``` ### 关键区别 | 方法 | 优点 | 适用场景 | |--------------|-----------------------------|------------------------| | 手动转换code | 简单直接,无需配置 | 少量枚举字段 | | TypeHandler | 一劳永逸,保持代码整洁 | 项目中有大量枚举字段使用 | ### 注意事项 1. **防御SQL注入** 使用`#{}`语法(如`#{roleCode}`)可自动参数化查询,避免注入风险[^2]。 2. **事务管理** 确保在`@Transactional`注解的方法中执行插入操作以保证数据一致性。 3. **枚举设计规范** 建议枚举始终包含`code`和`label`两个属性,便于扩展: ```java public enum Status { ACTIVE(1, "激活"), INACTIVE(0, "未激活"); // getters... } ``` ### 示例场景 ```java // 业务层代码 public void addUser(User user) { // 方法一:手动转换code int roleCode = user.getRole().getCode(); userDao.insertRole(roleCode); // 方法二:直接传递枚举(需配置TypeHandler) userDao.insertRole(user.getRole()); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值