MyBatis源码解析(九)——Type类型模块之类型处理器注册器(TypeHandlerRegistry)

原创作品,可以转载,但是要标注出处地址:http://www.cnblogs.com/V1haoge/p/6709157.html

以身作则代码已经出狱!请移步动delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示范代码但是是自自家种蒙易出来的,封装好齐全适于自行扩展以及改。

1、回顾

 

  上一样篇研究之是种类别名注册器TypeAliasRegister,它最主要用来将着力型以及用户从定义的类进行别名注册,将别名及其对应类类型保存于一个HashMap中,方便存取,是映射器映射功能实现之底蕴,本篇所研究之档次处理器注册器TypeHandlerReister是用来统筹管理型处理器的,类型处理器是的确用于进行java类型与数据库类型映射的家伙。

iw14.0.50来了,在初的本子中极吸引自己的便是充实了完美之httphandler功能:终于得以直接以地点栏输入url打开iw功能页面了;可以自由使用EasyUI等js框架了;显示模式对话框也不再七缠绕八缠绕惹人劳动了;呵呵,我感到iw第一坏类似主流web开发工具了!

  这等同篇我们或要研究项目处理器的注册器,有关具体品种处理器的钻研放到之后进行。

兴奋了了,来品尝一下咔嚓。其实iw的坑还是那个多的,虽然早已接近主流了,但是,后面逐渐还见面说到…

2、类型处理器

1、新建一个iw工程,选择Stand
Alone Server /
Service,这种模式下进展付出是最为地道的,调试好有利,正式颁布时得以重复起一个library型的工程宣告到.net服务器上。(是的,大家没有看错,现在iw已经脱离了isapi模式,可以像部署.net
mvc4应用相同安排及iis上,后面会解释,.net虚拟主机也得以发布iw应用了!巨大的腾飞。)

  为了研究项目处理器注册器,我们要对品种处理器有必然的根底和认得,这里大概介绍一下,具体内容可相当下一致首。

 

  类型处理器简单点说就是用以拍卖javaType与jdbcType之间类型转换用的计算机,MyBatis针对诸多Java类型与数据库类型进行了相当处理。

2、保存工程后在工程被补充加一个初的单元文件,例如起名为wxapi.pas,这个文件被的代码用负微信接入工作。代码如下:

  它最主要用来映射器配置文件的干活,在经品种别名注册器获取项目别名代表的品种之后,就好应用得之花色通过项目处理器注册器来获取那个相应之JdbcType和呼应之种处理器。

interface

  由此可见每个门类处理器都对少数独品种,一个Java类型,一个数据库类型。而路处理器的来意就是是进行二者之间的匹配、对应、转换。

uses
  Classes, IW.Content.Base, System.SysUtils,HTTPApp, IWApplication,
  IW.HTTP.Request, IW.HTTP.Reply;

3、类型处理器注册器

type
  /// <summary>
  ///
于TContentBase继承下来的切近,就相当给asp.net中之httphandler

  /// </summary>
  TWxApi = class(TContentBase)
  protected
    function Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication; aParams: TStrings): Boolean; override;
  public
    constructor Create; override;
  end;

  类型处理器注册器既能够就项目处理器的登记功能,同时也能对品种处理器进行统筹管理,其中间定义了集来进展路处理器的存取,同时定义了存取方法。

implementation

1   private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<JdbcType, TypeHandler<?>>(JdbcType.class);
2   private final Map<Type, Map<JdbcType, TypeHandler<?>>> TYPE_HANDLER_MAP = new HashMap<Type, Map<JdbcType, TypeHandler<?>>>();
3   private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<Class<?>, TypeHandler<?>>();

uses
  ServerController, UserSessionUnit, Crypt.SHA1;

  以上是TypeHandlerRegister中定义的老三独Map集合,这三个聚众是因此来保存类型处理器的注册信息之。

{ TWxApi }

  第一种:JDBC_TYPE_HANDLER_MAP,这是一个枚举Map集合,其内部是为JdbcType枚举类中枚举值为键创建的同等种集合,这种集先天存在键(枚举值),它是盖数据库类型为键来保存类型处理器,亦将类型处理器注册到相应的数据库类型及。

