日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis源码之(TypeAliasRegistry)TypeAlias别名实现机制

發布時間:2025/3/11 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis源码之(TypeAliasRegistry)TypeAlias别名实现机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接:http://blog.csdn.net/qq924862077/article/details/52612589

----------------------------------

在Mybatis編程中我們經常會用到將某個bean作為參數類型parameterType或者結果返回值類型ResultType,所以很多時候我們需要把完成的Bean的包名在mapper文件中寫上,如下:

[html]?view plaincopy print?
  • <select?id="selectUser"?parameterType="com.dy.entity.User"?resultType="com.dy.entity.User">????
  • ????select?*?from?user?where?c_id=#{id}????
  • </select>????

  • Mybatis給我們提供了一種叫別名的機制,意思就是對某個具體的類設置別名,在mybatis的配置文件中配置如下:

    [html]?view plaincopy print?
  • <configuration>??
  • ????<typeAliases>??
  • ??????<!--??
  • ??????通過package,?可以直接指定package的名字,?mybatis會自動掃描你指定包下面的javabean,??
  • ??????并且默認設置一個別名,默認的名字為:?javabean?的首字母小寫的非限定類名來作為它的別名。??
  • ??????也可在javabean?加上注解@Alias?來自定義別名,?例如:?@Alias(user)???
  • ??????<package?name="com.dy.entity"/>??
  • ???????-->?

  • ??????<typeAlias?alias="user"?type="com.dy.entity.User"/>??

  • ??</typeAliases>??
  • ????
  • ??......??
  • ????
  • </configuration>??

  • 這樣之后mapper文件中的select可以寫成如下格式:

    [html]?view plaincopy print?
  • <select?id="selectUser"?parameterType="user"?resultType="user">????
  • ????select?*?from?user?where?c_id=#{id}????
  • </select>????
  • 這樣就可以在使用某個bean時使用別名就可以了,不需要寫完成的包名+類名

    接下來我們介紹TypeAlias別名的實現機制

    (1)我們在mybatis的配置文件中配置了typeAliases,我們首先分析XMLConfigBuilder類中對于typeAliases的解析,源碼如下:

    [java]?view plaincopy print?
  • //類別名解析??
  • ??private?void?typeAliasesElement(XNode?parent)?{??
  • ????if?(parent?!=?null)?{??
  • ??????for?(XNode?child?:?parent.getChildren())?{??
  • ????????//如果子節點是package,那么就獲取package節點的name屬性??
  • ????????if?("package".equals(child.getName()))?{??
  • ??????????String?typeAliasPackage?=?child.getStringAttribute("name");??
  • ??????????configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);??
  • ????????}?else?{??
  • ????????//如果子節點是typeAlias節點,那么就獲取alias屬性和type的屬性??
  • ??????????String?alias?=?child.getStringAttribute("alias");??
  • ??????????String?type?=?child.getStringAttribute("type");??
  • ??????????try?{??
  • ????????????//通過type的值來加載獲得類??
  • ????????????Class<?>?clazz?=?Resources.classForName(type);??
  • ????????????if?(alias?==?null)?{??
  • ????????????//typeAliasRegistry會進行別名注冊??
  • ??????????????typeAliasRegistry.registerAlias(clazz);??
  • ????????????}?else?{??
  • ??????????????typeAliasRegistry.registerAlias(alias,?clazz);??
  • ????????????}??
  • ??????????}?catch?(ClassNotFoundException?e)?{??
  • ????????????throw?new?BuilderException("Error?registering?typeAlias?for?'"?+?alias?+?"'.?Cause:?"?+?e,?e);??
  • ??????????}??
  • ????????}??
  • ??????}??
  • ????}??

  • 通過分析源碼我們可以得知,解析alias來獲得別名,解析type元素來獲得類名,通過Resources.classForName(type)獲得類信息,然后通過typeAliasRegistry.registerAlias(alias, clazz)將類別名注冊到typeAliasRegistry中,這樣就完成了mybatis中配置文件的解析。

    (3)TypeAliasRegistry:是用來記錄別名alias和類clazz之間的對應關系的,它可以看做是一個Map,alias作為key,類名作為value,詳看源碼如下:

    [java]?view plaincopy print?
  • //其實就是一個map結構,用來對象key別名和value具體的類??
  • public?class?TypeAliasRegistry?{??
  • ??
  • ??private?final?Map<String,?Class<?>>?TYPE_ALIASES?=?new?HashMap<String,?Class<?>>();??
  • ??
  • ??public?TypeAliasRegistry()?{??
  • ????registerAlias("string",?String.class);??
  • ??
  • ????registerAlias("byte",?Byte.class);??
  • ????registerAlias("long",?Long.class);??
  • ????registerAlias("short",?Short.class);??
  • ????registerAlias("int",?Integer.class);??
  • ????registerAlias("integer",?Integer.class);??
  • ????registerAlias("double",?Double.class);??
  • ????registerAlias("float",?Float.class);??
  • ????registerAlias("boolean",?Boolean.class);??
  • ??
  • ????registerAlias("byte[]",?Byte[].class);??
  • ????registerAlias("long[]",?Long[].class);??
  • ????registerAlias("short[]",?Short[].class);??
  • ????registerAlias("int[]",?Integer[].class);??
  • ????registerAlias("integer[]",?Integer[].class);??
  • ????registerAlias("double[]",?Double[].class);??
  • ????registerAlias("float[]",?Float[].class);??
  • ????registerAlias("boolean[]",?Boolean[].class);??
  • ??
  • ????registerAlias("_byte",?byte.class);??
  • ????registerAlias("_long",?long.class);??
  • ????registerAlias("_short",?short.class);??
  • ????registerAlias("_int",?int.class);??
  • ????registerAlias("_integer",?int.class);??
  • ????registerAlias("_double",?double.class);??
  • ????registerAlias("_float",?float.class);??
  • ????registerAlias("_boolean",?boolean.class);??
  • ??
  • ????registerAlias("_byte[]",?byte[].class);??
  • ????registerAlias("_long[]",?long[].class);??
  • ????registerAlias("_short[]",?short[].class);??
  • ????registerAlias("_int[]",?int[].class);??
  • ????registerAlias("_integer[]",?int[].class);??
  • ????registerAlias("_double[]",?double[].class);??
  • ????registerAlias("_float[]",?float[].class);??
  • ????registerAlias("_boolean[]",?boolean[].class);??
  • ??
  • ????registerAlias("date",?Date.class);??
  • ????registerAlias("decimal",?BigDecimal.class);??
  • ????registerAlias("bigdecimal",?BigDecimal.class);??
  • ????registerAlias("biginteger",?BigInteger.class);??
  • ????registerAlias("object",?Object.class);??
  • ??
  • ????registerAlias("date[]",?Date[].class);??
  • ????registerAlias("decimal[]",?BigDecimal[].class);??
  • ????registerAlias("bigdecimal[]",?BigDecimal[].class);??
  • ????registerAlias("biginteger[]",?BigInteger[].class);??
  • ????registerAlias("object[]",?Object[].class);??
  • ??
  • ????registerAlias("map",?Map.class);??
  • ????registerAlias("hashmap",?HashMap.class);??
  • ????registerAlias("list",?List.class);??
  • ????registerAlias("arraylist",?ArrayList.class);??
  • ????registerAlias("collection",?Collection.class);??
  • ????registerAlias("iterator",?Iterator.class);??
  • ??
  • ????registerAlias("ResultSet",?ResultSet.class);??
  • ??}??
  • ??
  • ??@SuppressWarnings("unchecked")??
  • ??//?throws?class?cast?exception?as?well?if?types?cannot?be?assigned??
  • ??/*?通過別名來找到具體的類**/??
  • ??public?<T>?Class<T>?resolveAlias(String?string)?{??
  • ????try?{??
  • ??????if?(string?==?null)?{??
  • ????????return?null;??
  • ??????}??
  • ??????//?issue?#748??
  • ??????String?key?=?string.toLowerCase(Locale.ENGLISH);??
  • ??????Class<T>?value;??
  • ??????if?(TYPE_ALIASES.containsKey(key))?{??
  • ????????value?=?(Class<T>)?TYPE_ALIASES.get(key);??
  • ??????}?else?{??
  • ????????value?=?(Class<T>)?Resources.classForName(string);??
  • ??????}??
  • ??????return?value;??
  • ????}?catch?(ClassNotFoundException?e)?{??
  • ??????throw?new?TypeException("Could?not?resolve?type?alias?'"?+?string?+?"'.??Cause:?"?+?e,?e);??
  • ????}??
  • ??}??
  • ??/*?通過包名注冊類**/??
  • ??public?void?registerAliases(String?packageName){??
  • ????registerAliases(packageName,?Object.class);??
  • ??}??
  • ??/*?獲得包內的類,除去內部類和接口**/??
  • ??public?void?registerAliases(String?packageName,?Class<?>?superType){??
  • ????ResolverUtil<Class<?>>?resolverUtil?=?new?ResolverUtil<Class<?>>();??
  • ????resolverUtil.find(new?ResolverUtil.IsA(superType),?packageName);??
  • ????Set<Class<??extends?Class<?>>>?typeSet?=?resolverUtil.getClasses();??
  • ????for(Class<?>?type?:?typeSet){??
  • ??????//?Ignore?inner?classes?and?interfaces?(including?package-info.java)??
  • ??????//?Skip?also?inner?classes.?See?issue?#6??
  • ??????if?(!type.isAnonymousClass()?&&?!type.isInterface()?&&?!type.isMemberClass())?{??
  • ????????registerAlias(type);??
  • ??????}??
  • ????}??
  • ??}??
  • ??/*?注冊類**/??
  • ??public?void?registerAlias(Class<?>?type)?{??
  • ????String?alias?=?type.getSimpleName();??
  • ????Alias?aliasAnnotation?=?type.getAnnotation(Alias.class);??
  • ????if?(aliasAnnotation?!=?null)?{??
  • ??????alias?=?aliasAnnotation.value();??
  • ????}???
  • ????registerAlias(alias,?type);??
  • ??}??
  • ??/*?注冊類包括別名和類**/??
  • ??public?void?registerAlias(String?alias,?Class<?>?value)?{??
  • ????if?(alias?==?null)?{??
  • ??????throw?new?TypeException("The?parameter?alias?cannot?be?null");??
  • ????}??
  • ????//?issue?#748??
  • ????String?key?=?alias.toLowerCase(Locale.ENGLISH);??
  • ????if?(TYPE_ALIASES.containsKey(key)?&&?TYPE_ALIASES.get(key)?!=?null?&&?!TYPE_ALIASES.get(key).equals(value))?{??
  • ??????throw?new?TypeException("The?alias?'"?+?alias?+?"'?is?already?mapped?to?the?value?'"?+?TYPE_ALIASES.get(key).getName()?+?"'.");??
  • ????}??
  • ????TYPE_ALIASES.put(key,?value);??
  • ??}??
  • ??/*?注冊類包括別名和類名**/??
  • ??public?void?registerAlias(String?alias,?String?value)?{??
  • ????try?{??
  • ??????registerAlias(alias,?Resources.classForName(value));??
  • ????}?catch?(ClassNotFoundException?e)?{??
  • ??????throw?new?TypeException("Error?registering?type?alias?"+alias+"?for?"+value+".?Cause:?"?+?e,?e);??
  • ????}??
  • ??}??
  • ????
  • ??/**?
  • ???*?@since?3.2.2?
  • ???*/??
  • ??public?Map<String,?Class<?>>?getTypeAliases()?{??
  • ????return?Collections.unmodifiableMap(TYPE_ALIASES);??
  • ??}??
  • ??
  • }??
  • 通過上面的源碼我們可以看到,它默認注冊了一些基本的類型基本類和包裝類,然后我們可以調用registerAliases來注冊其他類的別名。

    (3)剛才我們看到了TypeAliasRegistry.registerAliases()函數會登記別名及類名,我們也可以看到TypeAliasRegistry通過了resolveAlias函數來讓我們通過別名alias來獲取實際的類,源碼如下:

    [java]?view plaincopy print?
  • /*?通過別名來找到具體的類**/??
  • ??public?<T>?Class<T>?resolveAlias(String?string)?{??
  • ????try?{??
  • ??????if?(string?==?null)?{??
  • ????????return?null;??
  • ??????}??
  • ??????//?issue?#748??
  • ??????String?key?=?string.toLowerCase(Locale.ENGLISH);??
  • ??????Class<T>?value;??
  • ??????if?(TYPE_ALIASES.containsKey(key))?{??
  • ????????value?=?(Class<T>)?TYPE_ALIASES.get(key);??
  • ??????}?else?{??
  • ????????value?=?(Class<T>)?Resources.classForName(string);??
  • ??????}??
  • ??????return?value;??
  • ????}?catch?(ClassNotFoundException?e)?{??
  • ??????throw?new?TypeException("Could?not?resolve?type?alias?'"?+?string?+?"'.??Cause:?"?+?e,?e);??
  • ????}??
  • ??}??

  • 總結:這樣我們就對Mybatis的typaAlias的實現機制就有了一個簡單的了解,其實簡單說就是創建了一個Map<string,Class<?>>,解析mybatis的配置文件,將alias元素的值作為Map的key,通過反射機制獲得的type元素對應的類名的類作為Map的value值,在真正使用時通過alias別名來獲取真正的類。


    -------------

    更多的Java,Angular,Android,大數據,J2EE,Python,數據庫,Linux,Java架構師,:

    http://www.cnblogs.com/zengmiaogen/p/7083694.html


    總結

    以上是生活随笔為你收集整理的Mybatis源码之(TypeAliasRegistry)TypeAlias别名实现机制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。