学习Mybatis(2):自定义TypeHandler

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

默认提供了很多转换器:

类型处理器Java 类型JDBC 类型
BooleanTypeHandlerjava.lang.Boolean, boolean数据库兼容的 BOOLEAN
ByteTypeHandlerjava.lang.Byte, byte数据库兼容的 NUMERIC 或 BYTE
ShortTypeHandlerjava.lang.Short, short数据库兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandlerjava.lang.Integer, int数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandlerjava.lang.Long, long数据库兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandlerjava.lang.Float, float数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandlerjava.lang.Double, double数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandlerjava.math.BigDecimal数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandlerjava.lang.StringCHAR, VARCHAR
ClobReaderTypeHandlerjava.io.Reader-
ClobTypeHandlerjava.lang.StringCLOB, LONGVARCHAR
NStringTypeHandlerjava.lang.StringNVARCHAR, NCHAR
NClobTypeHandlerjava.lang.StringNCLOB
BlobInputStreamTypeHandlerjava.io.InputStream-
ByteArrayTypeHandlerbyte[]数据库兼容的字节流类型
BlobTypeHandlerbyte[]BLOB, LONGVARBINARY
DateTypeHandlerjava.util.DateTIMESTAMP
DateOnlyTypeHandlerjava.util.DateDATE
TimeOnlyTypeHandlerjava.util.DateTIME
SqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMP
SqlDateTypeHandlerjava.sql.DateDATE
SqlTimeTypeHandlerjava.sql.TimeTIME
ObjectTypeHandlerAnyOTHER 或未指定类型
EnumTypeHandlerEnumeration TypeVARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引)
EnumOrdinalTypeHandlerEnumeration Type任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。
InstantTypeHandlerjava.time.InstantTIMESTAMP
LocalDateTimeTypeHandlerjava.time.LocalDateTimeTIMESTAMP
LocalDateTypeHandlerjava.time.LocalDateDATE
LocalTimeTypeHandlerjava.time.LocalTimeTIME
OffsetDateTimeTypeHandlerjava.time.OffsetDateTimeTIMESTAMP
OffsetTimeTypeHandlerjava.time.OffsetTimeTIME
ZonedDateTimeTypeHandlerjava.time.ZonedDateTimeTIMESTAMP
YearTypeHandlerjava.time.YearINTEGER
MonthTypeHandlerjava.time.MonthINTEGER
YearMonthTypeHandlerjava.time.YearMonthVARCHAR or LONGVARCHAR
JapaneseDateTypeHandlerjava.time.chrono.JapaneseDateDATE

自定义转换器:

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

这时候可以实现一个自定义的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}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值