学习Mybatis(2):自定义TypeHandler

TypeHandler是Mybatis用来在JDBCType和JavaType之间做类型转换的

默认提供了很多转换器:

类型处理器 Java 类型 JDBC 类型
BooleanTypeHandler java.lang.Boolean, boolean 数据库兼容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 数据库兼容的 NUMERIC 或 BYTE
ShortTypeHandler java.lang.Short, short 数据库兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler java.lang.Integer, int 数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandler java.lang.Long, long 数据库兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler java.lang.Float, float 数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler java.lang.Double, double 数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler java.math.BigDecimal 数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR
ClobReaderTypeHandler java.io.Reader -
ClobTypeHandler java.lang.String CLOB, LONGVARCHAR
NStringTypeHandler java.lang.String NVARCHAR, NCHAR
NClobTypeHandler java.lang.String NCLOB
BlobInputStreamTypeHandler java.io.InputStream -
ByteArrayTypeHandler byte[] 数据库兼容的字节流类型
BlobTypeHandler byte[] BLOB, LONGVARBINARY
DateTypeHandler java.util.Date TIMESTAMP
DateOnlyTypeHandler java.util.Date DATE
TimeOnlyTypeHandler java.util.Date TIME
SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP
SqlDateTypeHandler java.sql.Date DATE
SqlTimeTypeHandler java.sql.Time TIME
ObjectTypeHandler Any OTHER 或未指定类型
EnumTypeHandler Enumeration Type VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引)
EnumOrdinalTypeHandler Enumeration Type 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。
InstantTypeHandler java.time.Instant TIMESTAMP
LocalDateTimeTypeHandler java.time.LocalDateTime TIMESTAMP
LocalDateTypeHandler java.time.LocalDate DATE
LocalTimeTypeHandler java.time.LocalTime TIME
OffsetDateTimeTypeHandler java.time.OffsetDateTime TIMESTAMP
OffsetTimeTypeHandler java.time.OffsetTime TIME
ZonedDateTimeTypeHandler java.time.ZonedDateTime TIMESTAMP
YearTypeHandler java.time.Year INTEGER
MonthTypeHandler java.time.Month INTEGER
YearMonthTypeHandler java.time.YearMonth VARCHAR or LONGVARCHAR
JapaneseDateTypeHandler java.time.chrono.JapaneseDate DATE

自定义转换器:

系统自带的转换器不一定能够满足需求,比如有些字段存入数据库时需要进行加密,从数据库读取之后还需要解密

这时候可以实现一个自定义的TypeHandler

1.实现TypeHandler<T>接口

以Base64加解密为例:

package mybatis;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;

@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MyTypeHandler implements TypeHandler<String> {
    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, Base64.getEncoder().encodeToString(parameter.getBytes()));
    }

    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        return new String(Base64.getDecoder().decode(rs.getString(columnName)));
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        return new String(Base64.getDecoder().decode(rs.getString(columnIndex)));
    }

    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return new String(Base64.getDecoder().decode(cs.getString(columnIndex)));
    }
}

@MappedTypes用来指定JavaType,@MappedJdbcTypes用来指定JdbcType

2.注册自定义TypeHandler

在mybatis_config.xml的settings标签后面,添加:

<typeHandlers>
    <typeHandler handler="****Handler"/>
</typeHandlers>

即可,如果没有使用注解指定数据出入类型,还可以在此使用 jdbcType 和 javaType 属性进行指定

3.使用自定义TypeHandler

修改UserService.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="mybatis.UserService">
    <resultMap id="base64map" type="User">
        <id column="id" property="id" javaType="int" jdbcType="INTEGER"/>
        <result column="userName" property="userName" typeHandler="mybatis.MyTypeHandler"/>
        <result column="age" property="age" javaType="int" jdbcType="INTEGER"/>
    </resultMap>
    <select id="getUser" resultMap="base64map" parameterType="int">
        select * from User where id=#{id};
    </select>
</mapper>

添加了resultMap段,其中userName字段配置了typeHandler

然后将select段的resultType属性修改为resultMap,值为resultMap段的id

如果修改的是insert、update等标签,只需要创建parameterMap段,并将它们的parameterType改为parameterMap即可(parameterMap即将废弃,不推荐使用)

或者使用Map来传递参数

4.测试:

数据库中,将id为1的行的userName进行Base64编码,如 zhangsan 编码后为 emhhbmdzYW4=

运行程序,输出如下:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Thu Nov 22 14:20:37 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
User{id=1, userName='zhangsan', age=1}

猜你喜欢

转载自blog.csdn.net/u010670411/article/details/84338223