【ssm框架】枚举类Enum的应用

通常我们会用一个布尔值来表示状态,比如0表示不通过,1表示通过,然而,许多时候状态并不只有两种,比如在系统中表示毕业论文的答辩状态,通常有正常答辩,争优答辩,延期答辩3种,在数据库中我们使用的是整数来存储,0表示正常答辩,2表示争优答辩,4表示延期答辩,那么如何实现这种对应关系呢?

 

/**
 * @描述: 所有枚举类型都继承此接口,即可自动处理枚举类型的映射
 * @作者:https://github.com/xjs1919/enumhandler
 * @日期:2016-08-09 15:28
 * @版本: v1.0
 */
public interface Identifiable<K> {
    K getId();
}
 
/**
 * @描述: 枚举类型字段的通用处理类
 * @作者:https://github.com/xjs1919/enumhandler
 * @日期:2016-08-09 15:30
 * @版本: v1.0
 */
@Alias("EnumHandler")
public class EnumHandler<E extends Enum<E> &Identifiable<K>, K> extends BaseTypeHandler<E> {
    /**
     * 枚举类型的实际类型
     */
    private Class<E> type;

    public EnumHandler(Class<E>type) {
        if(type == null){
            throw newIllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
    }
    /**
     * 非NULL情况,怎么设参数还得交给不同的子类完成
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public voidsetNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcTypejdbcType) throws SQLException {
        if(jdbcType == null){
            K id = parameter.getId();
            if(id instanceof Integer ||id instanceof Short || id instanceof Character || id instanceof Byte){
                ps.setInt(i,(Integer)id);
            }else if(id instanceofString){
                ps.setString(i,(String)id);
            }else if(id instanceofBoolean){
                ps.setBoolean(i, (Boolean)id);
            }else if(id instanceof Long){
                ps.setLong(i, (Long)id);
            }else if(id instanceofDouble){
                ps.setDouble(i,(Double)id);
            }else if(id instanceofFloat){
                ps.setFloat(i, (Float)id);
            }else{
                throw newRuntimeException("unsupported [id] type of enum");
            }
        }else{
            ps.setObject(i,parameter.getId(), jdbcType.TYPE_CODE);
        }
    }

    /**
     * 根据列名,获取可以为空的记录
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public E getNullableResult(ResultSetrs, String columnName) throws SQLException {
        String s =rs.getString(columnName);
        return toEnum(s);
    }

    /**
     * 根据列索引,获取可以为空的记录
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public E getNullableResult(ResultSetrs, int columnIndex) throws SQLException {
        String s =rs.getString(columnIndex);
        return toEnum(s);
    }

    @Override
    public EgetNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String s =cs.getString(columnIndex);
        return toEnum(s);
    }

    private E toEnum(String id){
        EnumSet<E> set =EnumSet.allOf(type);
        if (set == null || set.size()<= 0) {
            return null;
        }
        for (E e : set) {
            K k = e.getId();
            if(k != null){
                if(k.toString().equals(id)){
                    return e;
                }
            }
        }
        return null;
    }
}

在mybatis中有一个功能强大的typeHandler专门用来解决数据库中的数据类型和Java中的数据类型之间的转化问题,我们通过定义EnumHandler,继承BaseTypeHandler,实现其中的抽象方法即可。

之后定义枚举类,实现上面的接口,泛型类型为数据库中存储的类型

public enum DefenseStatus implementsIdentifiable<Integer>{
    NORMAL(0, "正常答辩"),
    EXCEL(2, "争优答辩"),
    DELAY(4, "延期答辩");

    private Integer val;
    private String label;

    DefenseStatus(Integer val, Stringlabel) {
        this.val = val;
        this.label = label;
    }

    public static DefenseStatusgetById(int id){
        DefenseStatus[] statuses =DefenseStatus.values();
        for(DefenseStatus status :statuses){
            if(status.val == id){
                return status;
            }
        }
        return null;
    }



    @Override
    public Integer getId() {
        return this.val;
    }

    @JsonValue
    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public String toString() {
        return label;
    }
}

然后我们就可以使用这个handler来完成我们的转换了。在mapper.xml定义resultMap的时候,凡是枚举类那一项,就写成下面这种格式,其中的typeHandler换成EnumHandler的具体路径即可。


<result column="grouptype"property="grouptype" typeHandler="com.mankind.thesis.common.mybatis.EnumHandler"/>

在insert,delete,update等这些语句中如果有用到枚举类作为传入参数,则替换为即可

#{grouptype,typeHandler=com.mankind.thesis.common.mybatis.EnumHandler}


上面讲到的都是与数据库之间的交互,那么与controller与前台的交互呢?我如何让前台传一个0/2/4过来,就自动转换成对应的枚举类型呢?这同样需要我们去实现数据绑定。在BaseController中加入下面这段代码即可。

@InitBinder
protected void initBinder(WebDataBinder binder) { 
   binder.registerCustomEditor(DefenseStatus.class, newPropertyEditorSupport(){
        @Override
        public void setAsText(Stringtext) throws IllegalArgumentException {
            int val = 0;
            try {
                val =Integer.parseInt(text);
            }catch (Exception ex){

            }
            setValue(DefenseStatus.getById(val));
        }
    });
 }
这样在前端传入defenseStatus=0,而后台的方法参数中有 DefenseStatus defenseStatus时,参数将自动绑定为对应的枚举类,我们可以直接使用枚举类进行操作。

 

而如果我们需要将枚举类传到前台进行展示(通常是作为检索条件的单选框出现),只需要在controller中写上

@RequestMapping(value = "/add",produces = "text/html;charset=utf-8", method = RequestMethod.GET)
public String add(Model model, Long taskid) throws Exception {
   model.addAttribute("defenseTask",defenseTaskService.queryById(taskid));
   model.addAttribute("titles", TitleLevel.values());
    model.addAttribute("defenseStatuses",DefenseStatus.values());
    return"console/thesis/defense/group/add";
}

前端代码:

<select id="cc"class="easyui-combobox" name="type"editable="false" style="width:200px;">
    <c:forEach items="${ defenseStatuses }"var="type">
        <option value="${type.ordinal()}"}>${type.label}</option>
    </c:forEach>
</select>

以上便是Enum枚举类与ssm框架的融合应用。

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值