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