constructor TWxApi.Create;
begin
  inherited;
  // 文件未待真实存在
  FileMustExist := False;
end;

  第二种:TYPE_HANDLER_MAP,这是一个前套Map集合,内层集合是为数据库类型为键保存处理器,外层集合为以Java类型来保存对应之数据库类型及其处理器,这个集将三者关系起来,是实在展开三者对诺提到相当的汇。

function TWxApi.Execute(aRequest: THttpRequest; aReply: THttpReply;
  const aPathname: string; aSession: TIWApplication;
  aParams: TStrings): Boolean;
var
  signature: string;
  timestamp: string;
  nonce: string;
  echostr: string;
  strs: TStringList;
  tmpStr: string;
begin
  Result := True;

  第三种:ALL_TYPE_HANDLERS_MAP,这个集中保留着独具的路处理器,是因种类处理器的类类型为键值保存之,它好统筹有的种类处理器(带有统计的效力)。

  signature := aParams.Values[‘signature’];
  timestamp := aParams.Values[‘timestamp’];
  nonce := aParams.Values[‘nonce’];
  echostr := aParams.Values[‘echostr’];

3.1 基础项目处理器

  strs := TStringList.Create;
  strs.Add(‘MyTestToken’);    //
Token,要同微信接口配置信息保持一致

  strs.Add(timestamp);
  strs.Add(nonce);
  strs.Sort;

  在开立项目处理器注册器的时候,在其任参构造器中会展开基础项目处理器的登记,这些注册包括三种植办法,一种是用以JavaType为键的保存方法,一栽是因JdbcTye为键的保留方法,还有平等种就是为JavaType与JdbcType为键的保留方法,这最终一栽保存方法是同样种植嵌套的Map集合,前面的片栽就是略的Map集合。

  tmpStr := strs[0]+strs[1]+strs[2];
  tmpStr := SHA1(AnsiString(tmpstr));

  下面用该管参构造器源码罗列:

  if tmpStr=signature then
  begin
    aReply.WriteString(echostr)
  end else begin
    aReply.WriteString(‘如果看这个提示说明这链接地址可看成微信接口地址以。’);
  end;
  aSession.Terminate; //
释放会话资源,本handler无需会话

