上篇文章《深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)》 介绍了properties与environments, 本篇继续讲剩下的配置节点之一:typeAliases。 typeAliases节点主要用来设置别名,其实这是挺好用的一个功能, 通过配置别名,我们不用再指定完整的包名,并且还能取别名。

  例如: 我们在使用 com.demo.entity. UserEntity 的时候,我们可以直接配置一个别名user, 这样以后在配置文件中要使用到com.demo.entity. UserEntity的时候,直接使用User即可。

  就以上例为例,我们来实现一下,看看typeAliases的配置方法:  

<configuration><typeAliases> <!-- 通过package, 可以直接指定package的名字, mybatis会自动扫描你指定包下面的javabean, 并且默认设置一个别名,默认的名字为: javabean 的首字母小写的非限定类名来作为它的别名。 也可在javabean 加上注解@Alias 来自定义别名, 例如: @Alias(user) <package name="com.dy.entity"/> --> <typeAlias alias="UserEntity" type="com.dy.entity.User"/> </typeAliases> ...... </configuration>

再写一段测试代码,看看有没生效:(我只写一段伪代码)

Configuration con = sqlSessionFactory.getConfiguration();
Map<String, Class<?>> typeMap = con.getTypeAliasRegistry().getTypeAliases();for(Entry<String, Class<?>> entry: typeMap.entrySet()) {System.out.println(entry.getKey() + " ================> " + entry.getValue().getSimpleName());}

=======================================我是源码分割线==============================================

上面给大家简单介绍了typeAliases的用法, 接下来就看看Mybatis中的源码了:

老规矩,先从对xml的解析讲起:

 1 /**
 2  * 解析typeAliases节点
 3  */  4 private void typeAliasesElement(XNode parent) {  5 if (parent != null) {  6 for (XNode child : parent.getChildren()) {  7 //如果子节点是package, 那么就获取package节点的name属性, mybatis会扫描指定的package  8 if ("package".equals(child.getName())) {  9 String typeAliasPackage = child.getStringAttribute("name"); 10 //TypeAliasRegistry 负责管理别名, 这儿就是通过TypeAliasRegistry 进行别名注册, 下面就会看看TypeAliasRegistry源码 11  configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage); 12 } else { 13 //如果子节点是typeAlias节点,那么就获取alias属性和type的属性值 14 String alias = child.getStringAttribute("alias"); 15 String type = child.getStringAttribute("type"); 16 try { 17 Class<?> clazz = Resources.classForName(type); 18 if (alias == null) { 19  typeAliasRegistry.registerAlias(clazz); 20 } else { 21  typeAliasRegistry.registerAlias(alias, clazz); 22  } 23 } catch (ClassNotFoundException e) { 24 throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e); 25  } 26  } 27  } 28  } 29 }

重要的源码在这儿:

TypeAliasRegistry:

public class TypeAliasRegistry {//这就是核心所在啊, 原来别名就仅仅通过一个HashMap来实现, key为别名, value就是别名对应的类型(class对象)private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<String, Class<?>>(); /** * 以下就是mybatis默认为我们注册的别名 */ 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); } /** * 处理别名, 直接从保存有别名的hashMap中取出即可 */ @SuppressWarnings("unchecked") public <T> Class<T> resolveAlias(String string) { try { if (string == null) return null; String key = string.toLowerCase(Locale.ENGLISH); // issue #748 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); } } /** * 配置文件中配置为package的时候, 会调用此方法,根据配置的报名去扫描javabean ,然后自动注册别名 * 默认会使用 Bean 的首字母小写的非限定类名来作为它的别名 * 也可在javabean 加上注解@Alias 来自定义别名, 例如: @Alias(user) */ 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); } //这就是注册别名的本质方法, 其实就是向保存别名的hashMap新增值而已, 呵呵, 别名的实现太简单了,对吧 public void registerAlias(String alias, Class<?> value) { if (alias == null) throw new TypeException("The parameter alias cannot be null"); String key = alias.toLowerCase(Locale.ENGLISH); // issue #748 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); } } /** * 获取保存别名的HashMap, Configuration对象持有对TypeAliasRegistry的引用,因此,如果需要,我们可以通过Configuration对象获取 */ public Map<String, Class<?>> getTypeAliases() { return Collections.unmodifiableMap(TYPE_ALIASES); } }

由源码可见,设置别名的原理就这么简单,Mybatis默认给我们设置了不少别名,在上面代码中都可以见到。

好啦,本篇内容就是这么简单,到此为止。 下篇将继续讲解还没讲完的配置节点。

原文地址:http://www.cnblogs.com/dongying/p/4037678.html

转载于:https://www.cnblogs.com/jerrylz/p/5486321.html

深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)相关推荐

  1. 深入浅出Mybatis系列(十)---SQL执行流程分析(源码篇)

    原文地址:http://www.cnblogs.com/dongying/p/4142476.html 最近太忙了,一直没时间继续更新博客,今天忙里偷闲继续我的Mybatis学习之旅.在前九篇中,介绍 ...

  2. webpack手摸手学习系列之配置详解的 entry、output、module、resolve、devServer 和 optimization

    一.webpack 配置详解之 entry 创建空文件夹,通过 npm init 命令初始化 package.json 文件,通过 npm install webpack webpack-cli -g ...

  3. Spring、Spring MVC、MyBatis整合文件配置详解

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. web.xml的配置 web.xml应该是整个项目最重要的配置文件了,不过servlet3.0中已经 ...

  4. mybatis的resultMap配置详解

    1.mybatis的实体类继承 参考资料: 1.mybatis中实体类,po类继承另一个po类的情况 2.mybatis中resultMap配置细则 实体类的继承的作用是:可以通过继承减少代码在实体类 ...

  5. [Linux运维基础]全家桶详解!Linux中RPM包、wget下载、YUM安装、tar包、zip等包管理方式区别与参数详解,附wget下载源码包编译安装方法

    文章目录 一.RPM.tar.gz 1.rpm包格式 2.rpm包管理 3.tar包管理参数 二.wget 1.wget参数 2.wget下载源码包后编译安装 三.YUM 1.YUM工作原理 2. Y ...

  6. Android APP:Preference使用详解和实例(附源码)

    Android APP:Preference使用详解和实例 一.Preference 是Android app中重要的控件之一,Settings 模块大部分都是通过Preference 实现的,这里将 ...

  7. C++文件操作详解,实用文件辅助类源码分享,建议收藏自用!

    学习C++的小伙伴,应该会经常遇见对文件进行操作的需求,例如读写文件,作为一个使用频率较高的操作,我们每次重复地编写代码,就是浪费劳动力了,所以作者将自己常用的文件操作封装成了一个类,需要的小伙伴自取 ...

  8. word2vec 中的数学原理详解(六)若干源码细节

    word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单.高效,因此引起了很多人的关注.由于 word2vec 的作者 Tomas Miko ...

  9. AIDL在Telephony中的应用 —— ITelephony 详解 (以Android 9.0源码讲解)

    转载请注明出处:https://blog.csdn.net/turtlejj/article/details/84861020,谢谢- Telephony模块中大量的使用了AIDL,但网上却很少有文章 ...

最新文章

  1. CloudCompare 的简单的使用说明
  2. PAT 乙级 1041 考试座位号
  3. java有什么字符串_Java 中操作字符串都有哪些类?它们之间有什么区别
  4. (译)利用ASP.NET加密和解密Web.config中连接字符串
  5. linux系统5.5安装教程,图解安装Debian 9.5全过程
  6. java 规则引擎_【java规则引擎】java规则引擎搭建开发环境(示例代码)
  7. 求助pycharm里import pandas遇到No module named pandas怎么办
  8. 基于函数的二叉树的描述
  9. BZOJ2157旅游——树链剖分+线段树
  10. 【记录】ASP.NET MVC MapRoute .htm 不起作用
  11. iterator接口
  12. 成都盛铭轩:商品质量分怎么提升
  13. 17.11.25B组总结
  14. RE:从零开始的汇编语言_挑好书
  15. 在next js中添加google analytics功能
  16. 知识图谱-生物信息学-医学顶刊论文(Bioinformatics-2021)-SumGNN:通过有效的KG聚集进行多类型DDI预测
  17. 关于javaweb项目不能删除jir包解决
  18. JAVA中的集合概念
  19. 读书笔记之《安全边际(中文完整版)》
  20. 来自GitHub的系列渗透测试工具

热门文章

  1. php使用file,PHP中is_file()函数使用指南
  2. idea启动tomcat很慢_idea使用maven创建web项目
  3. php error 2,一起搞懂PHP的错误和异常(二)
  4. java中接口什么时候用_我什么时候应该在java中使用接口?
  5. java加载c库阻塞_【死磕Java並發】-----J.U.C之阻塞隊列:DelayQueue
  6. IS服务器下做301永久重定向设置方法
  7. IIS状态代码的含义
  8. python自定义分页器()转自https://www.cnblogs.com/yuanchenqi/articles/7652353.html
  9. TCP滑动窗口(发送窗口和接受窗口)
  10. 绘画软件优动漫PAINT系统要求