第一步:定义顶级枚举接口
public interface BaseEnum<E extends Enum<?>, T> {
public T getCode();public String getValue();
}
第二步:实现枚举接口
public enum AccountTypeEnum implements BaseEnum<AccountTypeEnum,Integer>{
PERSONAL(1,"PERSONAL"),ORGANIZATION(2,"ORGANIZATION");private Integer code;private String value;static Map<Integer,AccountTypeEnum> enumMap= new HashMap<>();static {for(AccountTypeEnum accountTypeEnum:AccountTypeEnum.values()) {enumMap.put(accountTypeEnum.getCode(),accountTypeEnum);}}private AccountTypeEnum(Integer code,String value) {this.code = code;this.value = value;}public void setCode(Integer code) {this.code = code;}public void setValue(String value) {this.value = value;}@Overridepublic Integer getCode() {return code;}@Overridepublic String getValue() {return value;}public static AccountTypeEnum getEnum(Integer code) {return enumMap.get(code);}
}
第三步:定义mybatis全局枚举处理器
public class UniversalEnumHandler<E extends BaseEnum> extends BaseTypeHandler<E> {
private Class<E> type;private E [] enums;/*** 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现* @param type 配置文件中设置的转换类*/public UniversalEnumHandler(Class<E> type) {if (type == null)throw new IllegalArgumentException("Type argument cannot be null");this.type = type;this.enums = type.getEnumConstants();if (this.enums == null)throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");}@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType)throws SQLException {//BaseTypeHandler已经做了parameter的null判断// ps.setObject(i,(Integer)parameter.getState(), jdbcType.TINYINT.TYPE_CODE);ps.setInt(i,(Integer)parameter.getCode());}@Overridepublic void setParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throwsSQLException {// ps.setObject(i,(Integer)parameter.getState(), jdbcType.TINYINT.TYPE_CODE);ps.setInt(i,(Integer)parameter.getCode());}@Overridepublic E getNullableResult(ResultSet rs, String columnName) throws SQLException {// 根据数据库存储类型决定获取类型Integer i = rs.getInt(columnName);if (rs.wasNull()) {return null;} else {// 根据数据库中的code值,定位enum子类return locateEnumStatus(i);}}@Overridepublic E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {// 根据数据库存储类型决定获取类型Integer i = rs.getInt(columnIndex);if (rs.wasNull()) {return null;} else {// 根据数据库中的code值,定位enum子类return locateEnumStatus(i);}}@Overridepublic E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {// 根据数据库存储类型决定获取类型Integer i = cs.getInt(columnIndex);if (cs.wasNull()) {return null;} else {// 根据数据库中的code值,定位enum子类return locateEnumStatus(i);}}@Overridepublic E getResult(ResultSet rs, String columnName) throws SQLException {Integer i = rs.getInt(columnName);if (rs.wasNull()) {return null;} else {// 根据数据库中的code值,定位enum子类return locateEnumStatus(i);}}@Overridepublic E getResult(ResultSet rs, int columnIndex) throws SQLException {Integer i = rs.getInt(columnIndex);if (rs.wasNull()) {return null;} else {// 根据数据库中的code值,定位enum子类return locateEnumStatus(i);}}@Overridepublic E getResult(CallableStatement cs, int columnIndex) throws SQLException {Integer i = cs.getInt(columnIndex);if (cs.wasNull()) {return null;} else {// 根据数据库中的code值,定位enum子类return locateEnumStatus(i);}}/*** 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷* @param value 数据库中存储的自定义value属性* @return value对应的枚举类*/private E locateEnumStatus(Integer value) {for(E e : enums) {if(e.getCode().equals(value)) {return e;}}throw new IllegalArgumentException("未知的枚举类型:" + value + ",请核对" + type.getSimpleName());}
}
第四步:在mybatis配置文件中添加typeHandler标签
<configuration>
<settings><!-- 开启驼峰自动映射 --><setting name="mapUnderscoreToCamelCase" value="true" /><!-- 二级缓存的总开关 --><setting name="cacheEnabled" value="false" /></settings>
<typeHandlers><typeHandler handler="moc.service.infrastructure.mybatis.UniversalEnumHandler"javaType="moc.commons.enums.AccountTypeEnum"/></typeHandlers>
<plugins><!-- 分页插件:com.github.pagehelper为PageHelper类所在包名 --><plugin interceptor="com.github.pagehelper.PageHelper"><!-- 方言 --><property name="dialect" value="mysql" /><!-- 该参数默认为false --><!-- 设置为true时,使用RowBounds分页会进行count查询,查询数据总条数 --><property name="rowBoundsWithCount" value="true" /></plugin><!-- 通用Mapper插件 --><plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor"><!-- 主键自增回写方法,默认值MYSQL,详细说明请看文档 --><property name="IDENTITY" value="MYSQL" /><!--通用Mapper接口,多个通用接口用逗号隔开 --><property name="mappers" value="moc.persistence.mapper.base.SysMapper" /></plugin></plugins>
</configuration>
第五步:定义数据持久对象
@Table(name = "t_user")
public class UserPO implements Serializable {
private static final long serialVersionUID = -7508885998192627398L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "Mysql")private Integer id;private String userName;private String nickName;private String userPwd;private AccountTypeEnum accountType;private RoleTypeEnum userRole;private String idCard;private String phone;private String email;private String contacts;private String contactsPhone;private String address;private Timestamp updateTime;private Timestamp createTime;private Boolean isDel;
}