主题

  因为对MyBatis在JDBC数据和Java对象之间数据转化比较感兴趣,所以就记录并学习一下TypeHandler.

使用场景

如上图所示,观察下接口方法就能明白.TypeHandler主要用于JDBC数据与Java对象数据之间转化,比如更新数据库的时候可以设置java对象里的字段怎么映射到JDBC数据库支持的类型.或者查询数据的时候,返回的JDBC的数据怎么转化成Java对象中的属性.

这篇文章主要以一个select查询为例,学习下TypeHandler都被应用在了哪些阶段? 怎么被使用的.

初始化阶段

正如之前文章分享的那样.MyBatis在初始化build SqlSessionFactory的时候会解析一大堆东西,生成Configuration.内置的TypeHandler在这个阶段被初始化.

如上图, new Configuration的时候会初始化TypeHandlerRegistry.

而这个Registry的构造方法就是注册各种内置的TypeHandler的地方.

如上图所示, register方法用于向TypeHandlerRegistry的成员域(Map)里注册TypeHandler.

register方法被重载了N多次.但是可以归纳为大致几种作用.

在此之前先介绍下TypeHandlerRegistry的几个成员域.因为register方法与他们密不可分.

JDBC_TYPE_HANDLER_MAP key为JDBC类型 Value是TypeHandler
TYPE_HANDLER_MAP    key是Java的Class类型,比如String.class, Value是1个Map,Key是JDBC类型,Value是TypeHandler. Value的key可以为null
ALL_TYPE_HANDLERS_MAP key是TypeHandler的Class类型, Value是TypeHandler
register有很多重载的方法.小结一下的话大约有2个分支:
register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler)
这个方法就是
1. 为1个Java类型添加对应的JDBC类型与handler. 主要是往TYPE_HANDLER_MAP里添加数据
2. 记录有哪些TypeHandler.即往ALL_TYPE_HANDLERS_MAP中里面添加数据.
它的一个变体是register(Type javaType, TypeHandler<? extends T> typeHandler)这个方法. 没有传JdbcType. 在这种情况下会扫描Handler上面的MappedJdbcTypes注解,找到这个handler对应的JdbcType.

当然也有类似public <T> void register(TypeHandler<T> typeHandler)这种变体.会扫描Handler上面的MappedTypes注解,找到对应的javaType.

register(JdbcType jdbcType, TypeHandler<?> handler) 这个分支是不传Java Type变量的.
这个分支就比较简单了.往JDBC_TYPE_HANDLER_MAP中加入数据
 
 
除了内置的TypeHandler自己也可以设置自定义的TypeHandler

在初始化的解析conf的时候会解析

这个代码比较简单,直接看就能明白.唯一要注意的是是先初始化自带的typeHandler.再加载自定义的typeHandler.所以自己定义的可能会覆盖mybatis内置的.

 
至此,TypeHandlerRegistry就已经完成了注册handler的任务了.
 
 

解析Mapper阶段

其实这个也算是初始化阶段...在解析完自定义的typeHandler之后需要解析Mapper

解析Mapper中有1个很重要的步骤就是解析resultMap.

resultMap里需要指定JavaType与JdbcType之间的映射.

那么如果不指定的时候呢?

因为知道jdbcType和Java类型(property),所以会调用这个方法找到对应的TypeHandler

从上图我们也可以发现,知道了JavaType会取到jdbcType为key, Handler为Value的Map.然后从Map中根据jdbcType去找对应的handler.如果没有,那就使用null作为key去找.相当于null为key得到的是一种不指定JdbcType的通用handler.

如果还没有就做pickSoleHandler方法,取对应的handler(如果这个JavaType只有唯一一个handler,那就取这个,不然就返回null).如此就确定了handler是哪个了.

当做selectByPrimaryKey的时候就会调用对应的方法做JAVA->JDBC的类型转化(java Int -> mysql integer)

同样道理,得到结果集映射到Java对象的时候也会掉相应的方法

 
 
 