end;

 1   //构造函数里注册系统内置的类型处理器
 2   public TypeHandlerRegistry() {    
 3     //以下是为多个类型注册到同一个handler
 4     register(Boolean.class, new BooleanTypeHandler());
 5     register(boolean.class, new BooleanTypeHandler());
 6     register(JdbcType.BOOLEAN, new BooleanTypeHandler());
 7     register(JdbcType.BIT, new BooleanTypeHandler());
 8 
 9     register(Byte.class, new ByteTypeHandler());
10     register(byte.class, new ByteTypeHandler());
11     register(JdbcType.TINYINT, new ByteTypeHandler());
12 
13     register(Short.class, new ShortTypeHandler());
14     register(short.class, new ShortTypeHandler());
15     register(JdbcType.SMALLINT, new ShortTypeHandler());
16 
17     register(Integer.class, new IntegerTypeHandler());
18     register(int.class, new IntegerTypeHandler());
19     register(JdbcType.INTEGER, new IntegerTypeHandler());
20 
21     register(Long.class, new LongTypeHandler());
22     register(long.class, new LongTypeHandler());
23 
24     register(Float.class, new FloatTypeHandler());
25     register(float.class, new FloatTypeHandler());
26     register(JdbcType.FLOAT, new FloatTypeHandler());
27 
28     register(Double.class, new DoubleTypeHandler());
29     register(double.class, new DoubleTypeHandler());
30     register(JdbcType.DOUBLE, new DoubleTypeHandler());
31 
32       //以下是为同一个类型的多种变种注册到多个不同的handler
33     register(String.class, new StringTypeHandler());
34     register(String.class, JdbcType.CHAR, new StringTypeHandler());
35     register(String.class, JdbcType.CLOB, new ClobTypeHandler());
36     register(String.class, JdbcType.VARCHAR, new StringTypeHandler());
37     register(String.class, JdbcType.LONGVARCHAR, new ClobTypeHandler());
38     register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler());
39     register(String.class, JdbcType.NCHAR, new NStringTypeHandler());
40     register(String.class, JdbcType.NCLOB, new NClobTypeHandler());
41     register(JdbcType.CHAR, new StringTypeHandler());
42     register(JdbcType.VARCHAR, new StringTypeHandler());
43     register(JdbcType.CLOB, new ClobTypeHandler());
44     register(JdbcType.LONGVARCHAR, new ClobTypeHandler());
45     register(JdbcType.NVARCHAR, new NStringTypeHandler());
46     register(JdbcType.NCHAR, new NStringTypeHandler());
47     register(JdbcType.NCLOB, new NClobTypeHandler());
48 
49     register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());
50     register(JdbcType.ARRAY, new ArrayTypeHandler());
51 
52     register(BigInteger.class, new BigIntegerTypeHandler());
53     register(JdbcType.BIGINT, new LongTypeHandler());
54 
55     register(BigDecimal.class, new BigDecimalTypeHandler());
56     register(JdbcType.REAL, new BigDecimalTypeHandler());
57     register(JdbcType.DECIMAL, new BigDecimalTypeHandler());
58     register(JdbcType.NUMERIC, new BigDecimalTypeHandler());
59 
60     register(Byte[].class, new ByteObjectArrayTypeHandler());
61     register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());
62     register(Byte[].class, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());
63     register(byte[].class, new ByteArrayTypeHandler());
64     register(byte[].class, JdbcType.BLOB, new BlobTypeHandler());
65     register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler());
66     register(JdbcType.LONGVARBINARY, new BlobTypeHandler());
67     register(JdbcType.BLOB, new BlobTypeHandler());
68 
69     register(Object.class, UNKNOWN_TYPE_HANDLER);
70     register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
71     register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
72 
73     register(Date.class, new DateTypeHandler());
74     register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler());
75     register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler());
76     register(JdbcType.TIMESTAMP, new DateTypeHandler());
77     register(JdbcType.DATE, new DateOnlyTypeHandler());
78     register(JdbcType.TIME, new TimeOnlyTypeHandler());
79 
80     register(java.sql.Date.class, new SqlDateTypeHandler());
81     register(java.sql.Time.class, new SqlTimeTypeHandler());
82     register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());
83 
84     // issue #273
85     register(Character.class, new CharacterTypeHandler());
86     register(char.class, new CharacterTypeHandler());
87   }

end.

  通过源码可以发现:MyBatis内置注册之类别处理器很是到,几乎囊括了具有常用之类型,所以一般情形下我们直接利用内置的项目处理器进行路处理即可。

只要代码所示,TContentBase即iw版httphandler的根底类,如果不需要展示iwForm,从这类型继承下来即可。如果欲采用iwForm还发出只TContentForm基础类可用,哇哦,在浏览器地址栏输入url也足以直接打开iwform了哦。TWxApi.Execute中的代码即微信接入的代码,非常简单,不了解之看看微信帮助:微信接入指南。

3.1.1
针对JavaType,MyBatis内置注册了一晃项目:

 

序号

3、于ServerController中注册之httphandler,直接贴出ServerController注册代码:
procedure TIWServerController.IWServerControllerBaseConfig(Sender: TObject);
begin
  //
以ServerController.OnConfig事件被登记我们定义的微信Handler

  //
ServerController.OnConfig事件于方方面面应用程序生命周期中只被运行一次于

  with THandlers.Add(”, ‘wxapi.php’, TWxApi.Create) do
  begin
    CanStartSession := True;            //
于字面上懂是会启动会话

    RequiresSessionStart := False;      //
从字面上懂是得启动会话,这点儿单特性必须开展设置,否则输入 /wxapi.php
将中转主窗体

                                        //
也尽管是未装CanStartSession和RequiresSessionStart,则要先行实施/$/start
启动会话后才

                                        //
能健康访问 /wxapi.php页面,这个明显不是咱要之。

  end;
end;

javaType

要是代码所示,红色的THandlers.Add(”, ‘wxapi.php’, TWxApi.Create)这段代码就到位了httphandler的报,在浏览器地址栏输入http://localhost/wxapi.php即可访问刚刚注册的此控制器。

JdbcType

而是及时段代码中生只中等的坑,详见我代码中之笺注。

TypeHandler

