前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试Mybatis之类型处理器​(typeHandlers)

面试Mybatis之类型处理器​(typeHandlers)

作者头像
小土豆Yuki
发布2020-06-15 17:41:53
1.2K0
发布2020-06-15 17:41:53
举报
文章被收录于专栏:洁癖是一只狗洁癖是一只狗

Mybatis之类型处理器

无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型,下表描述了一些默认的类型处理器.

类型处理器

Java 类型

JDBC 类型

BooleanTypeHandler

java.lang.Boolean, boolean

数据库兼容的 BOOLEAN

ByteTypeHandler

java.lang.Byte, byte

数据库兼容的 NUMERIC 或 BYTE

ShortTypeHandler

java.lang.Short, short

数据库兼容的 NUMERIC 或 SMALLINT

IntegerTypeHandler

java.lang.Integer, int

数据库兼容的 NUMERIC 或 INTEGER

LongTypeHandler

java.lang.Long, long

数据库兼容的 NUMERIC 或 BIGINT

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 类型,存储枚举的序数值(而不是名称)。

SqlxmlTypeHandler

java.lang.String

SQLXML

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 或 LONGVARCHAR

JapaneseDateTypeHandler

java.time.chrono.JapaneseDate

DATE

你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型,具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口,或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler我们就举一个简单的例子,我们先看个实体类.

public class Student {

    private int id;

    private String name;

    private boolean pass;//注意他的类型是布尔。我们要把他转成int放到数据库
    //get 和 set 省略
}

第一步:实现TypeHandler

package com.jiepi.util;

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.*;


public class MyTypeHandler implements TypeHandler {
    //在设置参数的时候调用
    public void setParameter(PreparedStatement preparedStatement, int i, Object param, JdbcType jdbcType) throws SQLException {
        if (param == null) {
            preparedStatement.setInt(i,0);
            return;
        }
        Boolean pass = (Boolean) param;
        int value = pass ? 1 : 0;
        preparedStatement.setInt(i,value);
    }
    //从数据库获取数据调用
    public Object getResult(ResultSet resultSet, String s) throws SQLException {
        int value = resultSet.getInt(s);
        if (value == 1) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
    public Object getResult(ResultSet resultSet, int i) throws SQLException {
        int value = resultSet.getInt(i);
        if (value == 1) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
    public Object getResult(CallableStatement callableStatement, int i) throws SQLException {
        int value = callableStatement.getInt(i);
        if (value == 1) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}

第二步:在mybatis配置注册TypeHandler(myBatis-config.xml).

<typeHandlers>
    <typeHandler handler="com.jiepi.util.MyTypeHandler" jdbcType="NUMERIC" javaType="java.lang.Boolean"/>
</typeHandlers>

第三步:在映射文件中设置使用TypeHandler.

注意:使用上述的类型处理器将会覆盖已经存在的处理 Java 的 Boolean 类型属性和 NUMERIC 参数及结果的类型处理器。要注意 MyBatis 不会通过窥探数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指明那是 NUMERIC 类型的字段, 以使其能够绑定到正确的类型处理器上。这是因为 MyBatis 直到语句被执行时才清楚数据类型.

 <resultMap id="studentMap" type="com.jiepi.beans.Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="pass" column="pass" typeHandler="com.jiepi.util.MyTypeHandler" jdbcType="NUMERIC" javaType="java.lang.Boolean"/>
    </resultMap>

    <insert id="add">//typeHandler 是没有双引号的
        INSERT INTO Student (id, name, pass) VALUES (#{id}, #{name}, #{pass,jdbcType=NUMERIC,javaType=java.lang.Boolean,typeHandler=com.jiepi.util.MyTypeHandler})
    </insert>

    <select id="find" resultMap="studentMap">
        SELECT * FROM Student
    </select>

第四步:测试结果.

     @Test
    public void find() {
        StudentMapper dao = session.getMapper(StudentMapper.class);
        List<Student> student = dao.find();
        student.stream().map(it->it.toString()).forEach(System.out::println);
        System.out.println(student);
    }
    @Test
    public void add1() {
        StudentMapper dao = session.getMapper(StudentMapper.class);
        Student student = new Student();
        student.setName("jiepi");
        student.setPass(true);//这里是boolean
        dao.add(student);
        session.commit();
    }

运行结果:

[DEBUG] Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@15a34df2]
[DEBUG] ==>  Preparing: INSERT INTO Student (id, name, pass) VALUES (?, ?, ?) 
int int 
[DEBUG] ==> Parameters: 0(Integer), jiepi(String), 1(Integer)//这里变成了1
[DEBUG] <==    Updates: 1
[DEBUG] Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@15a34df2]
Disconnected from the target VM, address: '127.0.0.1:51494', transport: 'socket'

1.当然也还可以使用注解分别是MappedJdbcTypes和MappedTypes代替映射文件里面的jdbcType 和javeType.

2.mybatis配置文件上面的配置只能一个个的去配置类型处理,因此我们还可以自动查找查找类型处理器.

  <typeHandlers>
       <package name="com.jiepi.util"/>
  </typeHandlers>
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洁癖是一只狗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档