MyBatis 学习记录6 TypeHandler的更多相关文章

  1. MyBatis 学习记录5 MyBatis的二级缓存

    主题 之前学习了一下MyBatis的一级缓存,主要涉及到BaseExecutor这个类. 现在准备学习记录下MyBatis二级缓存. 配置二级缓存与初始化发生的事情 首先二级缓存默认是不开启的,需要自 ...

  2. MyBatis 学习记录3 MapperMethod类

    主题 之前学习了一下MapperProxy的生产过程,自定义Mapper类的对象是通过动态代理生产的,调用自定义方法的时候实际上是调用了MapperMethod的execute方法:mapperMet ...

  3. MyBatis 学习记录7 一个Bug引发的思考

    主题 这次学习MyBatis的主题我想记录一个使用起来可能会遇到,但是没有经验的话很不好解决的BUG,在特定情况下很容易发生. 异常 java.lang.IllegalArgumentExceptio ...

  4. MyBatis 学习记录4 MyBatis的一级缓存

    主题 分享记录一下MyBatis的一级缓存相关的学习. Demo public static void firstLevelCache() { init("mybatis-config.xm ...

  5. mybatis 学习记录1

    起因 以前刚学习java三大框架的时候持久层框架我是自学的是hibernate..感觉蛮好用的,so easy..后来大三实习公司用的是jpa(hibernate外包装一层)...再后来工作1年多用的 ...

  6. mybatis学习记录六——一对一、一对多和多对多查询

    9       订单商品数据模型 9.1     数据模型分析思路 1.每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当 于你学习系统 需求(功能)的过程. 2.每张表重要的字段设置 非空 ...

  7. Mybatis学习记录(六)----Mybatis的高级映射

    1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT orders. ...

  8. Mybatis学习记录(五)----Mybatis的动态SQL

    1.  什么是动态sql mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 1.1 需求 用户信息综合查询列表和用户信息查询列表总数这两个statemen ...

  9. MyBatis 学习记录1 一个简单的demo

    主题 最近(N个月前)clone了mybatis的源码..感觉相比于spring真的非常小...然后看了看代码觉得写得很精简...感觉我的写代码思路和这个框架比较相似(很难具体描述...就是相对来说比 ...

随机推荐

  1. 初次使用git遇到的问题总结

    第一次使用git时,遇到好多问题,但也都是小问题,下边我把这些问题总结一下. 问题一: 创建远程仓库的时候,如果你勾选了Initialize this repository with a README ...

  2. Codeforces 25E Test 【Hash】

    Codeforces 25E Test E. Test Sometimes it is hard to prepare tests for programming problems. Now Bob ...

  3. Windows10安装MySQL8.0

    1.到MySQL官网下载安装包:https://dev.mysql.com/downloads/mysql/:选择8.0版本: 2.将下载好的安装包(mysql-8.0.12-winx64 .zip) ...

  4. WebBrower使用 Http 代理访问网页

    public struct Struct_INTERNET_PROXY_INFO { public int dwAccessType; public IntPtr proxy; public IntP ...

  5. kong nginx 配置文件说明&&借鉴

    备注:     只是简单的进行说明配置文件,不会牵扯到源码   1.  配置文件位置 // 通过ps 查找 ps -ef |grep nginx /usr/local/openresty/nginx/ ...

  6. 【转】理解Linux 配置文件

    原文网址:http://www.mike.org.cn/articles/understanding-linux-configuration-files-linux/ 介绍每个 Linux 程序都是一 ...

  7. Oracle 之 AIO (异步io)

    Linux 异步 I/O (AIO)是 Linux 内核中提供的一个增强的功能.它是Linux 2.6 版本内核的一个标准特性,AIO 背后的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等 ...

  8. luvcview,使用mplayer查看摄像头和luvcview保存YUV图像视频的播放(转)

    luvcview,使用mplayer查看摄像头和luvcview保存YUV图像视频的播放 在mplayer中查看摄像头,可使用如下命令:mplayer tv:// -tv driver=v4l2:in ...

  9. 各大互联网公司2014前端笔试面试题–HTML,CSS篇

    Html篇: 1.你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? IE: trident内核 Firefox:gecko内核 Safari:webkit内核 Opera:以前是presto ...

  10. PPP PDP 及GPRS

    1.相关概念: PDP:Packet Data Protocol 分组数据协议 PLMN:Public Land Mobile Network,公共陆地移动网络 APN:Access Point Na ...