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

要求:

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

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

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

Java Code复制内容到剪贴板
  1. ),
  2. );
  3. private int status;
  4. UserStatus(int status){
  5. this.status = status;
  6. }
  7. public int getStatus() {
  8. return status;
  9. }
  10. }

我们插入数据库中,数据库应该为我们保存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

执行完毕后,看结果:

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

但是问题来了?

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

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]]

完美结果。

MyBatis对于Java对象里的枚举类型处理的更多相关文章

  1. Java基础教程:枚举类型

    Java基础教程:枚举类型 枚举类型 枚举是将一具有类似特性的值归纳在一起的方法.比如,我们可以将周一到周日设计为一个枚举类型.彩虹的七种颜色设计为一个枚举类型. 常量实现枚举 我们通过定义常量的方式 ...

  2. 创建Java不可变型的枚举类型Gender

    创建Java不可变型的枚举类型,其实例如下: // 创建不可变型的枚举类 enum Gender { // 此处的枚举值必须调用对应的构造器来创建 MALE("男"), FEMAL ...

  3. Java魔法堂:枚举类型详解

    一.前言 Java的枚举类型相对C#来说具有更灵活可配置性,Java的枚举类型可以携带更多的信息. // C# enum MyColor{ RED = , BLUE = } Console.Write ...

  4. mybatis 查询单个对象,结果集类型一定要明确

    简单介绍:用ssm框架已经有很长时间了,但是似乎从来都没有对于查询单个对象,存在问题的,好像也就是那回事,写完sql就查出来了,也从来都没有认真的想过,为什么会这样,为什么要设置结果集类型 代码: / ...

  5. Java基础教程(15)--枚举类型

      枚举类型定义了一个枚举值的列表,每个值是一个标识符.例如,下面的语句声明了一个枚举类型,用来表示星期的可能情况: public enum Day { SUNDAY, MONDAY, TUESDAY ...

  6. java对象转化成String类型

    在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object#toString(),(String)要转换的对象,St ...

  7. Java中的Enum枚举类型总结

    废话不多说,直接上代码,该例子来源于:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html public enum Planet { ...

  8. java对象中含有Integer类型字段转json字符串问题

    问题:对于含有Integer类型字段的java对象,在通过下面这种方式转为json字符串时,Integer类型的字段如果为空的情况下,会默认转化为0,但是我想让它为空的时候直接转化为null,不要默认 ...

  9. Java练习 SDUT-1959_简单枚举类型——植物与颜色

    简单枚举类型--植物与颜色 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 请定义具有red, orange, yell ...

随机推荐

  1. .NET开源分布式日志框架ExceptionLess实战演练(公开版)

    一.课程介绍 在以前,我们做日志收集大多使用 Log4net,Nlog 等框架,在应用程序变得复杂并且集群的时候,可能传统的方式已经不是很好的适用了,因为收集各个日志并且分析他们将变得麻烦而且浪费时间 ...

  2. 字符串转换成整型,到底使用int.Parse,Convert.ToInt32还是int.TryParse?

    当我们想把一个字符串转换成整型int的时候,我们可能会想到如下三种方式:int.Parse,Convert.ToInt32和int.TryParse.到底使用哪种方式呢? 先来考虑string的可能性 ...

  3. Visual Studio 2012 调试程序加载缓慢,提示正在下载符号

    当在Visual Studio 2012中调试程序的时候,整个过程加载缓慢,并且有类似"正在下载符号......"的提示. 这是因为Visual Studio在调试的时候,默认从M ...

  4. FAQ:如何提高编译速度?

    问: 如何提高编译速度? 答: 减少一次需要编译的代码量,目前想到的有两种思路: 1:修改解决方案的属性配置,取消勾选不常修改的项目的“生成”复选框. 2:采用插件化的架构,每一个插件弄一个解决方案, ...

  5. centos7安装debuginfo

    转自:https://www.72zk.com/show/blog/20 查看内核版本,查找对应的内核rpm文件 [root@localhost ~]#uname -rsp Linux 3.10.0- ...

  6. 同一个账号启动两个resin而要求使用不同jdk的解决方法

    天,一个老同事问起这样一个问题,起因是他们的系统由于某些原因原有的部分模块不能运行在新的jdk下,所以需要启动两个resin并使用不同jdk.由 于是要开机自动启动,因此启动的账号还需要是同一个.这样 ...

  7. fastjson转换对象,属性首字母大小写的问题

    请求Json数据的时候,传递过去的String类型转Json数据的时候经常有首字母是大写的情况,例如"LoginAccount":"02:00:00:62:73:74&q ...

  8. 开源项目DataTimePicker实现时间和日期的选择

       这个开源项目是模仿Google官方的time选择器做的,是否漂亮.让我爱不释手,真心喜欢.很有幸和大家一起分享下,那么话不多说开始讲解. 开源项目地址:https://github.com/fl ...

  9. 用开源项目RoundedImageView来实现 圆形 / 圆角 / 椭圆的图片

    该开源项目的地址:https://github.com/vinc3m1/RoundedImageView 我自己分流下载文件的:http://download.csdn.net/detail/shar ...

  10. Spring注解详解@Repository、@Component、@Service 和 @Constroller

    概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...