主题

  因为对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. erl_0014 《硝烟中的erlang》 读书笔记001 “绪论”

    1.大家听说Erlang,往往是因为其对高并发的良好支持.其实,Erlang的核心特征是容错,从某种程度上讲,并发只是容错这个约束下的一个副产品.容错是Erlang语言的DNA,也是和其他所有编程语言 ...

  2. new Date()相关获取当月天数和当月第一天

    var  myDate = new Date(); //获取本月第一天周几 var monthFirst = new Date(myDate.getFullYear(), parseInt(myDat ...

  3. CF1114B Yet Another Array Partitioning Task

    CF1114B Yet Another Array Partitioning Task 贪心,选择前 \(k*m\) 大的元素对答案进行贡献. 每次划分时,从当前位置往后扫,扫到 \(m\) 个前 \ ...

  4. Linux Mint17.1安装PHPStorm8.0.2

    phpstorm是用JAVA开发的,所以在安装之前需要先安装jdk sudo apt-get install default-jdk 从官网上下载phpstorm 的linux版本 http://ww ...

  5. 《DSP using MATLAB》示例Example 8.9

  6. Python 函数 -hasattr()

    hasattr(object, name)hasattr() 函数用于判断对象是否包含对应的属性.如果对象有该属性返回 True,否则返回 False.object -- 对象.name -- 字符串 ...

  7. socket编程 —— 非阻塞socket (转)---例子已上传至文件中

    在上一篇文章 <socket编程——一个简单的例子> http://blog.csdn.net/wind19/archive/2011/01/21/6156339.aspx 中写了一个简单 ...

  8. Hibernate Cannot release connection 了,有办法解决!

      问题:    系统采用Spring MVC 2.5 + Spring 2.5 + Hibernate 3.2架构,其中数据源连接池采用的是Apache commons DBCP.问题是这样的,系统 ...

  9. 2、Hive UDF编程实例

    Hive的UDF包括3种:UDF(User-Defined Function).UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Tabl ...

  10. 分布式事务之:TCC几个框架的测试情况记录

    国内主要的开源TCC分布式事务框架包括 框架名称 Github地址  star数量  tcc-transaction  https://github.com/changmingxie/tcc-tran ...