思考
什么是别名?
古代文人骚客会给自己取个好听的响亮的“别名”,如李白,字太白,号青莲居士,后世人称“诗仙”;又如你身边有人叫“穆罕默德·本·阿卜杜拉·本·阿卜杜勒·穆塔利·本·哈希姆”,估计每次喊他会让人崩溃的,所以自然而然的给他起个别名“穆罕默德”;还有作家的笔名等等,这些都是别名。别名就是为了化繁为简,便于使用和记忆。
注意事项
- 不宜有多个别名,否则会带来复杂性的提升,比如有个人有好多别名,当你们谈论时,使用不同的别名竟然不知道说的是同一个人;
- 别名冲突导致的映射错乱,比如你在大街上喊个“美女”,好多人都会响应;
实现思路
别名的本质实际是一种映射关系,所以其数据结构可以使用 Map<String, Object>,Key 不能重复正好避免别名冲突问题,存取通过 getObject(String) 便可获取别名所映射的对象。
MyBatis typeAliases
MyBatis 类型别名可为 Java 类型设置一个缩写名字,意在降低冗余的全限定类名书写。
配置方式
-
XML配置(全局配置文件)
- 单个Bean配置
<typeAliases> <typeAlias type="xx.xx.xxx.User" alias="user"/> </typeAliases> - 包名配置
<!-- 使用包内 Bean 的首字母小写的非限定类名来作为它的别名 --> <typeAliases> <package name="xx.xx.xxx"/> </typeAliases>
- 单个Bean配置
-
注解
@Alias(“alias”)
内置别名
MyBatis 内置了一些基本常用的类型别名,在 TypeAliasRegistry 的构造器中注册,如下表所示。这里需要注意的是,内置便意味着强制使用,如使用int,则实际类型为Integer,而实际的int类型需要使用_int或_integer。int和Integer的别名分别都是2个,为什么要设计为一对多?这样容易造成混乱,目前还不理解为何要这样做!
| 别名 | 映射的类型 |
|---|---|
| _byte | byte |
| _long | long |
| _short | short |
| _int | int |
| _integer | int |
| _double | double |
| _float | float |
| _boolean | boolean |
| string | String |
| byte | Byte |
| long | Long |
| short | Short |
| int | Integer |
| integer | Integer |
| double | Double |
| float | Float |
| boolean | Boolean |
| date | Date |
| decimal | BigDecimal |
| bigdecimal | BigDecimal |
| object | Object |
| map | Map |
| hashmap | HashMap |
| list | List |
| arraylist | ArrayList |
| collection | Collection |
| iterator | Iterator |
除了以上这些,在 MyBatis 中还有部分内置别名,在 Configuration 的构造器中注册的,如 JDBC/MANAGED/JNDI/POOLED/UNPOOLED等,都是为了简化配置而设置的。
| 别名 | 映射的类型 |
|---|---|
| JDBC | JdbcTransactionFactory |
| MANAGED | ManagedTransactionFactory |
| JNDI | JndiDataSourceFactory |
| POOLED | PooledDataSourceFactory |
| UNPOOLED | UnpooledDataSourceFactory |
| PERPETUAL | PerpetualCache |
| FIFO | FifoCache |
| LRU | LruCache |
| SOFT | SoftCache |
| WEAK | WeakCache |
| DB_VENDOR | VendorDatabaseIdProvider |
| XML | XMLLanguageDriver |
| RAW | RawLanguageDriver |
| SLF4J | Slf4jImpl |
| COMMONS_LOGGING | JakartaCommonsLoggingImpl |
| LOG4J | Log4jImpl |
| LOG4J2 | Log4j2Impl |
| JDK_LOGGING | Jdk14LoggingImpl |
| STDOUT_LOGGING | StdOutImpl |
| NO_LOGGING | NoLoggingImpl |
| CGLIB | CglibProxyFactory |
| JAVASSIST | JavassistProxyFactory |
源码细节
通过阅读源码可知:
- 类型别名注册表中的别名统一为小写,所以建议使用小写。如果别名中包含有大写字母,MyBatis 也是转换为小写进行注册和获取的。
- 别名冲突问题,如果别名已经存在注册表中,则后注册的相同别名会抛出异常
TypeException。 - 通过包名批量注册别名需要注意,别名注册表忽略了匿名类(既然是匿名类当然没有名字,自然不能定义别名)、接口、成员类(成员类是在一个类中定义的类)。
- 通过包名批量注册别名时,默认别名为类名的全小写格式,如果存在
@Alias注解则会使用注解定义的别名。通过<typeAlias>标签定义别名时,忽略注解的别名。 - 通过
<typeAlias>标签定义别名时,如果没有指定alias属性,则默认别名为类名的全小写格式,如果存在@Alias注解则会使用注解定义的别名。<typeAliases> <typeAlias type="xx.xx.xxx.User"/> </typeAliases> - 别名解析规则:如果存在别名则获取实际类型,否则尝试通过类加载器加载类,可能会有类型转换异常!
总结
别名确实给项目开发提供了便捷,但是在大型项目中的别名冲突问题依然没有完美的方案,除非要求项目中不能有同名类,但是Java语言通过包边界可以定义同名的Java类。如果允许使用别名,那么项目组最好需要制定同名类别名的命名规范。如果允许自由发挥那就是灾难了,对于强迫症遇到命名就头疼!
本人愚见,如果项目不想使用别名,但由于MyBatis有内置别名,所以建议官方可以新增配置,指定是否使用别名!!
本文深入探讨MyBatis中的别名机制,包括别名的定义、作用、配置方式及其实现细节。介绍了如何通过XML配置和注解定义别名,以及MyBatis内置的一些常用类型别名。
990

被折叠的 条评论
为什么被折叠?