此坑是handler注册后开行iw应用可非事先以浏览器地址栏输入/$/start启动程序,而是直接输入/wxapi.php验证httphandler时失败,页面自动导航及主窗体!阅读帮助后意识,需要装TContentBase.RequiresSessionStart:=false否则会招致iw应用必须先启动会话访问主窗体才能运用httphandler,按照救助的验证设置了TContentBase.RequiresSessionStart:=false虽然一直输入/wxapi.php不再导航及主窗体了,但是会唤起404代码错误,单步跟踪发现httphandler代码确实曾履行了,这样非应出现404荒谬,多方查证和尝试发现尚需安装TContentBase.CanStartSession := True,呵呵,这个当支援中并未提到,估计是初本子新增加的性质。好了,现在于地方栏输入http://localhost/wxapi.php能够正常打开页面了。

入口

图片 1 

说明

4、将编译完成的iw应用拷贝到主机及展开测试,实战微信接入

1

图片 2,居然提示配置失败!这是呀状况,我动用的代码是由别人写好的一个Delphi版微信接入接口代码中拷贝的,那个程序一样之代码没有其他问题,当时先是个念头是页面编码不科学,好吧,我改,iw的handler默认的编码是utf-8格式的,于是自己尝试了gbk,iso-8859-1等多种编码格式,均提示上述失实。万般无奈只好写日记看看到底handler代码执行没有,结果令人震惊,放到真实服务器上后,微信认证时handler代码居然没实施,而以自己本机调试时同实在服务器的浏览器上浏览时犹蛮好未尝其他问题。巨大的坑啊,连在好几天各种测试,各种修改,都备放弃了,呵呵,结果看了生iw自己的httphandler示例,发现以该ServerController中落实了一个轩然大波:OnBrowserCheck,于是尝试当温馨代码中益了同一事件代码进行测试,哇塞,可以了。。。

Boolean.class

procedure TIWServerController.IWServerControllerBaseBrowserCheck(
  aSession: TIWApplication; var rBrowser: TBrowser);
begin
  //
这个波代码很关键,我当这里卡了少数龙!
 
  //
  // 以无落实此波之早晚,在其它浏览器输入
/wxapi.php 都能够不负众望响应,唯独到了

  //
微信中就展示配置失败,后来当代码中使了日志输出才意识iw能收到微信请求,但是

  //
TWxApi.Execute方法也从不尽,后来失去官网阅览了连带辅助,才意识iw只出支撑之浏

  //
览器才可正常应输出,而微信发出的web请求显然不属另外一个既掌握的浏览器

  if rBrowser is TOther then begin
    rBrowser.Free;
    rBrowser := TInternetExplorer.Create(8); //
以兼容IE8页面浏览进行页面内容输出

  end;
end;

null

图片 3,呵呵,太不容易了,就这样几履行代码折腾好几龙,不过iw终于可以用来微信支付了。

BooleanTypeHandler

 

入口2

自身以为Delphi的雄强在于除了编译器外有源代码均提供,这样出现问题了足以经过看源码解决,但是iw太封闭了,没有源码就终于了,帮助吗跟不上,在线特别帮助实在女人太死了,建议就此iw的爱人做在线帮助及iw自己的言传身教工程同步看,少走弯路!不过,iw发展及今审就好好用了,尤其对发生delphi情节的食指,能为此自己太拿手的言语及开发工具进行web开发真是挺爽的同等码业务。

 

 

2

未完,待续。。。

boolean.class

 

null

下同样破讲话说iw的时髦部署方式,以.net
mvc4方式配置于iis上,呵呵,如果单单拘留iw在线帮助有关mvc方式部署就错过实践,也来小坑哦!

BooleanTypeHandler

 

3

Byte.class

null

ByteTypeHandler

 

4

byte.class

null

ByteTypeHandler

 

5

Short.class

null

ShortTypeHandler

 

6

short.class

null

ShortTypeHandler

 

7

Integer.class

null

IntegerTypeHandler

 

8

int.class

null

IntegerTypeHandler

 

9

Long.class

null

LongTypeHandler

 

10

long.class

null

LongTypeHandler

 

11

Float.class

null

FloatTypeHandler

 

12

float.class

null

FloatTypeHandler

 

13

Double.class

