• MyBatis自定义TypeHandler处理枚举

    在绝大多数情况下,typeHandler 因为枚举而使用,MyBatis 已经定义了两个类作为枚举类型的支持,这两个类分别是:

    • EnumOrdinalTypeHandler。
    • EnumTypeHandler。

    因为它们的作用不大,所以在大部分情况下,我们都不用它们,不过我们还是要稍微了解一下它们的用法。在此之前,先来建一个性别枚举类——SexEnum,代码如下所示。

    package com.mybatis.po;
    
    public enum SexEnum {
        MALE(1, "男"),
        FEMALE(0, "女");
    
        private int id;
        private String name;
    
        /** stter and getter **/
    
        SexEnum(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public SexEnum getSexById(int id) {
            for (SexEnum sex : SexEnum.values()) {
                if (sex.getId() == id) {
                    return sex;
                }
            }
            return null;
        }
    }

    为了使用这个关于性别的枚举,可用以下 sql 语句创建 myUser 表。

    CREATE TABLE `myuser` (
      `id` bigint(20) NOT NULL,
      `user_name` varchar(20) DEFAULT NULL,
      `password` varchar(20) DEFAULT NULL,
      `sex` char(1) DEFAULT NULL,
      `mobile` varchar(20) DEFAULT NULL,
      `tel` varchar(20) DEFAULT NULL,
      `email` varchar(20) DEFAULT NULL,
      `note` varchar(20) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    再创建一个用户 POJO,如下所示。

    public class User {
        private Long id;
        private String userName;
        private String password;
        private SexWnum sex;
        private String moblie;
        private String tel;
        private String email;
        private String note;
        /**setter and getter**/
    }

    EnumOrdinalTypeHandler

    EnumOrdinalTypeHandler 是按 MyBatis 根据枚举数组下标索引的方式进行匹配的,也是枚举类型的默认转换类,它要求数据库返回一个整数作为其下标,它会根据下标找到对应的枚举类型。

    根据这条规则,可以创建一个 UserMapper.xml 作为测试的例子,如下所示。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.mybatis.mapper.UserMapper">
        <resultMap id="userMapper" type="user">
            <result property="id" column="id" />
            <result property="userName" column="user_name" />
            <result property="password" column="passsword" />
            <result property="sex" column="sex"
                typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
            <result property="mobile" column="mobile" />
            <result property="tel" column="tel" />
            <result property="email" column="email" />
            <result property="note" column="note" />
        </resultMap>
        <select id="getUser" resultMap="userMapper" parameterType="long">
            select id,user_name,password,sex,mobile,tel,email,note from myUser
            where id=#{id}
        </select>
    </mapper>

    插入一条数据,执行的 SQL 如下:

    INSERT INTO `myuser` (`id`,`user_name`,`password`,`sex`,`mobile`,`tel`,`email`,`note`) VALUES(1,'zhangsan','123456','1','13675683675','0755-88888888','zhangsan@163.com','note......');

    这样,sex 字段就在数据库里被设置为 1,代表女性,使用以下进行测试。

    package com.mybatis.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.apache.log4j.Logger;
    
    import com.mybatis.mapper.UserMapper;
    import com.mybatis.po.User;
    
    public class MyBatisTest {
        public static void main(String[] args) throws IOException {
            Logger log = Logger.getLogger(MyBatisTest.class);
            InputStream config = Resources
                    .getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
            SqlSession ss = ssf.openSession();
            UserMapper userMapper = ss.getMapper(UserMapper.class);
            User user = userMapper.getUser(1L);
            log.info(user.getSex().getName());
        }
    }

    运行结果如图 1 所示:

    运行结果
    图 1  运行结果

全部加载完成