Ibatis的类型处理器TypeHandler解析
Ibatis允許用戶(hù)像在hibernate中一樣定義自己的類(lèi)型,但是,用戶(hù)自定義類(lèi)型需要與數(shù)據(jù)庫(kù)中的字段類(lèi)型進(jìn)行對(duì)應(yīng)。它的處理方法是允許我們擴(kuò)展TypeHandler。Ibatis框架在處理該數(shù)據(jù)類(lèi)型時(shí)就會(huì)自動(dòng)調(diào)用TypeHandler進(jìn)行類(lèi)型轉(zhuǎn)換,非常方便,ibatis中所有的類(lèi)型都有它自己的TypeHandler,只是一些常用的數(shù)據(jù)類(lèi)類(lèi)型它已經(jīng)給我們實(shí)現(xiàn)了而已。
在配置文件中,我們有兩個(gè)地方可以配置這種處理器。
第一個(gè)地方是sqlMap文件中標(biāo)簽ResultMap或者ParameterMap中的TypeHandler屬性,這里配置的handler是局部屬性,只會(huì)在該ResultMap中才會(huì)進(jìn)行轉(zhuǎn)換。
<resultMap id="UserOrder" class="UserOrderDO" groupBy="id">......<result property="tripType" column="trip_Type"typeHandler="com.taobao.et.biz.dal.common.EnumTypeHandlerCallBack"/>...... </resultMap>?第二個(gè)地方是sqlMapConfig文件中的標(biāo)簽typeHandlers中配置typeHandle子標(biāo)簽,這里配置的標(biāo)簽是全局屬性,任何只要匹配該子標(biāo)簽的地方都會(huì)自動(dòng)使用該Handler.
<typeHandlers> <typeHandler jdbcType="CLOB" javaType="java.lang.String" callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler"/> </typeHandlers>例如這里的全局配置,如果此時(shí)某個(gè)數(shù)據(jù)庫(kù)字段的jdbcType是CLOB類(lèi)型,并且映射的JavaType類(lèi)型是字符串類(lèi)型,那么就會(huì)自動(dòng)調(diào)用這里的callback來(lái)實(shí)行類(lèi)型轉(zhuǎn)換。
那么Ibatis是如何確定使用哪一個(gè)TypeHandler的呢?!
? ? ? 它會(huì)在自己的局部區(qū)域?qū)ふ沂欠裨谂渲梦募信渲昧薍andler,找到了就使用這個(gè)handler,如果沒(méi)有找到,就會(huì)查找是否有全局handler,也就是第二種方式配置的handler,這里要注意,可能我們也沒(méi)有在全局配置文件中配置handler,此時(shí),Ibatis就會(huì)根據(jù)實(shí)際類(lèi)型配置默認(rèn)的handler。
? ? ? 我們來(lái)看一些關(guān)鍵代碼,按照查找步驟,這里我去掉了異常,只看關(guān)鍵的部分。
? ? ? 第一步:從局部Reultmap中取出配置屬性。
String propertyName = childAttributes.getProperty("property");String nullValue = childAttributes.getProperty("nullValue");String jdbcType = childAttributes.getProperty("jdbcType");String javaType = childAttributes.getProperty("javaType");String columnName = childAttributes.getProperty("column");String columnIndex = childAttributes.getProperty("columnIndex");String statementName = childAttributes.getProperty("select");String resultMapName = childAttributes.getProperty("resultMap");String callback = childAttributes.getProperty("typeHandler");callback = vars.typeHandlerFactory.resolveAlias(callback);javaType = vars.typeHandlerFactory.resolveAlias(javaType);TypeHandler handler = null;if (callback != null) { // 注意這里,如果配置了就使用這個(gè)配置的handlerObject impl = Resources.classForName(callback).newInstance();if (impl instanceof TypeHandlerCallback) {handler = new CustomTypeHandler((TypeHandlerCallback) impl);} else if (impl instanceof TypeHandler) {handler = (TypeHandler) impl;} else {throw new NestedRuntimeException ("The class '' is not a valid implementation of TypeHandler or TypeHandlerCallback");}} else {//如果沒(méi)有配置,就到這里來(lái)找handler = resolveTypeHandler(vars.client.getDelegate().getTypeHandlerFactory(), vars.currentResultMap.getResultClass(), propertyName, javaType, jdbcType, true);}第二步,如果局部配置中沒(méi)有找到,就到下面去找。
public TypeHandler resolveTypeHandler(TypeHandlerFactory typeHandlerFactory, Class clazz, String propertyName, String javaType, String jdbcType, boolean useSetterToResolve) {TypeHandler handler = null;if (clazz == null) {// Unknownhandler = typeHandlerFactory.getUnkownTypeHandler();} else if (DomTypeMarker.class.isAssignableFrom(clazz)) {// DOMhandler = typeHandlerFactory.getTypeHandler(String.class, jdbcType);} else if (java.util.Map.class.isAssignableFrom(clazz)) {// Mapif (javaType == null) {handler = typeHandlerFactory.getUnkownTypeHandler(); //BUG 1012591 - typeHandlerFactory.getTypeHandler(java.lang.Object.class, jdbcType);} else {try {Class javaClass = Resources.classForName(javaType);handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);} catch (Exception e) {throw new NestedRuntimeException("Error. Could not set TypeHandler. Cause: " + e, e);}}} else if (typeHandlerFactory.getTypeHandler(clazz, jdbcType) != null) {// Primitivehandler = typeHandlerFactory.getTypeHandler(clazz, jdbcType);} else {// JavaBeanif (javaType == null) {if (useSetterToResolve) {Class type = PROBE.getPropertyTypeForSetter(clazz, propertyName);handler = typeHandlerFactory.getTypeHandler(type, jdbcType);} else {Class type = PROBE.getPropertyTypeForGetter(clazz, propertyName);handler = typeHandlerFactory.getTypeHandler(type, jdbcType);}} else {try {Class javaClass = Resources.classForName(javaType);handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);} catch (Exception e) {throw new NestedRuntimeException("Error. Could not set TypeHandler. Cause: " + e, e);}}}return handler;}其實(shí)一個(gè)Handler=javaType+jdbcType 。
總結(jié)
以上是生活随笔為你收集整理的Ibatis的类型处理器TypeHandler解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 第二部分:浅析 Linux 初始化 in
- 下一篇: valgrind-3.11.0 交叉编译