zoukankan      html  css  js  c++  java
  • MyBatis对于Java对象里的枚举类型处理

    平时咱们写程序实体类内或多或少都会有枚举类型属性,方便嘛。但是mybatis里怎么处理他们的增删改查呢?

    要求:

    插入的时候,会用枚举的定义插入数据库,我们希望在数据库中看到的是数字或者其他东西;

    查询的时候,数据库的值可以自动转换为我们对应的枚举值。

    举例,我有一个这样的枚举类型:

    Java Code复制内容到剪贴板
    1. package cn.com.shuyangyang.domain;  
    2.   
    3. public enum UserStatus {  
    4.   
    5.     /** 无效*/  
    6.     DISABLED(0),  
    7.     /** 有效 */  
    8.     AVAILABLE(1);  
    9.       
    10.     private int status;  
    11.       
    12.     UserStatus(int status){  
    13.         this.status = status;  
    14.     }  
    15.   
    16.     public int getStatus() {  
    17.         return status;  
    18.     }  
    19.       
    20. }  

    我们插入数据库中,数据库应该为我们保存0或者1

    我们可以使用mybatis自带的枚举类型EnumOrdinalTypeHandler

    举例如下:

    Java Code复制内容到剪贴板
    1. <insert id="addUser" parameterType="User">  
    2.     INSERT INTO t_user(USER_ID,USER_NAME,LOGIN_NAME,  
    3.     LOGIN_PASSWORD,USER_STATUS,CREATE_TIME,UPDATE_TIME)  
    4.     VALUES(  
    5.         #{user_id},  
    6.         #{user_name},  
    7.         #{login_name},  
    8.         #{login_password},  
    9.         #{user_status, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},  
    10.         #{create_time},  
    11.         #{update_time}  
    12.     )  
    13. </insert>  

    我们的UserStatus插入的时候是UserStatus.AVAILABLE

    执行完毕后,看结果:

    DB.jpg

    看,是不是结果是我们期望的那样。

    但是问题来了?

    我们查询的时候报错了:Error querying database.  Cause: java.lang.IllegalArgumentException: No enum constant cn.com.shuyangyang.mybatis.UserStatus.1

    我们可以自定义这样的一个EnumStatusHandler:

    Java Code复制内容到剪贴板
    1. package cn.com.shuyangyang.mybatis;  
    2.   
    3. import java.sql.CallableStatement;  
    4. import java.sql.PreparedStatement;  
    5. import java.sql.ResultSet;  
    6. import java.sql.SQLException;  
    7.   
    8. import org.apache.ibatis.type.BaseTypeHandler;  
    9. import org.apache.ibatis.type.JdbcType;  
    10.   
    11. /** 
    12.  * Mybatis自定义转换类型 
    13.  * @author ShuYangYang 
    14.  * E-Mail:shuyangyang@aliyun.com 
    15.  * http://www.shuyangyang.com.cn 
    16.  * Date:2015年1月26日下午10:12:54 
    17.  * 
    18.  */  
    19. public class EnumStatusHandler extends BaseTypeHandler<UserStatus> {  
    20.       
    21.     private Class<UserStatus> type;  
    22.        
    23.     private final UserStatus[] enums;  
    24.    
    25.     /** 
    26.      * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现 
    27.      * @param type 配置文件中设置的转换类 
    28.      */  
    29.     public EnumStatusHandler(Class<UserStatus> type) {  
    30.         if (type == null)  
    31.             throw new IllegalArgumentException("Type argument cannot be null");  
    32.         this.type = type;  
    33.         this.enums = type.getEnumConstants();  
    34.         if (this.enums == null)  
    35.             throw new IllegalArgumentException(type.getSimpleName()  
    36.                     + " does not represent an enum type.");  
    37.     }  
    38.   
    39.     @Override  
    40.     public void setNonNullParameter(PreparedStatement ps, int i,  
    41.             UserStatus parameter, JdbcType jdbcType) throws SQLException {  
    42.         // baseTypeHandler已经帮我们做了parameter的null判断  
    43.         ps.setInt(i, parameter.getStatus());  
    44.           
    45.     }  
    46.   
    47.     @Override  
    48.     public UserStatus getNullableResult(ResultSet rs, String columnName)  
    49.             throws SQLException {  
    50.         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型  
    51.         int i = rs.getInt(columnName);  
    52.            
    53.         if (rs.wasNull()) {  
    54.             return null;  
    55.         } else {  
    56.             // 根据数据库中的code值,定位EnumStatus子类  
    57.             return locateEnumStatus(i);  
    58.         }  
    59.     }  
    60.   
    61.     @Override  
    62.     public UserStatus getNullableResult(ResultSet rs, int columnIndex)  
    63.             throws SQLException {  
    64.         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型  
    65.         int i = rs.getInt(columnIndex);  
    66.         if (rs.wasNull()) {  
    67.             return null;  
    68.         } else {  
    69.             // 根据数据库中的code值,定位EnumStatus子类  
    70.             return locateEnumStatus(i);  
    71.         }  
    72.     }  
    73.   
    74.     @Override  
    75.     public UserStatus getNullableResult(CallableStatement cs, int columnIndex)  
    76.             throws SQLException {  
    77.         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型  
    78.         int i = cs.getInt(columnIndex);  
    79.         if (cs.wasNull()) {  
    80.             return null;  
    81.         } else {  
    82.             // 根据数据库中的code值,定位EnumStatus子类  
    83.             return locateEnumStatus(i);  
    84.         }  
    85.     }  
    86.       
    87.     /** 
    88.      * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷 
    89.      * @param code 数据库中存储的自定义code属性 
    90.      * @return code对应的枚举类 
    91.      */  
    92.     private UserStatus locateEnumStatus(int code) {  
    93.         for(UserStatus status : enums) {  
    94.             if(status.getStatus()==(Integer.valueOf(code))) {  
    95.                 return status;  
    96.             }  
    97.         }  
    98.         throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());  
    99.     }  
    100.   
    101. }  

    mapper.xml里这样配置:

    XML/HTML Code复制内容到剪贴板
    1. <resultMap type="User" id="userResult">  
    2. ……省略其他属性配置  
    3.         <result column="USER_STATUS" property="user_status" typeHandler="cn.com.shuyangyang.mybatis.EnumStatusHandler"/>  
    4. ……省略其他属性配置  
    5.     </resultMap>  

    现在来看看结果:

     [User [user_id=782cba19-559f-41c3-a1b0-25fcac4cf118, user_name=系统管理员, login_name=admin, login_password=admin,user_status=AVAILABLE, create_time=Mon Jan 26 21:17:09 CST 2015, update_time=Mon Jan 26 21:17:09 CST 2015]]

     

    完美结果。






  • 相关阅读:
    RUST实践.md
    redis.md
    opencvrust.md
    aws rds can't connect to mysql server on 'xx'
    Foundation ActionScript 3.0 With Flash CS3 And Flex
    Foundation Flash Applications for Mobile Devices
    Flash Mobile Developing Android and iOS Applications
    Flash Game Development by Example
    Actionscript 3.0 迁移指南
    在SWT中非UI线程控制界面
  • 原文地址:https://www.cnblogs.com/jeffen/p/6380724.html
Copyright © 2011-2022 走看看