2.2 MyBatis框架的核心配置文件
核心配置文件(mybatis-config.xml)配置了MyBatis框架的一些全局信息,包含数据库连接信息和MyBatis框架运行时所需的各种特性,以及设置和影响MyBatis框架行为的一些属性。这些信息只能编写在一个核心配置文件中,且不会轻易被改动。虽然在实际项目中需要开发人员编写或修改的配置文件并不多,但熟悉配置文件中各个元素的功能还是十分重要的。接下来将对MyBatis框架核心配置文件中的元素进行详细讲解。
2.2.1 mybatis-config.xml文件结构
mybatis-config.xml文件需要配置一些基本元素,但要注意的是,该文件的元素节点是有先后顺序的,其层次结构如图2.5所示。
图2.5 MyBatis框架的核心配置文件的层次结构
可以看出configuration元素是整个XML配置文件的根节点,其角色就相当于是MyBatis框架的总管,将所有的配置信息都存放在其中。MyBatis框架还提供了设置这些配置信息的方法。
这些子元素必须按照由上到下的顺序进行配置,否则MyBatis框架在解析XML配置文件时会报错。
Configuration可以从配置文件里获取属性值,也可以通过程序直接设置。它可供配置的内容如下。
1.<properties>元素
<properties>元素描述的都是外部化、可替代的属性。这些属性的获取方式有以下两种。
(1)通过外部指定的方式,即配置在典型的Java中,并使用这些属性对配置项实现动态配置。
①database.properties的代码如下。
②mybatis-config.xml的部分代码如下。
在上述代码中,driver、url、username、password等属性,都将用包含进来的database.properties文件值替换。
(2)直接配置为xml,并使用这些属性对配置项实现动态配置。
mybatis-config.xml的部分代码如下。
在上述代码中,driver、url、username、password将由properties元素设置的值替换。
思考:若使用两种方式,哪种方式优先呢?代码如下:
分析:这个例子中property子节点设置的user值和password值会先被读取,由于database.properties也设置了这两个属性,所以resource中同名属性将会覆盖property子节点的值。
结论:resource属性值的优先级高于property子节点的值。
2.<settings>元素
<settings>元素主要用于改变MyBatis框架运行时的行为,如开启二级缓存、开启延迟加载等。虽然不配置<settings>元素也可以正常运行MyBatis框架,但熟悉<settings>元素的配置内容及其作用还是十分必要的。
<settings>元素的常见配置及其描述如表2-2所示。
表2-2 <settings>元素的常见配置及其描述
续表
在表2-2中介绍了<settings>元素中的常见配置,这些配置在配置文件中的使用方式如下。
上面所介绍的配置内容大多数不需要开发人员进行配置,通常在需要时只配置少数几项即可。这里只需要了解可设置的参数值及其含义。
<settings>元素的作用是设置一些非常重要的选项,以改变运行中的行为,其常用配置如表2-3所示。
表2-3 <settings>元素的常用配置
其他配置可参考MyBatis开发手册进行学习。
3.<typeAliases>元素
<typeAliases>元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。通过与MyBatis框架的SQL映射文件相关联,减少输入多余的完整类名,以简化操作。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余,具体配置见示例7。
【示例7】 <typeAliases>元素的作用是配置类型别名
以上这种写法的弊端在于,如果一个项目中有多个POJO类时,需要一一进行配置,所以有更加简化的写法,就是通过package的name属性直接指定包名,MyBatis框架会自动扫描指定包下的JavaBean,并默认设置一个JavaBean的非限定类名。上述示例中,<typeAliases>元素的子元素<typeAlias>中的type属性用于指定需要被定义别名的类的全限定名;alias属性的属性值user就是自定义的别名,它可以代替cn.dsscm.pojo.User使用在MyBatis框架文件的任何位置。如果省略alias属性,则会默认将类名首字母小写后的名称作为别名。
当POJO类过多时,还可以通过自动扫描包的形式自定义别名,具体配置见示例8。
【示例8】 默认名称为JavaBean的非限定类名
那么UserMapper.xml的配置如下:
在上述示例中,<typeAliases>元素的子元素<package>的name属性用于指定要被定义别名的包,MyBatis框架会将所有cn.dsscm.pojo包中的POJO类以首字母小写的非限定类名来作为其别名,如cn.dsscm.pojo.User的别名为user等。
需要注意的是,上述方式的别名只适用于没有使用注解的情况。如果在程序中使用了注解,则别名为其注解的值,具体配置见示例9。
【示例9】 使用注解定义别名
另外,对于基础数据类型,MyBatis框架已经为许多常见的Java类型内建了相应的类型别名,一般都与其映射类型一致,并且它们都是大小写不敏感的,如映射的类型int、Boolean、String、Integer等,它们的别名是int、Boolean、String、Integer。MyBatis框架还默认为许多常见的Java类型(如数值、字符串、日期和集合等)提供了相应的类型别名,其默认别名如表2-4所示。
表2-4 MyBatis框架的默认别名
表2-4中所列举的别名在MyBatis框架中可直接使用,但由于别名不区分大小写,所以在使用时要注意重复定义的覆盖问题。
4.typeHandler元素
MyBatis框架在预处理语句(PreparedStatement)中设置一个参数或从结果集(ResultSet)中取出一个值时,都会用其框架内部注册的typeHandler(类型处理器)进行相关处理。typeHandler元素的作用就是将预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者在从数据库取出结果时将jdbcType转换为javaType。
为了方便转换,MyBatis框架提供了一些默认的类型处理器,其常用类型处理器如表2-5所示。
表2-5 MyBatis框架的常用类型处理器
当MyBatis框架所提供的这些类型处理器不能够满足需求时,还可以通过自定义的方式对类型处理器进行扩展(自定义类型处理器可以通过实现TypeHandler接口或继承BaseTypeHandle类来定义)。typeHandler就是用于在配置文件中注册自定义的类型处理器的,其使用方式有两种,具体内容如下。
(1)注册一个类的类型处理器
在上述代码中,子元素handler属性用于指定在程序中自定义的类型处理器类。
(2)注册一个包中所有的类型处理器
在上述代码中,子元素<package>的 name属性用于指定类型处理器所在的包名,使用此种方式后,系统会在启动时自动扫描cn.dsscm.type包下所有的文件,并把它们作为类型处理器。
5.<objectFactory>元素
MyBatis框架每次创建结果对象的新实例时,都会使用一个对象工厂(ObjectFactory)的实例来完成。MyBatis框架中默认的<objectFactory>元素的作用就是实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在时通过参数构造方法实例化。在通常情况下,使用默认的<objectFactory>元素即可,MyBatis框架中默认的<objectFactory>元素是由org.apache.ibatis.reflection.factory.DefaultObjectFactory来提供服务的。大部分场景下都不用配置和修改,但如果想覆盖<objectFactory>元素的默认行为,则可以通过自定义<objectFactory>元素来实现。
(1)自定义一个对象工厂。自定义的对象工厂需要实现ObjectFactory接口,或者继承DefaultObjectFactory类。由于DefaultObjectFactory类已经实现了ObjectFactory接口,所以通过继承DefaultObjectFactory类实现即可,示例代码如下。
(2)在配置文件中使用<objectFactory>元素配置自定义的ObjectFactory,示例代码如下:
由于自定义<objectFactory>元素在实际开发时不经常使用,所以这里读者只要了解即可。
6.<plugins>元素
MyBatis框架允许在已映射语句执行过程中的某一点进行拦截调用,这种拦截调用是通过插件来实现的。<plugins>元素的作用就是配置用户所开发的插件。如果用户想要进行插件开发,则必须先了解其内部运行原理,因为在试图修改或重写已有方法的行为时,很可能会破坏MyBatis框架原有的核心模块。关于插件的使用,本书不做详细讲解,只要了解<plugins>元素的作用即可,有兴趣的读者可查找官方文档等资料自行学习。
7.<environments>元素
在配置文件中,<environments>元素用于对环境进行配置。MyBatis框架的环境配置实际上就是数据源的配置,即配置多种数据库。
MyBatis框架可以配置多套运行环境,如开发环境、测试环境、生产环境等,通过灵活选择不同的配置可将SQL映射应用到不同的数据库环境上。这些不同的运行环境即可通过<environments>元素来配置,但是不管增加几套运行环境都必须选出唯一一个运行环境,这是因为每个数据库都是对应一个SqlSessionFactory实例的,应指明哪个运行环境将被创建,并把运行环境中设置的参数传递给SqlSessionFactoryBuilder,具体配置如下。
在上述示例代码中,<environments>元素是环境配置的根元素,它包含一个default属性,该属性用于指定默认的环境id。<environment>元素是<environments>元素的子元素,可以定义多个,其id属性用于表示所定义环境的id值。在<environment>元素中,包含事务管理和数据源的配置信息,其中<transactionManager>元素用于配置事务管理,它的type属性用于指定事务管理的方式,即使用哪种事务管理器;<dataSource>元素用于配置数据源,它的type属性用于指定使用哪种数据源。
需要注意以下几个关键点。
(1)默认运行id。通过default属性来指定当前的运行环境id为development,对于环境id的命名要确保唯一。
(2)transactionManager事务管理器,设置其类型为JDBC,可直接使用JDBC的提交和回滚功能,依赖于从数据源获得连接来管理事务的生命周期。
(3)dataSource使用标准的数据源接口配置JDBC连接对象的资源。MyBatis框架提供了3种数据源类型(UNPOOLED、POOLED和JNDI),这里使用POOLHD数据源类型。该类型利用“池”的概念将JDBC连接对象组织起来,避免创建新连接实例时所必需的初始化和认证时间,是MyBatis框架实现的简单数据库连接池类型。它使数据库连接可被复用,不必在每次请求时都去创建一个物理连接。这对于高并发的Web应用是一种流行的处理方式,有利于快速响应请求。
在MyBatis框架中可以配置两种类型的事务管理器,分别是JDBC和MANAGED。关于这两个事务管理器的描述如下。
(1)JDBC:此配置可直接使用JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务的作用域。
(2)MANAGED:此配置从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。在默认情况下,它会关闭连接,但一些容器并不希望这样,为此可以将closeConnection属性设置为false以阻止其关闭行为。
如果项目中使用的框架是Spring+ MyBatis,则没有必要在MyBatis框架中配置事务管理器。因为在实际开发中会使用Spring框架自带的管理器来实现事务管理。
对于数据源的配置,MyBatis框架提供了UNPOOLED、POOLED和JNDI 3种数据源类型,具体内容如下。
(1)UNPOOLED类型。
配置此数据源类型后,在每次被请求时都会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。
UNPOOLED类型的数据源需要配置5种属性,如表2-6所示。
表2-6 UNPOOLED类型数据源需要配置的属性
(2)POOLED类型。
此数据源利用“池”的概念将JDBC连接对象组织起来,可避免在创建新的连接实例时所需要初始化和认证的时间。这种方式使并发Web应用能快速地响应请求,是当前流行的处理方式(本书中使用的就是此种方式)。配置此类型数据源时,除了表2-6中的5种属性,还可以配置更多的属性,如表2-7所示。
表2-7 POOLED类型数据源可额外配置的属性
续表
(3)JNDI类型。
此数据源可以在EJB或应用服务器等容器中使用。容器集中或在外部配置数据源后,放置一个JNDI上下文的引用。配置JNDI数据源时,只需要配置两个属性,如表2-8所示。
表2-8 JNDI类型数据源需要配置的属性
8.<mappers>元素
<mappers>元素用来定义SQL的映射语句。表示告诉MyBatis框架去哪里找到相应的SQL映射文件,可以使用类资源路径或URL等。
在配置文件中,<mappers>元素用于指定MyBatis框架映射文件的位置,一般使用以下4种方式引入映射器文件,具体代码如下。
(1)使用类路径引入。
(2)使用本地文件路径引入。
(3)使用接口类引入。
(4)使用包名引入。
上述4种引入方式都非常简单,可以根据实际项目需要选取使用。这些配置只是告诉MyBatis框架如何找到SQL映射文件,其更详尽的信息配置则在每个SQL映射文件里,相关内容将在后续章节讲述。
2.2.2 DTD文件的引入
MyBatis框架有两种配置文件:核心配置文件(mybatis-config.xml)和SQL映射文件(mapper.xml)。这两种配置文件都需要手动引入各自的DTD文件(mybatis-3-config.dtd和mybatis-3-mapper.dtd),并在IDE中进行相应配置,否则在编写配置文件时,其节点元素及属性等将不能自动联想。具体引入方法如下。
1.DTD文件的位置
这两个DTD文件都在mybatis-3.5.1里,可以压缩包形式解压并打开。DTD文件路径为mybatis-3.5.1.jar\org\apache\ibatis\builder\xml,如图2.6所示。
图2.6 DTD文件的位置
将两个文件复制出来,放在一个统一的位置(如D:\)中,以方便下一步的手动引入。
2.新增 XML Catalog
在MyEclipse的工具栏中,选择“Window”→“Preferences”,如图2.7所示。
图2-7 新增 XML Catalog(1)
选择“XML Catalog”→“User Specified Entries”,单击“Add”按钮,如图2.8所示,并添加相关内容,相关设置如下。
(1)Location:单击“File System”按钮,选择DTD文件位置(D:\mybatis-3-config.dtd)或者选择将该DTD文件放入本项目工程中的某个固定位置,单击“Workspace”按钮进行加入。
(2)Key type:Public ID (默认即可)。
(3)Key:-//mybatis.org//DTD Config 3.0//EN(与mybatis-config.xml文件头中的“-//mybatis.org// DTDConfig 3.0//EN”相同)。
图2.8 新增 XML Catalog(2)
保存配置后,即可在编写mybatis-config.xml时,实现自动联接节点元素及属性等操作,方便用户操作。
mapper.xml文件的配置同上,引入mybatis-3-mapper.dtd文件即可,此处不再赘述。
2.2.3 技能训练
上机练习2 实现供应商表的查询
需求说明
在上机练习1的基础上,完成以下操作。
(1)增加数据库测试运行环境(如SQL Server数据库或者另一台测试服务器的MySQL数据库),并完成由开发环境到测试环境的切换。
(2)更改praperties元素对于数据库信息的配置方式,直接配置为xml。使用这些属性实现动态配置,并观察resource属性值和property子节点配置的优先级。
(3)使用typeAliases元素给POJO类增加别名。
(4)对于mappers元素,使用URL方式获取SQL映射文件。