null

DoubleTypeHandler

 

14

double.class

null

DoubleTypeHandler

 

15

String.class

null

StringTypeHandler

 

16

BigDecimal.class

null

BigDecimalTypeHandler

 

17

BigInteger.class

null

BigIntegerTypeHandler

 

18

Byte[].class

null

ByteObjectArrayTypeHandler

 

19

byte[].class

null

ByteArrayTypeHandler

 

20

Object.class

null

UNKNOWN_TYPE_HANDLER

 

21

Date.class

null

DateTypeHandler

 

22

java.sql.Date.class

null

SqlDateTypeHandler

 

23

java.sql.Time.class

null

SqlTimeTypeHandler

 

24

Character.class

null

CharacterTypeHandler

 

25

char.class

null

CharacterTypeHandler

 

26

java.sql.Timestamp.class

null

SqlTimestampTypeHandler

 

3.1.2
针对JdbcType,MyBatis内置注册了瞬间色:

序号

javaType

JdbcType

TypeHandler

入口

说明

1

 

JdbcType.BOOLEAN

BooleanTypeHandler

入口1

 

2

 

JdbcType.BIT

BooleanTypeHandler

 

3

 

JdbcType.TINYINT

ByteTypeHandler

 

4

 

JdbcType.SMALLINT

ShortTypeHandler

 

5

 

JdbcType.INTEGER

IntegerTypeHandler

 

6

 

JdbcType.FLOAT

FloatTypeHandler

 

7

 

JdbcType.DOUBLE

DoubleTypeHandler

 

8

 

JdbcType.CHAR

StringTypeHandler

 

9

 

JdbcType.VARCHAR

StringTypeHandler

 

10

 

JdbcType.CLOB

ClobTypeHandler

 

11

 

JdbcType.LONGVARCHAR

ClobTypeHandler

 

12

 

JdbcType.NVARCHAR

NStringTypeHandler

 

13

 

JdbcType.NCHAR

NStringTypeHandler

 

14

 

JdbcType.NCLOB

NClobTypeHandler

 

15

 

dbcType.ARRAY

ArrayTypeHandler

 

16

 

JdbcType.BIGINT

LongTypeHandler

 

17

 

JdbcType.REAL

BigDecimalTypeHandler

 

18

 

JdbcType.DECIMAL

BigDecimalTypeHandler

 

19

 

JdbcType.NUMERIC

BigDecimalTypeHandler

 

20

 

JdbcType.LONGVARBINARY

BlobTypeHandler

 

21

 

JdbcType.BLOB

BlobTypeHandler

 

22

 

JdbcType.OTHER

UNKNOWN_TYPE_HANDLER

 

23

 

JdbcType.TIMESTAMP

DateTypeHandler

 

24

 

JdbcType.DATE

DateOnlyTypeHandler

 

25

 

JdbcType.TIME

TimeOnlyTypeHandler

 

3.1.3
针对JdbcType和JavaType,MyBatis内置注册了一下类:

序号

JavaType

JdbcType

TypeHandler

入口

说明

1

Date.class

JdbcType.DATE

DateOnlyTypeHandler

入口3

 

2

Date.class

JdbcType.TIME

TimeOnlyTypeHandler

 

3

Object.class

JdbcType.OTHER

UNKNOWN_TYPE_HANDLER

 

4

byte[].class

JdbcType.BLOB

BlobTypeHandler

 

5

byte[].class

JdbcType.LONGVARBINARY

BlobTypeHandler

 

6

Byte[].class

JdbcType.BLOB

BlobByteObjectArrayTypeHandler

 

7

Byte[].class

JdbcType.LONGVARBINARY

BlobByteObjectArrayTypeHandler

 

8

String.class

JdbcType.CHAR

StringTypeHandler

 

9

String.class

JdbcType.CLOB

ClobTypeHandler

 

10

String.class

JdbcType.VARCHAR

StringTypeHandler

 

11

String.class

JdbcType.LONGVARCHAR

ClobTypeHandler

 

12

String.class

JdbcType.NVARCHAR

NStringTypeHandler

 

13

String.class

JdbcType.NCHAR

NStringTypeHandler

 

14

String.class

JdbcType.NCLOB

NClobTypeHandler

 

