SQL
create table sys_role
(
id bigint auto_increment comment '角色ID'
primary key,
role_name varchar(50) null comment '角色名',
enabled int null comment '有效标志',
create_by bigint null comment '创建人',
create_time datetime null comment '创建时间'
)
comment '角色表' charset = utf8;
枚举规范接口
JDBC数字转JavaType的字符串接口
/**
* 枚举应该包含 属性 Integer value 、String label;
*/
public interface BaseIntDBEnum {
Integer getValue();
String getLabel();
String toString();
}
JDBC字符串转JavaType的字符串接口
/**
* 枚举应该包含 属性 Integer value 、String label;
*/
public interface BaseStringDBEnum {
String getValue();
String getLabel();
String toString();
}
枚举具体类
public enum SysRoleUserTypeEnum implements BaseStringDBEnum {
ONE("admin", "管理员"),
TWO("user", "普通用户");
String value;
String label;
SysRoleUserTypeEnum(String value, String label) {
this.value = value;
this.label = label;
}
@Override
public String getValue() {
return value;
}
@Override
public String getLabel() {
return label;
}
// 必须添加
@Override
public String toString() {
return label;
}
}
public enum SysRoleIDDBEnum implements BaseIntDBEnum {
FIRST(1, "第一名"),
SECOND(2, "第二名"),
THREE(3, "第三名");
Integer value;
String label;
public Integer getValue() {
return value;
}
public String getLabel() {
return label;
}
SysRoleIDDBEnum(Integer value, String label) {
this.value = value;
this.label = label;
}
/**
* 因为 TypeHandler 的三个 get 方法返回值是 BaseIntDBEnum
* 如果不重新 toString 方法。则展示值 为 Enum 的 name(DISABLE、ENABLE)
*
* @return 禁用\启用
*/
@Override
public String toString() {
return label;
}
}
public enum SysRoleIntDBEnum implements BaseIntDBEnum {
/**
* 0-立即发布、1-定时发布
*/
DISABLE(0, "禁用"),
ENABLE(1, "启用");
Integer value;
String label;
public Integer getValue() {
return value;
}
public String getLabel() {
return label;
}
SysRoleIntDBEnum(Integer value, String label) {
this.value = value;
this.label = label;
}
/**
* 因为 TypeHandler 的三个 get 方法返回值是 BaseIntDBEnum
* 如果不重新 toString 方法。则展示值 为 Enum 的 name(DISABLE、ENABLE)
*
* @return 禁用\启用
*/
@Override
public String toString() {
return label;
}
}
添加对应的TypeHandler
JDBC数字 与 JavaType的字符串处理的TypeHandler
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// 规范应该写 @MappedJdbcTypes
//@MappedJdbcTypes(value = JdbcType.TINYINT, includeNullJdbcType = true)
@MappedTypes(value = {SysRoleIntDBEnum.class ,SysRoleIDDBEnum.class})
// 实现DisplayedEnum 都需要写进去
// MyBatis 会扫描 @MappedTypes 的所有value 并生成 一对一的 DefaultEnumTypeHandler
// 例如:<typeHandler handler="EnableTypeHandler" javaType="SysRoleIntDBEnum"/>
// <typeHandler handler="EnableTypeHandler" javaType="SysRoleIDDBEnum"/>
public class DefaultEnumTypeHandler extends BaseTypeHandler<BaseIntDBEnum> {
private Class<BaseIntDBEnum> type;
public DefaultEnumTypeHandler() {
System.out.println("init DefaultEnumTypeHandler no args");
this.type = BaseIntDBEnum.class;
}
public DefaultEnumTypeHandler(Class<BaseIntDBEnum> type) {
System.out.println("init DefaultEnumTypeHandler with args");
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, BaseIntDBEnum parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getValue());
}
@Override
public BaseIntDBEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
return convert(rs.getInt(columnName));
}
@Override
public BaseIntDBEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return convert(rs.getInt(columnIndex));
}
@Override
public BaseIntDBEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return convert(cs.getInt(columnIndex));
}
private BaseIntDBEnum convert(int status) {
BaseIntDBEnum[] objs = type.getEnumConstants();
for (BaseIntDBEnum em : objs) {
if (em.getValue() == status) {
return em;
}
}
return null;
}
}
JDBC字符串 与 JavaType的字符串处理的TypeHandler
@MappedTypes({SysRoleUserTypeEnum.class})
public class DefaultStringEnumTypeHandler extends BaseTypeHandler<BaseStringDBEnum> {
private Class<BaseStringDBEnum> type;
public DefaultStringEnumTypeHandler() {
System.out.println("init DefaultStringEnumTypeHandler no args");
this.type = BaseStringDBEnum.class;
}
public DefaultStringEnumTypeHandler(Class<BaseStringDBEnum> type) {
System.out.println("init DefaultStringEnumTypeHandler with args");
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, BaseStringDBEnum parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.getValue());
}
@Override
public BaseStringDBEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
return convert(rs.getString(columnName));
}
@Override
public BaseStringDBEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return convert(rs.getString(columnIndex));
}
@Override
public BaseStringDBEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return convert(cs.getString(columnIndex));
}
private BaseStringDBEnum convert(String value) {
BaseStringDBEnum[] enumConstants = type.getEnumConstants();
for (BaseStringDBEnum dbEnum : enumConstants) {
if (dbEnum.getValue() == value) {
return dbEnum;
}
}
return null;
}
}
@MappedTypes 的作用
在扫描所有的typehandler:1.查看类上是否标注有注解;2.若标有注解则循环注册typehandler;3.循环注册即通过有参构造创建对象,参数是 @MappedTypes 的 value
2.如果没有标注@MappedTypes则使用 typehandler的无参数的构造方法创建typehandler;
实体类使用具体枚举类
仅关注红色内容即可
Mapper配置
此处未具体配置要使用的typehangdler
<?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="tk.mybatis.simple.mapper.SysRoleMapper">
<resultMap id="BaseResultMap" type="tk.mybatis.simple.model.SysRole">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="role_name" jdbcType="VARCHAR" property="roleName"/>
<result column="enabled" jdbcType="INTEGER" property="enabled" />
<result column="create_by" jdbcType="BIGINT" property="createBy"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
</resultMap>
<sql id="Base_Column_List">
id, role_name, enabled , create_by, create_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from sys_role
where id = #{id,jdbcType=BIGINT}
</select>
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="tk.mybatis.simple.model.SysRole"
useGeneratedKeys="true">
insert into sys_role
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="roleName != null">
role_name,
</if>
<if test="enabled != null">
enabled,
</if>
<if test="createBy != null">
create_by,
</if>
<if test="createTime != null">
create_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="roleName != null">
#{roleName,jdbcType=VARCHAR},
</if>
<if test="enabled != null">
#{enabled,jdbcType=INTEGER},
</if>
<if test="createBy != null">
#{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
</mapper>
MyBatis-config 配置
<?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>
<settings>
<!-- logImpl 属性配置指定使用 LOG4J 输出日志 -->
<setting name="logImpl" value="LOG4J"/>
<!--指定 Enum 使用的默认 TypeHandler (新增于 3.4.5)-->
<!-- <setting name="defaultEnumTypeHandler" value="**TypeHandler"/>-->
</settings>
<typeHandlers>
<!-- 这里配置的话在 xml 遇到对应了类型会自动使用 TypeHandler --》
<!-- 此处未指明要处理的JavaType是什么,使用为两个TypeHandler 处理的是 一类(多种数据)无法指定到一种数据类型-->
<typeHandler handler="tk.mybatis.simple.type.DefaultEnumTypeHandler" />
<typeHandler handler="tk.mybatis.simple.type.DefaultStringEnumTypeHandler" />
<!--使用该注解可以指定(package 应放在 typeHandler的后面)-->
<!-- <package name="tk.mybatis.simple.type"/> -->
</typeHandlers>
</configuration>
效果演示
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.junit.BeforeClass;
import java.io.IOException;
import java.io.Reader;
// 基础测试类
public class BaseMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException exception) {
exception.printStackTrace();
}
}
public SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
测试添加
@Test
public void testInsertSelective(){
SqlSession sqlSession = getSqlSession();
SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class);
SysRole record = new SysRole();
record.setEnabled(SysRoleIntDBEnum.ENABLE);
int i = sysRoleMapper.insertSelective(record);
System.out.println(i);
}
测试查询
@Test
public void testSelectByPrimaryKey() {
SqlSession sqlSession = getSqlSession();
SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class);
SysRole sysRole = sysRoleMapper.selectByPrimaryKey(1L);
System.out.println(sysRole);
}