pojo类
package com.sg.bean;public class User { /** * 用户ID */ private String userID; /** * 用户名 */ private String userName; /** * 用户状态 * @see com.sg.bean.EnumStatus */ private EnumStatus status; public String getUserID() { return userID; } public void setUserID(String userID) { this.userID = userID; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public EnumStatus getStatus() { return status; } public void setStatus(EnumStatus status) { this.status = status; }}
枚举类
package com.sg.bean;public enum EnumStatus { NORMAL("1", "正常"), DELETE("2", "删除"), LOGICDEL("3", "注销"); private EnumStatus(String code, String description) { this.code = code; this.description = description; } private String code; private String description; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; }}
重点来了——ibatis类型转换接口实现
先看一下源码中的注释
com.ultrapower.common.ibatis.sqlmap.client.extensions.TypeHandlerCallbackA simple interface for implementing custom type handlers. Using this interface, you can implement a type handler that will perform customized processing before parameters are set on a PreparedStatement and after values are retrieved from a ResultSet. Using a custom type handler you can extend the framework to handle types that are not supported, or handle supported types in a different way. For example, you might use a custom type handler to implement proprietary BLOB support (e.g. Oracle), or you might use it to handle booleans using "Y" and "N" instead of the more typical 0/1. EXAMPLE Here's a simple example of a boolean handler that uses "Yes" and "No". public class YesNoBoolTypeHandlerCallback implements TypeHandlerCallback { private static final String YES = "Yes"; private static final String NO = "No"; public Object getResult(ResultGetter getter) throws SQLException { String s = getter.getString(); if (YES.equalsIgnoreCase(s)) { return new Boolean (true); } else if (NO.equalsIgnoreCase(s)) { return new Boolean (false); } else { throw new SQLException ("Unexpected value " + s + " found where "+YES+" or "+NO+" was expected."); } } public void setParameter(ParameterSetter setter, Object parameter) throws SQLException { boolean b = ((Boolean)parameter).booleanValue(); if (b) { setter.setString(YES); } else { setter.setString(NO); } } public Object valueOf(String s) { if (YES.equalsIgnoreCase(s)) { return new Boolean (true); } else if (NO.equalsIgnoreCase(s)) { return new Boolean (false); } else { throw new SQLException ("Unexpected value " + s + " found where "+YES+" or "+NO+" was expected."); } } }
针对User对象中的EnumStatus,他的转换类如下
package com.sg.util;import java.sql.SQLException;import java.sql.Types;import com.ibatis.sqlmap.client.extensions.ParameterSetter;import com.ibatis.sqlmap.client.extensions.ResultGetter;import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;import com.sg.bean.EnumStatus;public class EnumStatusHandler implements TypeHandlerCallback { public Object getResult(ResultGetter getter) throws SQLException { EnumStatus result = null; if(!getter.wasNull() && getter.getObject()!= null) { for(EnumStatus status : EnumStatus.values()) { if(status.getCode().equals(getter.getObject())) { result = status; break; } } } return result; } public void setParameter(ParameterSetter setter, Object obj) throws SQLException { if(obj == null) { setter.setInt(Types.INTEGER); }else { EnumStatus status = (EnumStatus)obj; setter.setString(status.getCode()); } } public Object valueOf(String s) { return s; }}
ibatis配置文件声明
经过上述的配置,User对象中的EnumStatus枚举类就可以顺利的进行数据库操作了,以上方案有以下几个好处:
- 没有破坏pojo的纯净,pojo对象的扩展和可维护性更高;
- 枚举类加强了User对象对属性类型的把控,开发这不用担心其他人在status属性中放错值了;
- pojo的扩展性增强,比如现在前台展示需要展示名称,开发者只需对枚举进行简单的读取就可以将数据库中的0、1转为自然语言;
- 脱离实体的限制,比如前台需要展示status的可选值,枚举类便可以首当其冲。