3.2 注册入口计

  通过观察源码我们啊得发现立即三种注册方式,我于此用即刻三种植艺术的register方法看做三独入口,分别由名叫也:入口1、入口2、入口3。

  其中:

    入口1:对应之前介绍的率先种集合(枚举集合),其进口计吗:

1   //入口1
2   public void register(JdbcType jdbcType, TypeHandler<?> handler) {
3     JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler);
4   }

    该入口计用于将品种处理器注册及相应的数据库类型。

    入口2:对应之前介绍的第二栽嵌套集合(其中内层集合的键为null),其输入计吧:

1   //入口2
2   public <T> void register(Class<T> javaType, TypeHandler<? extends T> typeHandler) {
3     register((Type) javaType, typeHandler);
4   }

    该入口计用于将项目处理器注册及对应之Java类型。

    入口3:对应之前介绍的老二栽嵌套集合,其输入计为:

1   //入口3
2   public <T> void register(Class<T> type, JdbcType jdbcType, TypeHandler<? extends T> handler) {
3     register((Type) type, jdbcType, handler);
4   }

    该入口计用于将项目处理器和Java类型和数据库类型联系起。

  上述的老三独输入计均是对内而设的入口计,也就是说是用以注册器内部基础项目处理器(MyBatis内置的型处理器)注册下的。而MyBatis还提供了于定义类型处理器的功力,也就是说在此类中尚提供了对外的自定义类型处理器注册入口。

  这么理解:对内就是欠办法为类似中调用进行挂号,对外就是拖欠方式给类似外部的任何类进行调用而开展注册,这里的其它类其实就是XMLConfigBuilder类,它在构建Configuration对象时就是会见调用对外的报方式,来拿用户从定义之类别处理器注册及注册器中。

    对外入口1:只指定包名的状况下,这种状况一般用配合注解@MappedTypes使用,使用该注解进行JavaType的装置(即注解的value值)

 1   //对外入口1:扫描器
 2   public void register(String packageName) {
 3     ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
 4     resolverUtil.find(new ResolverUtil.IsA(TypeHandler.class), packageName);
 5     Set<Class<? extends Class<?>>> handlerSet = resolverUtil.getClasses();
 6     for (Class<?> type : handlerSet) {
 7       //Ignore inner classes and interfaces (including package-info.java) and abstract classes
 8       if (!type.isAnonymousClass() && !type.isInterface() && !Modifier.isAbstract(type.getModifiers())) {
 9         register(type);
10       }
11     }
12   }

  这个进口是一个扫描器,它会动ResolverUtil工具类在被定包名下扫描所有类,然后开展巡回注册,注册之前会开展铲除操作,将其中类、接口、抽象类排除在外。这个扫描器针对的就是是咱们由定义之项目处理器进行登记,这个进口方法会在构建Configuration配置类时由XMLConfigBuilder进行调用,用于将用户从定义的色处理器注册及注册器中。

  上面的输入是当指定包名的情状下开展保险扫描来取包下所发生类似来展开项目处理器注册,一般会配合注解一起行使,但是倘若无配合注解也克得逞。如果配合注解指定JavaType,那么它用和对外入口2的状态亦然(指定JavaType与TypeHandler),如果没配合注解,那么即便惟有TypeHandler,这时候会调用另外一个注册方式,在这办法中会再次印证是否有注解,不存的话,那么证明得到之好像是否是TypeReference接口的实现类似,如果是实在现类,说明这仿佛是一个品类处理器,那么重调用另外一个挂号方式,以该种处理器的原生类型为参数进行调用,在这个办法中需要查询该类型处理器是否发生注解@MappedJdbcTypes来指定JdbcType,如果起则这JdbcType值为数据库类型,如果没或者是Null类型,则一直拿JdbcType置null再调用核心注册方式,将拖欠型处理器注册及TYPE_HANDLER_MAP集合中,最后还有用该注册器注册到ALL_TYPE_HANDLERS_MAP中用于统一保管。

    对外入口2:指定Java类型与品类处理器的景象

