因為類的全限定名一般包括包名,顯得很長,在使用過程中不是很方便,所以MyBatis中允許我們使用一種簡寫的方式來代替全限定名,這就是別名。這就相當於我們在玩微信的時候,有些人的昵稱很長很難記,怎么辦?我們給它加一個備注,方便我們快速識別,但是如果有兩個相同的備注名怎么區分到底誰是誰呢,你可能會說通過頭像,那再極端一點萬一這倆人的頭像也是一摸一樣的呢?所以這就說明一個問題,別名必須是能夠唯一標示一個類,否則容易引發沖突,這些問題在MyBatis的配置中都有對應的處理方式,待會會介紹。別名又分為系統別名和自定義別名,在MyBatis中別名由類TypeAliasRegistry去定義,且別名不分大小寫。
一、系統定義的別名
因為別名是由TypeAliasRegistry去定義,所以我們既可以通過這個對象獲取系統中已經定義好的別名,也能自定義別名,先通過一段代碼來獲取系統中都預定義了哪些別名。
1 /** 2 * 獲取系統別名配置 3 */ 4 public static void getTypeAlias() { 5 SqlSession sqlSession = getSqlSession(); 6 TypeAliasRegistry typeAliasRegistry = sqlSession.getConfiguration().getTypeAliasRegistry(); 7 Map<String, Class<?>> tarMap = typeAliasRegistry.getTypeAliases(); 8 for (String key : tarMap.keySet()) { 9 System.out.println("類:"+tarMap.get(key).getSimpleName()+"====別名:"+key); 10 } 11 } 12 13 public static void main(String[] args) { 14 getTypeAlias(); 15 }
1⃣️首先要獲取SqlSession對象sqlSession;
2⃣️通過sqlSession對象獲取到Configuration對象configuration;
3⃣️通過configuration對象獲取TypeAliasRegistry對象typeAliasRegistry
4⃣️通過typeAliasRegistry的getTypeAliases()方法就能獲取到所有系統別名了
下面是我打印出的結果:
1 Date=====date 2 boolean=====_boolean 3 CglibProxyFactory=====cglib 4 byte[]=====_byte[] 5 int[]=====_int[] 6 Object[]=====object[] 7 BigDecimal[]=====decimal[] 8 Integer=====integer 9 Float=====float 10 PerpetualCache=====perpetual 11 byte=====_byte 12 Iterator=====iterator 13 BigInteger[]=====biginteger[] 14 XMLLanguageDriver=====xml 15 double=====_double 16 int=====_int 17 HashMap=====hashmap 18 float[]=====_float[] 19 SoftCache=====soft 20 JavassistProxyFactory=====javassist 21 Date[]=====date[] 22 BigDecimal[]=====bigdecimal[] 23 Slf4jImpl=====slf4j 24 Byte=====byte 25 Double=====double 26 ResultSet=====resultset 27 RawLanguageDriver=====raw 28 Collection=====collection 29 List=====list 30 LruCache=====lru 31 float=====_float 32 long=====_long 33 int=====_integer 34 int[]=====_integer[] 35 Boolean[]=====boolean[] 36 BigDecimal=====decimal 37 double[]=====_double[] 38 Object=====object 39 BigInteger=====biginteger 40 String=====string 41 Long[]=====long[] 42 JdbcTransactionFactory=====jdbc 43 Long=====long 44 WeakCache=====weak 45 NoLoggingImpl=====no_logging 46 UnpooledDataSourceFactory=====unpooled 47 PooledDataSourceFactory=====pooled 48 VendorDatabaseIdProvider=====db_vendor 49 ManagedTransactionFactory=====managed 50 JakartaCommonsLoggingImpl=====commons_logging 51 short[]=====_short[] 52 short=====_short 53 Map=====map 54 Log4jImpl=====log4j 55 Jdk14LoggingImpl=====jdk_logging 56 Product=====product 57 FifoCache=====fifo 58 BigDecimal=====bigdecimal 59 Short[]=====short[] 60 Integer[]=====int[] 61 ArrayList=====arraylist 62 Integer=====int 63 Float[]=====float[] 64 Log4j2Impl=====log4j2 65 Byte[]=====byte[] 66 Boolean=====boolean 67 StdOutImpl=====stdout_logging 68 Double[]=====double[] 69 long[]=====_long[] 70 JndiDataSourceFactory=====jndi 71 Short=====short 72 boolean[]=====_boolean[] 73 Integer[]=====integer[]
可以看到系統總共定義了73個別名,所以我們可以使用別名代替冗長的全限定名。
比如在MyBatis的映射文件中,我們設置一個sql語句的參數類型或返回類型的時候,如果這個類型是字符串,我們完全可以用string代替java.lang.String。但是這就會有一個問題,我怎么知道哪個類型的別名是什么呢?在不知道的情況下有兩種方式可以知道:
1⃣️保險的方法:將系統別名打印出來,或者找官方文檔查詢;
2⃣️尋規律:其實從上面的結果可以發現一個規律,就是如果類名以大寫開頭,則只要將大寫變為小寫就是該類的別名;而如果類名本來就是小寫,只需要在小寫前面加上下划線即可。
二、自定義別名
自定義別名的方式有通過配置文件配置、通過TypeAliasRegistry的registerAlias方法注冊、通過注解三種方式,一般來說使用第一種比較方便,第二種和第三種都可以用來給特定類設置,以解決別名重復的問題。
1⃣️配置文件中的typeAliases屬性
1 <!--別名:pojo對象的別名 --> 2 <typeAliases> 3 <!--對類單獨進行別名設置 --> 4 <typeAlias alias="user" type="com.daily.pojo.User"></typeAlias> 5 <typeAlias alias="product" type="com.daily.pojo.Product"></typeAlias> 6 <!-- 對包進行掃描,可以批量進行別名設置,設置規則是:獲取類名稱,將其第一個字母變為小寫 --> 7 <package name="com.daily.pojo"/> 8 </typeAliases>
如代碼注解中所寫,有兩種配置,一種是通過typeAlias子屬性給每個類單獨做配置,其缺點在於當有很多個類需要配置別名時就顯得很麻煩,所以有了第二種配置,使用package子元素對整個包進行自動掃描,MyBatis會自動設置別名,設置規則是:將類名的第一個字母變為小寫,這和我們一個一個配置的規則是一樣的。但是這種方式還是存在缺陷,比如需要掃描的包有多個,其中有好幾個包下面都有一個名稱相同的類,那么按照上面的規則就會出現同一個別名作用在不同包的不同類上,這樣在使用過程中難免引發沖突,怎么辦?答案是使用后兩種。
2⃣️通過TypeAliasRegistry的registerAlias方法
假設我還有一個叫做com.daily.pojo2的包,該包下也有一個User類,我在配置文件中是這樣配置的:
1 <!--別名:pojo對象的別名 --> 2 <typeAliases> 3 <!-- 對包進行掃描,可以批量進行別名設置,設置規則是:獲取類名稱,將其第一個字母變為小寫 --> 4 <package name="com.daily.pojo"/> 5 <package name="com.daily.pojo2"/> 6 </typeAliases>
那么掃描的時候MyBatis只會定義一個別名user,那我們在引用的時候就不知道是哪個包下的User類了,是吧?解決方法如下
這種方式跟前面獲取系統配置的方式一樣,都要獲取到TypeAliasRegistry對象,然后用其registerAlias方法進行注冊
1 /** 2 * 總定義別名 3 */ 4 public static void setTypeAlias() { 5 SqlSession sqlSession = getSqlSession(); 6 TypeAliasRegistry typeAliasRegistry = sqlSession.getConfiguration().getTypeAliasRegistry(); 7 //代碼方式配置別名 8 typeAliasRegistry.registerAlias("user1",com.daily.pojo2.User.class); 9 }
3⃣️通過注解
這種方式比較簡單,只要在對應包下的對應類上面使用注解@Alias("別名")即可,如下:
1 package com.daily.pojo2; 2 3 import org.apache.ibatis.type.Alias; 4 5 @Alias("user1") 6 public class User { 7 private Integer id; 8 9 private String userName; 10 11 private String pwd; 12 13 private String sex; 14 15 private String random; 16 }
以上就是自定義別名的方式,注意,當解決沖突的時候,別名要區分於另一個同名類的別名哦!!!