MyBatis中自定义类型处理器(TypeHandler)

2021-07-03  本文已影响0人  Wannay

1.创建数据表Status

CREATE TABLE `status` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

2.创建实体类UserStatus

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class UserStatus {
    private Integer id;
    private String username;
    private Status status;
}

其中Status是一个枚举类型

public enum Status {
    LOGIN(200, "登录成功"), LOGOUT(300, "登出成功"), REMOVE(400, "用户不存在");

    private Integer code;
    private String msg;

    Status(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static Status getStatusByCode(Integer code) {
        switch (code) {
            case 200:
                return LOGIN;
            case 300:
                return LOGOUT;
            case 400:
                return REMOVE;
            default:
                return LOGOUT;
        }
    }

    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;
    }
}

3.创建对应的类型处理器

自定义类型处理器,只需要 ==实现TypeHandler接口或者继承BaseTypeHandler即可==,其中的泛型是需要处理的类型,比如我这里需要处理的是Status类型。

//使用纯注解方式,这里需要配置MappedTypes注解,不然会不使用对应处理器
//从而导致该类型处理器不会生效,并出现`No enum constant...`异常等情况
@MappedTypes({Status.class})
@MappedJdbcTypes(value = JdbcType.INTEGER)
public class MyEnumTypeHandler implements TypeHandler<Status> {

    //设置参数,在数据库中存储的应该为状态码,这个方法用来对数据库进行操作时,给数据库传递枚举参数时传递的是状态码
    @Override
    public void setParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    //用来查询操作,直接利用结果集返回,columnName为列名
    @Override
    public Status getResult(ResultSet rs, String columnName) throws SQLException {
        int code = rs.getInt(columnName);
        return Status.getStatusByCode(code);
    }

    //用来查询操作,直接利用结果集返回,columnIndex是列索引
    @Override
    public Status getResult(ResultSet rs, int columnIndex) throws SQLException {
        int code = rs.getInt(columnIndex);
        return Status.getStatusByCode(code);
    }

    //用来存储过程的查询操作,直接利用结果集返回,columnIndex是列索引
    @Override
    public Status getResult(CallableStatement cs, int columnIndex) throws SQLException {
        int code = cs.getInt(columnIndex);
        return Status.getStatusByCode(code);
    }
}

4.创建DAO

public interface StatusDao {
    @Select("select * from status where username=#{username};")
    public UserStatus getUserStatusByUsername(String username);

    @Select("select * from status where id=#{id};")
    public UserStatus getUserStatusByUserId(Integer id);

    @Insert("insert into status(username,status) values(#{username},#{status})")
    public Integer addUserStatus(@Param("username") String username, @Param("status") Status status);

    @Select("select * from status")
    public List<UserStatus> getAllUserStatus();
}

5.配置类型处理器

5.1 使用xml方式去进行配置

虽然说是使用xml,但是并不是完全的xml,当然也可以使用完全的xml去进行配置,下面采用的是混合的方式进行配置。

5.1.1 配置MyBatis的主配置文件

配置typeHandlers标签,配置typeHandler,配置handler,以及javaType以及jdbcType。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration>
    <typeHandlers>
        <typeHandler handler="com.wanna.config.typehandler.MyEnumTypeHandler"
                     javaType="com.wanna.config.typehandler.Status" jdbcType="INTEGER"/>
    </typeHandlers>
    <mappers>
        <mapper resource="mybatis/mapper.xml"/>
    </mappers>
</configuration>

5.1.2 在SqlSessionFactoryBean中配置configLocation

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //设置数据源为druid
        sqlSessionFactoryBean.setDataSource(druidDataSource());
        //设置configLocation
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
        return sqlSessionFactoryBean;
    }

5.2 直接使用SqlSessionFactoryBean去进行配置

需要说明的是

使用这种方式去进行配置,需要在类型处理器的类上配置MappedTypes和MappedJdbcTypes对应于xml配置文件中的javaTypes和jdbcTypes,不然无法生效...

@MappedTypes({Status.class})
@MappedJdbcTypes(value = JdbcType.INTEGER)
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //设置数据源为druid
        sqlSessionFactoryBean.setDataSource(druidDataSource());
        TypeHandler<?>[] handlers = new TypeHandler<?>[]{new MyEnumTypeHandler()};
        sqlSessionFactoryBean.setTypeHandlers(handlers);
        return sqlSessionFactoryBean;
    }
上一篇下一篇

猜你喜欢

热点阅读