1   //对外入口2
2   public void register(Class<?> javaTypeClass, Class<?> typeHandlerClass) {
3     register(javaTypeClass, getInstance(javaTypeClass, typeHandlerClass));
4   }

  对于第二种植对外入口其实当率先种之情状被一度有描述,这个方法会调用另外一个注册方式,来行使@MappedJdbcTypes获取jdbcType类型,其余步骤同齐。

    对外入口3:指定JavaType、JdbcType、TypeHandler三者的景

1   //对外入口3
2   public void register(Class<?> javaTypeClass, JdbcType jdbcType, Class<?> typeHandlerClass) {
3     register(javaTypeClass, jdbcType, getInstance(javaTypeClass, typeHandlerClass));
4   }

  这种场面好一直调用核心注册进行挂号即可。

    对外入口4:只指定TypeHandler的景况

 1   //对外入口4
 2   public void register(Class<?> typeHandlerClass) {
 3     boolean mappedTypeFound = false;
 4     MappedTypes mappedTypes = typeHandlerClass.getAnnotation(MappedTypes.class);
 5     if (mappedTypes != null) {
 6       for (Class<?> javaTypeClass : mappedTypes.value()) {
 7         register(javaTypeClass, typeHandlerClass);
 8         mappedTypeFound = true;
 9       }
10     }
11     if (!mappedTypeFound) {
12       register(getInstance(null, typeHandlerClass));
13     }
14   }

  这种状况下,需要事先证是否生@MappedType指定JavaType,再作证是否有@MappedJdbcType指定JdbcType,分各种状态进行考虑,这在率先独输入计中就描述。

3.3 核心注册方式

  虽然所有众多对内对外的挂号入口计,但是几乎都见面靠于骨干注册方式,只有对内入口1不见面借助为中心注册方式,因为第一种对内入口计的施行效果是通向枚举集合JDBC_TYPE_HANDLER_MAP中注册数据库类型处理器。这与其余的挂号情况例外,一般我们的登记是依赖往TYPE_HANDLER_MAP嵌套集合和ALL_TYPE_HANDLERS_MAP集合中注册项目处理器。

 1   private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {
 2     if (javaType != null) {
 3       Map<JdbcType, TypeHandler<?>> map = TYPE_HANDLER_MAP.get(javaType);
 4       if (map == null) {
 5         map = new HashMap<JdbcType, TypeHandler<?>>();
 6         TYPE_HANDLER_MAP.put(javaType, map);
 7       }
 8       map.put(jdbcType, handler);
 9     }
10     ALL_TYPE_HANDLERS_MAP.put(handler.getClass(), handler);
11   }

  然我来总述一下报的经过,对地方的情形作何总结:

  注册就使三者兼备,哪三啊:javaType、JdbcType、TypeHandler三者兼备,针对于定义类型处理器而言,我们可以通过连续BaseTypeHandler抽象类或者实现TypeHandler接口的法子来进展路处理器的自定义实现。但是以要其能够以MyBatis中发挥作用,我们设以那个注册到项目处理器注册器中。通过简单的部署即可实现,配置方式发出点儿种:

1     <typeHandlers>
2         <package name="com.xx.xx"/>
3         <typeHandler handler="com.xx.xx.XxxTypeHandler" javaType="xxx" jdbcType="JdbcType.xxx" />
4     </typeHandlers>

  若是用第二种植方法配置即可直接开展挂号,但是有时我们见面看去javaType设置,而用@MappedTypes注解来指定多个JavaType,或者省去JdbcType配置,采用@MappedJdbcTypes注解来指定多只jdbcType(毕竟配置文件只能指定一个,当用装多个时,就不得不使用注解的道实现),这时便需要查询目标处理器类的注解来收获项目,如果既没以配置文件被配备,也绝非经注解配置,那么就不得不置为null(这种气象究竟,少见,一般我们若自定义类型处理器,必定是发某种类型处理器处理的免满意,我们自然会指定相应之Java类型与数据库类型,如果任的无的的讲话我们又何必多之一举为?)

  极端气象就是是下包名配置或者单指定处理器类型进行注册,这时急需逐步查看类型处理器类的注释配置来博取该计算机处理的Java类型与数据库类型,最后当两岸都获到之状下,三者兼备,调用核心注册方式,将这类型处理器注册到TYPE_HANDLER_MAP嵌套集合和ALL_TYPE_HANDLERS_MAP集合中。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图