使用delphi+intraweb进行微信开发1–微信平台对接

原创小说,可以转发,可是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6709157.html

以身作则代码已经放出!请移步行使delphi+intraweb举行微信开发1~4代码示例拓展下载,虽为示例代码不过是从笔者项目中移出来的,封装很齐全适于自行扩张和改动。

1、回顾

 

  上一篇研讨的是项目外号注册器TypeAliasRegister,它最重要用来将挑广陵项目和用户自定义的档次进行外号注册,将别名及其对应类类型保存在一个HashMap中,方便存取,是映射器映射功用完成的底子,本篇所探究的门类处理器注册器TypeHandler雷斯ter是用来统一筹划管理项目处理器的,类型处理器是确实用于开始展览java类型与数据库类型映射的工具。

iw14.0.50来了,在新的本子中最吸引自个儿的正是扩张了宏观的httphandler作用:终于得以从来在地点栏输入url打开iw成效页面了;能够私下使用EasyUI等js框架了;彰显形式对话框也不再七绕八绕令人烦了;呵呵,笔者感到iw第③遍类似主流web开发工具了!

  这一篇大家如故首要商量项目处理器的注册器,有关具体品种处理器的钻研放到之后进展。

快乐过了,来品尝一下吧。其实iw的坑照旧挺多的,即使一度八九不离十主流了,不过,前面渐渐都会说到…

贰 、类型处理器

1、新建一个iw工程,选取Stand
Alone Server /
Service
,那种形式下进展付出是最了不起的,调节和测试很便利,正式布告时方可再建立2个library型的工程宣布到.net服务器上。(是的,大家没有看错,以后iw已经脱离了isapi形式,能够像铺排.net
mvc4应用相同布署到iis上,后边会解释,.net虚拟主机也能够发布iw应用了!巨大的上扬。)

  为了商量项目处理器注册器,我们要求对品种处理器有肯定的底蕴和认识,那里大概介绍一下,具体内容可等下一篇。

 

  类型处理器简单点说正是用来拍卖javaType与jdbcType之间类型转换用的处理器,MyBatis针对诸多Java类型与数据库类型进行了十一分处理。

2、封存工程后在工程中添加1个新的单元文件,例如起名为wxapi.pas,那么些文件中的代码将肩负微信接入工作。代码如下:

  它首要用以映射器配置文件的行事,在经过品种外号注册器获取项目别称代表的体系之后,就能够利用获取的品类通过品种处理器注册器来取得其相应的JdbcType和呼应的类型处理器。

interface

  综上说述每一个连串处理器都对准多少个种类,一个Java类型,贰个数据库类型。而项目处理器的成效正是进展二者之间的合作、对应、转换。

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

三 、类型处理器注册器

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方法看做多少个输入,分别起名为:入口① 、入口二 、入口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   }

  这几个进口是2个扫描器,它会使用ResolverUtil工具类在给定包名下扫描全部类,然后实行巡回注册,注册在此以前会进展铲除操作,将里面类、接口、抽象类排除在外。这一个扫描器针对的正是大家自定义的品种处理器实行注册,这几个进口方法会在营造Configuration配置类时由XMLConfigBuilder进行调用,用于将用户自定义的连串处理器注册到注册器中。

  上边的入口是在内定包名的情景下开始展览包扫描来获得包下全部类来举行项目处理器注册,一般会合营注脚一起行使,可是借使不匹配申明也能得逞。倘诺匹配注脚钦定JavaType,那么它将与对外入口2的图景亦然(钦赐JavaType与TypeHandler),如若没有协作表明,那么就唯有TypeHandler,那时候会调用别的四个注册形式,在那几个办法中会再一次验证是还是不是留存注明,不设有的话,那么申明得到的类是还是不是是TypeReference接口的兑现类,要是是实际上现类,表达那一个类是3个档次处理器,那么再度调用其它1个登记格局,以该类型处理器的原生类型为参数举办调用,在那个点子中须求查询该类型处理器是还是不是有评释@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地图