MyBatis 全局配置文件详解(七)

MyBatis 配置文件作用

MyBatis配置文件包含影响 MyBatis 框架正常使用的功能设置和属性信息。它的作用好比手机里的设置图标,点击这个图标就可以帮助我们查看手机的属性信息和设置功能。其实,几乎每个框架都有一个配置文件,好比几乎每部手机也都有一个设置图标。

作为 MyBatis 框架使用者,很有必要熟悉和掌握 MyBatis 配置文件的常见功能设置和属性信息,这会帮助我们更好的使用 MyBatis 框架。

MyBatis 配置文件类型

MyBatis配置文件有两种类型,如下:

  • 全局配置文件(如 mybatis-config.xml)
  • Mapper XML映射文件(如 UserMapper.xml)

全局配置文件详解

  • properties 设置

    properties 配置的属性可在外部 Java 属性文件中动态替换,也可通过 properties 元素的子元素来替换。

    方式一:在外部 Java 配置文件中配置属性

    首先,在 Java 工程的 src 下创建名为 config.properties 的 Java 属性文件,内容如下:

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
    username=root
    password=
    

    接着,在 mybatis-config.xml 全局配置文件的 configuration 元素下添加 properties 属性,内容如下:

    <!-- resource表示Java属性文件名 -->
    <properties resource="config.properties">
    </properties>
    

    最后,使用 config.properties 文件中的配置项替换需要动态配置的属性值

     <!--设置数据库驱动 -->
    <property name="driver" value="${driver}"/>
     <!--设置数据库url地址-->
    <property name="url" value="${url}"/>
    

    方式二:通过 properties 元素的子元素配置属性

    <properties resource="config.properties">
      <property name="driver" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
      <property name="username" value="root"/>
      <property name="password" value=""/>
    </properties>
    

    使用子元素配置项替换需要动态配置的属性值

    <!--设置数据库驱动 -->
    <property name="driver" value="${driver}"/>
     <!--设置数据库url地址-->
    <property name="url" value="${url}"/>
    <!--设置数据库用户名-->
    <property name="username" value="${username}"/>
    <!--设置数据库密码-->
    <property name="password" value="${password}"/>
    

    在实际项目开发中,采用最多的是方式一,即利用 properties 属性读取 Java 属性文件的方式替换 mybatis-config.xml 全局配置文件中需要动态修改的配置属性值,比如数据库的用户名、密码。好处就是以后数据库变了,就不用去修改 MyBatis 全局配置文件,只需要修改 config.properties 的属性值即可,这样便于项目维护。

  • settings 设置

    settings 用于设置 MyBatis 框架的功能开关,一共可以设置四个功能开关,如下:

    <configuration>
    	<settings>
      	<!-- 缓存开关(默认值true)-->
      	<setting name="cacheEnable" value="true"/>
      	<!-- 延时加载开关(默认值false)-->
      	<setting name="lazyLoadingEnable" value="false"/>
      	<!-- 配合延时加载开关使用(默认值false)-->
    		<setting name="aggressiveLazyLoading" value="false"/>
    		<!-- 自动驼峰命名规则映射开关(默认值false)-->
      	<setting name="mapUnderscoreToCamelCase" value="false"/>
    	</settings>
      ...
    </configuration>  
    

    缓存开关的背后涉及 MyBatis 的缓存机制,这个后面会专门讲解缓存机制的原理。

    延时加载开关的背后涉及 MyBatis 的延时加载机制,这个后面也会专门讲解延时加载机制的原理。

    前两个都是硬骨头不好啃,我们这里先挑软柿子捏,最后一个设置比较容易理解,就是自动驼峰命名规则映射开关。这个开关有什么作用呀,它默认是关闭的,什么时候需要打开它呢?

    首先我们需要知道两个知识点:经典数据库命名规则和 Java 驼峰命名规则

    • 经典数据库命名规则:如果数据库字段由多个单词组成,则通过下划线连接多个单词,如 goods_name

    • Java 驼峰命名规则:如果 Java 的类名、方法名或属性名由多个单词组成,则第二个单词首字母大写,如goodsName

    当 MyBatis 进行 ORM 映射时,如果数据库的字段采用的是经典数据库命名规则,而 Java 的属性或成员变量采用的是驼峰命名规则,那么将导致映射时数据库字段和 Java 的属性或成员变量之间无法正确匹配。通过开启自动驼峰命名规则映射开关后,MyBatis 就会自动去掉数据库字段的下划线,让其变得和 Java 能够匹配。

    下面举个例子:

    数据库字段:user_name

    Java属性:userName

    查询接口方法的映射语句如下:

    <!--select查询语句 id表示接口方法名 resultType表示将数据库结果集自动映射为UserEntity-->
    <select id="selectUserByAge"  resultType="entity.UserEntity">
       select * from tb_user where age > #{age}
    </select>
    

    如果你观察仔细,可能会发现之前我们使用的 resultMap 进行结果集映射,但是为何这里变成了 resultType;那么resultMap 与 resultType 这两个元素有何区别呀?resultMap 是 MyBatis 映射文件中非常重要的元素,下面我会专门讲解。这里的 resultType 的意思就是将查询的结果集自动映射为 UserEntity 实例,要求数据库字段名要和 Java 属性名相同才能自动映射哈。

    执行查询操作如下:

    [entity.UserEntity{id=1, userName='null', password='123456', name='张三三', age=22, sex=1, birthday=Sun Sep 02 00:00:00 IRKST 1990, created='2020-06-17 09:30:58.0', updated='2020-06-17 09:30:58.0'}]
    

    大家看到了吗?UserEntity实例中其他属性都有值,但 userName 的属性值为 null。原因就是查询的结果集映射到UserEntity 时,user_name 和 userName 不匹配导致的。

    那怎么办呢?首先想到的可以修改数据库字段名,改为 userName,这样不就和 Java 属性名匹配了;或者反过来,修改 Java 的属性名,改为 user_name,不过所有使用 userName 属性的地方都需要改哦。

    假设数据库字段和 Java 属性名都不允许修改,那怎么办呢?

    可以在 mybatis-config.xml 中添加 settings 设置,如下:

    <configuration>
        <settings>
          	<!-- 开启自动驼峰命名规则映射开关 -->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
        ...
    </configuration>
    

    再执行查询操作:

    [entity.UserEntity{id=1, userName='zs', password='123456', name='张三三', age=22, sex=1, birthday=Sun Sep 02 00:00:00 IRKST 1990, created='2020-06-17 09:30:58.0', updated='2020-06-17 09:30:58.0'}]
    

    看到了吧,userName 属性有值了,开启自动驼峰命名规则映射开关后, user_name 和 userName 不匹配问题得到完美解决了。

    现在总算明白了开启自动驼峰命名规则映射开关的作用了吧。

  • typeAliases 设置

    typeAliases 类型别名,就是为 Java 类全路径名(即包名+类名)取一个别名。它只和 XML 配置有关,存在的意义仅在于用来减少类全路径名的冗余。啥意思呀,看例子就明白了。

     <!--结果集映射(ORM)-->
     <resultMap id="userResultMap" type="entity.UserEntity">
       ...
     </resultMap>   
    

    以上是 Mapper 接口映射 XML 文件中,使用 resultMap 元素将数据库结果集映射为实体类,其中 type 属性值是实体类的类全路径名。想一想,如果实体类的包名很长,是不是引用起来很麻烦,这时候 typeAliases 设置就可以解决这个麻烦。

    typeAliases 设置如下

    <configuration>
        <typeAliases>
            <!--type:实体类的全路径名。alias:别名,通常首字母大写-->
            <typeAlias type="entity.UserEntity" alias="UserEntity"/>
        </typeAliases>
        ...
    </configuration>
    

    这样就给 UserEntity 类的类全路径名取了一个别名 UserEntity,现在重新修改 Mapper 接口映射 XML 文件,如下:

     <!--结果集映射(ORM)-->
     <resultMap id="userResultMap" type="UserEntity">
       ...
     </resultMap>   
    

    type 属性就可以直接使用别名 UserEntity,MyBatis 框架会自动通过别名 UserEntity 找到实体类的全路径名。

    爱动脑经的你,可能会提出一个问题,那就是如果很多实体类都要取别名,那就意味着每个实体类都要去配置。这玩意儿似乎比原先的方式更麻烦,简直是个鸡肋嘛。

    别着急,你说的没错,这点 MyBatis 框架开发者也早想到了,并提供了解决方案,如下:

    <configuration>
        <typeAliases>
            <!--name:实体类所在包名-->
            <package name="entity" />
        </typeAliases>
        ...
    </configuration>
    

    以上配置的意思就是只配置实体类的包路径,然后扫描指定包路径下的所有类,扫描之后的别名就是类名(不区分大小写),建议使用的时候和类名一致。现在只需要把所有的实体类放到同一个包路径下,就可以配置一次,所有实体类自动取别名,一劳永逸。

  • environments 设置

    MyBatis 可以配置成适应多种环境,例如,开发、测试和生产环境需要有不同的配置。尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。

    <configuration>
        <!-- 数据库配置 -->
        <environments default="development"><!--default表示选择默认的环境-->
            <environment id="development"> <!--开发环境-->
                <!-- 事务管理器,JDBC类型的事务管理器 -->
                <transactionManager type="JDBC" />
                <!-- 数据源,池类型的数据源 -->
                <dataSource type="POOLED">
                    <!--设置数据库驱动 -->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <!--设置数据库url地址-->
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
                    <!--设置数据库用户名-->
                    <property name="username" value="root"/>
                    <!--设置数据库密码-->
                    <property name="password" value=""/>
                </dataSource>
            </environment>
            <environment id="test"> <!--测试环境-->
                <!-- 事务管理器,JDBC类型的事务管理器 -->
                <transactionManager type="JDBC" />
                <!-- 数据源,池类型的数据源 -->
                <dataSource type="POOLED">
                    <!--设置数据库驱动 -->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <!--设置数据库url地址-->
                    <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8"/>
                    <!--设置数据库用户名-->
                    <property name="username" value="root"/>
                    <!--设置数据库密码-->
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    

    以上配置中我配了两个环境:一个开发环境和一个测试环境,而当前默认使用是开发环境。如果我想切换为测试环境,只需要设置 default=“test” 即可。

    虽然,以上方式可以做到很方便的分离多个环境,但是实际项目开发中,我们更多的是选择使用 Spring 框架来管理数据源,来做到分离多个各种环境。

    这样跟你说吧,实际项目开发中 MyBatis 框架一般很少单打独斗,更多的是和大名鼎鼎的 Spring 框架集成起来使用。那 MyBatis 框架如何与 Spring 框架集成,这个首先你得掌握 Spring 框架再说。目前 MyBatis 框架和 Spring 框架都是 JavaEE(Java企业级开发) 的主流框架,是 Java 程序员居家旅游必备技能哈。

  • mappers 设置

    mappers 设置的作用是告诉 MyBatis 到哪里去找 Mapper 接口映射文件,它有 3 种设置方式:

    • 使用相对于类路径的资源引用(映射文件方式使用)
    • 使用映射器 Mapper 接口实现类的完全限定类名(注解方式使用)
    • 使用映射器 Mapper 接口包路径(注解方式使用)
    <!-- 使用相对于类路径的资源引用 -->
    <mappers>
      <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
    
    <!-- 使用映射器接口实现类的完全限定类名 -->
    <mappers>
      <mapper class="mapper.UserMapper"/>
    </mappers>
    
    <!-- 使用映射器 Mapper 接口包路径 -->
    <mappers>
    	<package name="mapper" />
    </mappers>
    

    我们之前的 mappers 设置用的是第一种方式,这种方式需要创建 Mapper 映射文件,而且每增加一个 Mapper 映射文件就需要使用 mapper 元素配置相应的资源引用。

总结

  • properties 设置:通过外部 Java 属性文件动态替换全局配置文件属性值
  • settings 设置:设置 MyBatis 功能开关
  • typeAliases 设置:为类路径取别名简化配置
  • environments 设置:可以配置多个环境,同时满足开发、测试和运维不同环境需要
  • mappers 设置:配置 Mapper 映射文件路径
作者:Binge
本文版权归作者和博客园共有,转载必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/binbingg/p/13747305.html