MyBatis(十三) 自定义 TypeHandler

一、Mybatis 内置的 TypeHandler

  Mybatis 在数据交换时就会用到 TypeHandler 类型处理器,比如:从JavaType->JdbcType的转化过程,上面是 Mybatis 自带的 TypeHandler,一般情况下够我们使用了,但是有时候需要特殊处理一些数据,就需要我们自己定义一个 TypeHandler 来处理。

二、自定义 TypeHandler

  • 要自定义一个 TypeHandler 需要实现TypeHandler接口;或者继承BaseTypeHandler。
  • 在配置文件中配置这个 TypeHandler。

三、自定义 TypeHandler 来处理枚举类

  • 需求:
    • 数据库中每个 employee 对应一个状态。
    • 存入数据库中的是该状态的状态码。
    • 显示到页面的是该状态的提示信息。
1、存放状态的枚举类

    public enum EmpStatus {
        LOGIN(100,"用户已登录"),
        LOGOUT(200,"用户已注销"),
        REMOVE(300,"用户已被移除");

        private Integer code;
        private String msg;
        private EmpStatus(Integer code,String msg) {
            this.code = code;
            this.msg = msg;
        }
        public Integer getCode() {
            return code;
        }
        public void setCode(Integer code) {
            this.code = code;
        }
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }

        //根据状态码返回当前枚举类
        public static EmpStatus getEmpStatusByCode(Integer code) {
            switch (code) {
                case 100:
                    return LOGIN;
                case 200:
                    return LOGOUT;  
                case 300:
                    return REMOVE;
                default:
                    return LOGOUT;  
            }
        }
    }
2、定义 TypeHandler 处理该枚举类:

    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.TypeHandler;
    import cn.edu.pzhu.cg.entities.EmpStatus;

    public class MyEmpStatusTypeHandler implements TypeHandler<EmpStatus>{

        /*
         * 设置 sql 语句参数值,定义当前数据如何保存到数据库中
         */
        @Override
        public void setParameter(PreparedStatement ps, int i, EmpStatus parameter, JdbcType jdbcType) throws SQLException {
            System.out.println("要保存的状态码为: " + parameter.getCode());
            ps.setString(i, parameter.getCode().toString());
        }
        //从数据库中取出数据
        @Override
        public EmpStatus getResult(ResultSet rs, String columnName) throws SQLException {
            int code = rs.getInt(columnName);
            System.out.println("从数据库中获取到的状态码为: " + code);
            //根据从数据库中拿到的一个枚举状态码返回一个枚举类
            EmpStatus status = EmpStatus.getEmpStatusByCode(code);
            return status;
        }

        @Override
        public EmpStatus getResult(ResultSet rs, int columnIndex) throws SQLException {
            int code = rs.getInt(columnIndex);
            System.out.println("从数据库中获取到的状态码为: " + code);
            EmpStatus status = EmpStatus.getEmpStatusByCode(code);
            return status;
        }

        @Override
        public EmpStatus getResult(CallableStatement cs, int columnIndex) throws SQLException {
            int code = cs.getInt(columnIndex);
            System.out.println("从数据库中获取到的状态码为: " + code);
            EmpStatus status = EmpStatus.getEmpStatusByCode(code);
            return status;
        }

    }

在上面的 TypeHandler 中在存入数据时,是将每个状态的状态码存放在数据库中,而在取数据时,通过该状态码去获取对应的枚举对象,并返回。

3、配置 TypeHandler
  • 在全局配置文件中配置:

    <typeHandlers>
        <typeHandler handler="cn.edu.pzhu.cg.typehandler.MyEmpStatusTypeHandler" javaType="cn.edu.pzhu.cg.entities.EmpStatus"/>
    </typeHandlers>
   在全局配置文件中配置后,每次处理当前这个枚举类都会去使用自定义的这个 TypeHandler;也可以在 resultMap 处理结果集时去引用这个 TypeHandler,这样当需要使用这个 TypeHandler 时再去引用,更加灵活。

    <resultMap type="cn.edu.pzhu.cg.entities.Employee" id="MyEmpStatus">
            <id column="id" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="age" property="age"/>
            <result column="dept_id" property="department.id"/>
            <result column="dept_name" property="department.departmentName"/>

            <!-- 处理当前字段去使用自定义的 TyprHandler -->
            <result column="emp_status" property="empStatus"  
                    typeHandler="cn.edu.pzhu.cg.typehandler.MyEmpStatusTypeHandler"/> 
        </resultMap>
        <select id="getEmployeeStatusById" resultMap="MyEmpStatus">
            select * from employee where id=#{id}
        </select>
4、测试
  • 测试插入:

    @Test
    public void testAddEmployee() {
        Employee employee = new Employee(null, "enum3", 22, "enum3@qq.com");
        employee.setEmpStatus(EmpStatus.LOGOUT);
        mapper.addEmployee(employee);

        sqlSession.commit();
    }

数据库中的记录:

  • 测试查询:

    @Test
    public void testQuery() {
        Employee employee = mapper.getEmployeeStatusById(18);
        //输入枚举对象
        System.out.println(employee.getEmpStatus());
    }

结果:

Mybatis中处理MySQL数据库中的JSON字段映射时,自定义TypeHandler是关键步骤之一。自定义TypeHandler允许我们定义Java对象与数据库中JSON字段之间如何转换,这在涉及到复杂数据结构的ORM映射时尤其重要。 参考资源链接:[Mybatis处理JSON类型数据:自定义TypeHandler实例](https://wenku.csdn.net/doc/7i6xtckgf4?spm=1055.2569.3001.10343) 为了正确地实现这一映射,你需要定义一个继承自`BaseTypeHandler<T>`的Java类。在这个类中,你将实现几个关键的方法,如`setParameter`、`getResult`、`handleResult`和`handleInput`等,来控制数据在Java对象与数据库之间的转换逻辑。 例如,假设你有一个用户类`User`,它包含了一个`preferences`字段,这个字段是JSON格式存储的字符串: ```java public class User { private int id; private String name; private String preferences; // JSON格式的字符串 // getters and setters... } ``` 你可以创建一个`UserTypeHandler`来处理`preferences`字段: ```java public class UserTypeHandler extends BaseTypeHandler<String> { @Override public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); // 直接设置JSON字符串到PreparedStatement中 } @Override public String getResult(ResultSet rs, String columnName) throws SQLException { String json = rs.getString(columnName); return json != null ? json : null; // 直接从ResultSet中获取JSON字符串 } @Override public String getResult(ResultSet rs, int columnIndex) throws SQLException { String json = rs.getString(columnIndex); return json != null ? json : null; // 同上 } @Override public String getResult(CallableStatement cs, int columnIndex) throws SQLException { String json = cs.getString(columnIndex); return json != null ? json : null; // 同上 } } ``` 然后在Mybatis的`mybatis-config.xml`配置文件中注册这个TypeHandler: ```xml <typeHandlers> <typeHandler handler= 参考资源链接:[Mybatis处理JSON类型数据:自定义TypeHandler实例](https://wenku.csdn.net/doc/7i6xtckgf4?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值