• Mybatis的类型转换注册类TypeHandlerRegistry


    Table of Contents

      • 聊聊Mybatis的类型转换注册类TypeHandlerRegistry
        • 注册类型转换处理器
        • 获取类型处理器
          • 获取jdbc类型对应的处理器
        • 总结

    聊聊Mybatis的类型转换注册类TypeHandlerRegistry

    上篇文章中我们说到TypeHandler是进行类型转换的接口,它有针对不同的类型有很多实现类,TypeHandlerRegistry来进行统一管理

    Mybatis初始化TypeHandler后,调用TypeHandlerRegistry的register()方法进行注册,下面就看一下register()

    注册类型转换处理器

    ypeHandlerRegistry的register()方法:

    private void register(Type javaType, JdbcType jdbcType, TypeHandler handler) {        if (javaType != null) {             Map<JdbcType, TypeHandler> map = typeHandlerMap.get(javaType);            if (map == null || map == NULL_TYPE_HANDLER_MAP) {                map = new HashMap<>();            }            map.put(jdbcType, handler);            typeHandlerMap.put(javaType, map);        }        allTypeHandlersMap.put(handler.getClass(), handler);    }1.2.3.4.5.6.7.8.9.10.11.

    allTypeHandlersMap中保存着所有TypeHandler类型和它对应的实例,除了这个register()方法,还可以根据@MappedJdbcTypes和@MappedTypes注解获取数据,@MappedTypes配置配置TypeHandler接口与Java类型的集合,@MappedJdbcTypes配置TypeHandler接口与Jdbc类型的集合,TypeHandlerRegistry的构造方法中调用了很多注册方法对不同jdbc类型选择不同TypeHandler的实例来进行注册

    完成类型与TypeHandler实例的注册后,mybatis会根据java类型和jdbc类型来查找对应的TypeHandler实例,调用方法是TypeHandlerRegistry的getTypeHandler()方法:

    获取类型处理器

    TypeHandlerRegistry的getTypeHandler()方法:

    private  TypeHandler getTypeHandler(Type type, JdbcType jdbcType) {        if (ParamMap.class.equals(type)) {            return null;        }        Map<JdbcType, TypeHandler> jdbcHandlerMap = getJdbcHandlerMap(type);        TypeHandler handler = null;        if (jdbcHandlerMap != null) {            handler = jdbcHandlerMap.get(jdbcType);            if (handler == null) {                handler = jdbcHandlerMap.get(null);            }            if (handler == null) {                handler = pickSoleHandler(jdbcHandlerMap);            }        }        // type drives generics here        return (TypeHandler) handler;    }1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.
    1. 调用getJdbcHandlerMap()方法根据Java类型查找对应的TypeHandler集合
    2. 如果不为空,根据jdbcType获取TypeHandler实例,如果找不到实例就使用null来获取TypeHandler的实例
    3. 如果jdbcHandlerMap只注册了一个TypeHandler,就使用这个TypeHandler对应的实例

    再看一下getJdbcHandlerMap()方法:

    获取jdbc类型对应的处理器

    private Map<JdbcType, TypeHandler> getJdbcHandlerMap(Type type) {        Map<JdbcType, TypeHandler> jdbcHandlerMap = typeHandlerMap.get(type);        if (NULL_TYPE_HANDLER_MAP.equals(jdbcHandlerMap)) { // 检测是否为空集合标识            return null;        }        if (jdbcHandlerMap == null && type instanceof Class) {            Class clazz = (Class) type;            if (Enum.class.isAssignableFrom(clazz)) { // 针对枚举类型的处理                Class enumClass = clazz.isAnonymousClass() ? clazz.getSuperclass() : clazz;                jdbcHandlerMap = getJdbcHandlerMapForEnumInterfaces(enumClass, enumClass);                if (jdbcHandlerMap == null) {                    register(enumClass, getInstance(enumClass, defaultEnumTypeHandler));                    return typeHandlerMap.get(enumClass);                }            } else {                // 查找父类关联的TypeHandler集合,并将其作为clazz对应的TypeHandler集合                jdbcHandlerMap = getJdbcHandlerMapForSuperclass(clazz);            }        }        // 如果上述查找皆失败,则以NULL_TYPE_HANDLER_MAP作为clazz对应的TypeHandler集合        typeHandlerMap.put(type, jdbcHandlerMap == null ?                NULL_TYPE_HANDLER_MAP : jdbcHandlerMap);        return jdbcHandlerMap;    }1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
    1. 先查找指定Java类型对应的TypeHandler集合
    2. 如果为空返回null
    3. 初始化指定Java类型的TypeHandler集合
    4. 调用getJdbcHandlerMapForSuperclass()
    private Map> getJdbcHandlerMapForSuperclass(Class clazz) {        Class superclass = clazz.getSuperclass();        if (superclass == null || Object.class.equals(superclass)) {            return null; // 父类为Objectnull则查找结束        }        Map> jdbcHandlerMap = typeHandlerMap.get(superclass);        if (jdbcHandlerMap != null) {            return jdbcHandlerMap;        } else {            return getJdbcHandlerMapForSuperclass(superclass);        }    }1.2.3.4.5.6.7.8.9.10.11.12.

    这个方法是返回给定class的父类对应的jdbcHandlerMap集合,这里用到了递归。

    总结

    这篇文章主要讲解了类型转换注册类的TypeHandlerRegistry的注册方法和根据Java类型获取对应的TypeHandler实例的功能,注册类是重要的一个类,Mybatis的类型转换都需要在这个类进行注册才能实现类型转换

  • 相关阅读:
    数据库复习带答案
    js摄像头动态检测
    Neo4J入门笔记
    四种质数筛选算法总结(c++)
    git_合并分支
    TCP/IP协议专栏——IP 详解——网络入门和工程维护必看
    事务隔离级别和MVCC
    MySQL之JDBC编程
    HTML网页设计制作大作业(游戏主题)---电竞
    解释什么是分布式数据库,列举几种常见的分布式数据库系统
  • 原文地址:https://blog.csdn.net/l688899886/article/details/126213454