Mybatis配置之typeAlias標(biāo)簽的用法
Mybatis typeAlias標(biāo)簽
在實(shí)際的工程之中,類的全限定名稱很長,當(dāng)我們需要大量使用的時(shí)候,這非常不方便的,然而mybatis提供了typeAlias別名標(biāo)簽供我們別名和自定義別名,然而在mybatis之中別名的注冊(cè)實(shí)際上由TypeAliasRegistry去定義,需要非常注意的是,在mybatis中名不區(qū)分大小寫的,這一點(diǎn)非常重要。
下面展示了mybatis自己自動(dòng)初始化了一些別名:


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

