Mybatis配置之typeAlias標簽的用法
Mybatis typeAlias標簽
在實際的工程之中,類的全限定名稱很長,當我們需要大量使用的時候,這非常不方便的,然而mybatis提供了typeAlias別名標簽供我們別名和自定義別名,然而在mybatis之中別名的注冊實際上由TypeAliasRegistry去定義,需要非常注意的是,在mybatis中名不區(qū)分大小寫的,這一點非常重要。
下面展示了mybatis自己自動初始化了一些別名:
那么他是如何實現(xiàn)初始化別名的呢?
一般的是通過Configuration獲取TypeAliasRegistry類對象其中有一個getTypeAliasRegisry方法獲取別名,獲取之后就可以通過registerAlias方法對別名注冊了。
事實上Configuration對象也對一些常用的配置項配置了別名:
public class TypeAliasRegistry { //使用的HashMap來傳記錄,String為鍵或者屬性名稱,Class<?>則為鍵值或者為 //屬性值。 private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<String, Class<?>>(); /* * TypeAliasRegistry主要進行初始化別名的配置, */ public TypeAliasRegistry() { /* * 初始化別名 * e.g. 調用registerAlias方法注冊別名 * */ 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); } } /* * registerAlias方法輸入參數(shù)為包的路徑名稱,并且其要注冊的對應的類 * 既可以僅通過包的完整名稱進行注冊,也可以通過提供包名和對應的類的注冊 * 類型。 * 方法1,通過提供包名稱進行注冊,默認的注冊為Object類 */ public void registerAliases(String packageName){ registerAliases(packageName, Object.class); } /* * ResolverUtil用于定位,某一個類的路徑,可滿足任意條件類。兩個最常見的條件是 * 一個類實現(xiàn)/繼承另一個類,或者用一個特定的注釋注釋它。但是,通過使用測試類, * 可以使用任意條件進行搜索。 * 類加載器是用于定位所有位置(目錄和JAR文件)在類路徑中包含在一定的包裝類, * 然后加載這些類和檢查。默認情況下,類加載器使用的的線程可以由currentthread()。 * getcontextclassloader()獲取其名稱, 但這可以通過調用setclassloader(ClassLoader) * 方法重寫 */ /* * 方法2:主要是利用ResolverUtil對提供的超類,和包名方式進行注冊 */ 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); } } } /* * 方法3,僅提供注冊類型 */ 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); } }
以上是mybatis中關于別名的類,其在org.apache.ibatis.type包里面,還要注意某些已經注冊過的類別就不要重復定義了,這會引起mybatis 的運行錯誤,那么我們如何實現(xiàn)自定義別名呢,
<typeAliases> <typeAlias alias="role" type="com.*.類名"> </typeAliases>
這樣可以定義一個別名了,如果需要很多的類需要注冊時,可以使用mybatis支持的掃描別名。
<typeAliases> <package name="com."> </typeAliases>
這樣就會掃描指定的這個包,并將這個包中的類的第一個字母變?yōu)樾懽帜傅男旅肿鳛閯e名,假如掃描的多個包中有同名稱的類,這時候就會產生異常,此時我們可以在pojo類添加Alias注解。
@Alias("User2") public class User{ ···· }
這樣就能夠導致不同的包中出現(xiàn)相同的類名而導致自動掃描的別名一樣造成的沖突,建議部分包名和類型名作為別名,可以有效進行區(qū)分。
Mybatis typeAlias配置
用3種方法實現(xiàn)typeAlias配置
1.定義別名:
<typeAliases> <typeAlias alias="User" type="cn.lxc.vo.User" /> </typeAliases>
2.掃描包方式:
<typeAliases> <package name="cn.lxc.vo" /> </typeAliases>
3.注解方式:
package cn.lxc.vo; import org.apache.ibatis.type.Alias; @Alias("User") public class User { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Springboot2.x+ShardingSphere實現(xiàn)分庫分表的示例代碼
這篇文章主要介紹了Springboot2.x+ShardingSphere實現(xiàn)分庫分表的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10mybatis中使用InsertProvider注解報錯解決全過程
這篇文章主要介紹了mybatis中使用InsertProvider注解報錯解決全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07Spring如何通過@Lazy注解解決構造方法循環(huán)依賴問題
循環(huán)依賴其實就是循環(huán)引用,也就是兩個或則兩個以上的bean互相持有對方,最終形成閉環(huán),這篇文章主要給大家介紹了關于Spring如何通過@Lazy注解解決構造方法循環(huán)依賴問題的相關資料,需要的朋友可以參考下2023-03-03Springboot中@Value注解的場景用法及可能遇到的問題詳解
這篇文章主要給大家介紹了關于Springboot中@Value注解的場景用法及可能遇到問題的相關資料, @Value通常用于注入外部化屬性,即外部配置屬性的注入,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-11-11Spring?Data?JPA框架的Repository自定義實現(xiàn)詳解
Spring?Data?JPA是Spring基于JPA規(guī)范的基礎上封裝的?套?JPA?應?框架,可使開發(fā)者?極簡的代碼即可實現(xiàn)對數(shù)據庫的訪問和操作,本篇我們來了解Spring?Data?JPA框架的Repository自定義實現(xiàn)2022-04-04