mybatis 配置详解

全局配置文件

官网示例如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <!-- 环境变量列表 -->  
  <environments default="development">
    <!-- 至少配置一个环境 -->  
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <!-- mapper 映射文件列表 -->  
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>
  1. 根节点是 configuration(所有配置信息都会保存在一个 configuration 对象中
  2. 可以有多个环境变量配置,意味着支持多数据源
  3. 示例没有写完所有配置,还有别的比如 属性、别名、插件 等等

完整的配置

  • configuration(配置)
    1. properties(属性)
    2. settings(设置)
    3. typeAliases(类型别名)
    4. typeHandlers(类型处理器)
    5. objectFactory(对象工厂)
    6. plugins(插件)
    7. environments(环境配置)
      • environment(环境变量)
        • transactionManager(事务管理器)
        • dataSource(数据源)
    8. databaseIdProvider(数据库厂商标识)
    9. mappers(映射器)

properties

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <!-- 定义 properties -->
    <properties>
        <property name="jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="jdbc.url" value="jdbc:mysql://localhost:3306/test" />
        <property name="jdbc.username" value="root"/>
        <property name="jdbc.password" value="root"/>
    </properties>
	...
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 这里能用已定义的 properties -->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
	...

</configuration>

对于关键信息配置,常见做法是独立一个配置文件,通过 resource 引入这个配置文件,如: <properties resource="org/mybatis/example/config.properties" />

settings

<settings>
    <!-- 缓存开关(二级缓存) -->
    <setting name="cacheEnabled" value="true"/>
    <!-- 一级缓存 -->
    <setting name="localCacheScope" value="SESSION"/>
    
    <!-- 懒加载配置 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="true"/>
    <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    
    <!-- 自动映射配置 -->
    <setting name="autoMappingBehavior" value="PARTIAL"/>
    <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
    <setting name="mapUnderscoreToCamelCase" value="false"/>
    
    <!-- 日志配置,STDOUT_LOGGING -->
    <setting name="logPrefix" value="exampleLogPreFix_"/>
    <setting name="logImpl" value="SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING"/>
    
     <!-- 查询结果为空时,默认是直接返回 null,如果配置成 true 会返回一个空对象(对象不为空,所有属性没有值)-->
    <setting name="returnInstanceForEmptyRow" value="false"/>
    <!-- 字段为空是否映射到实体属性(调用 setter,如果是 map 就是 put 方法)对 map 有影响-->
    <setting name="callSettersOnNulls" value="false"/>
    <!-- 是否允许单一语句返回多结果集,这个不用想肯定要打开 -->
    <setting name="multipleResultSetsEnabled" value="true"/>
    <!-- 使用列标签代替列名 -->
    <setting name="useColumnLabel" value="true"/>
    <!-- 允许 JDBC 支持自动生成主键 -->
    <setting name="useGeneratedKeys" value="false"/>
    <!-- 配置默认的执行器 -->
    <setting name="defaultExecutorType" value="SIMPLE"/>
    <!-- 设置超时时间,单位秒,默认为空 -->
    <setting name="defaultStatementTimeout" value="25"/>
    <!-- 一次性返回多少数据,默认是 null 返回全部 -->
    <setting name="defaultFetchSize" value="100"/>
    <!-- 分页设置。mybatis 自带的分页是内存中的假分页,不要用 -->
    <setting name="safeRowBoundsEnabled" value="false"/>
    <!-- 是否允许在嵌套语句中使用结果处理器。一对多多对多场景,肯定也要映射结果撒 -->
    <setting name="safeResultHandlerEnabled" value="true"/>
    <!-- 指定动态 SQL 生成使用的默认脚本语言。也就是处理动态sql的类 -->
    <setting name="defaultScriptingLanguage" value="org.apache.ibatis.scripting.xmltags.XMLLanguageDriver"/>
    <!-- 上面是处理动态 SQL,这个是来处理枚举的 -->
    <setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumTypeHandler"/>
    
    <!-- 不常用的 -->
    <setting name="proxyFactory" value="CGLIB | JAVASSIST"/>
    <setting name="vfsImpl" value="org.mybatis.example.YourselfVfsImpl"/>
    <setting name="useActualParamName" value="true"/>
    <setting name="configurationFactory" value="org.mybatis.example.ConfigurationFactory"/>
    <setting name="jdbcTypeForNull" value="OTHER"/>
</settings>

有一些单独说明一下

  1. 缓存配置开关:mybatis 分为 一级缓存、二级缓存、自定义的三级缓存,后面专门讲
  2. 懒加载配置
    1. 只配置 lazyLoadingEnabled,所有方法都懒加载(但是有些特殊方法不能懒加载)
    2. aggressiveLazyLoading 简而言之是有特殊方法不懒加载,lazyLoadTriggerMethods 指明哪些是特殊方法
  3. 自动映射配置
    1. autoMappingBehavior:查询结果列和实体属性怎么映射
      1. NONE 不映射;
      2. PARTIAL 是集合的字段不映射;
      3. FULL 集合字段也映射
    2. autoMappingUnknownColumnBehavior:查询结果列对应不上实体属性怎么处理
      1. NONE 不做任何反应
      2. WARNING 日志输出警告(日志是 warning 级别,AutoMappingUnknownColumnBehavior)
      3. FAILING 抛异常(SqlSessionException)
    3. mapUnderscoreToCamelCase:查询结果列自动转驼峰

typeAliases

别名配置,两种方式

  1. 方式一

    <typeAliases>
      <typeAlias alias="Author" type="domain.blog.Author"/>
      <typeAlias alias="Blog" type="domain.blog.Blog"/>
    </typeAliases>
    
  2. 方式二

    配置文件中只写包名,这个包下的 java 类都会以类名作为别名(第一个字幕小写)

    <typeAliases>
      <package name="domain.blog"/>
    </typeAliases>
    

    如果包下的某个类不想使用默认的别名,还可以单独配置

    // 默认是 author,使用注解 @Alias 自定义别名
    @Alias("author1")
    public class Author {
        ...
    }
    

typeHandlers

类型处理器,sql 查询结果字段的 jdbc 类型处理成 java 类型,比如 jdbc 的 datetime、varchar 转为 java 的 Date、String 等

有需要可以自定义类型处理器,继承 BaseTypeHandler 重写里面的方法即可。比如数据脱敏,性别枚举转换等

一般不会全局配置类型处理器,一般都是某些表的个别字段做处理,在 mapper 映射文件中再说

objectFactory

对象工厂的目的是创建结果集对应的对象,一般使用默认的就行了不需要扩展,但是对于某些特殊的场景还是有点用:比如查询学生列表,想给每个学生根据成绩再增加一个排名。其实可以 mybatis 映射完成后,在 java 中遍历结果集,然后再设置排名

plugins

非常重要,后面专门讲插件

environments

用来配置数据环境的,事务、数据源、连接使用池化技术等,可以配置多个,但是必须指定一个作为默认环境

虽然可以使用多个环境,但是每个 SqlSessionFactory 实例只能选择一种环境

配置示例:

<environments default="dev">
    <!-- 开发环境 -->
    <environment id="dev">
        <!-- 事务管理器,可选 JDBC 和 MANAGED,默认是 JDBC -->
        <transactionManager type="JDBC">
            <!-- 跳过自动提交 -->
        	<property name="skipSetAutoCommitOnClose" value="true" />
        </transactionManager>
        <!-- 数据源,不使用数据库连接池,也就不用配置最大连接数等 -->
        <dataSource type="UNPOOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
    
    <!-- 测试环境 -->
    <environment id="sit">
        ...
    </environment>
    
    <!-- 准生产环境 -->
    <environment id="uat">
        ...
    </environment>
    
    <!-- 生产环境 -->
    <environment id="prod">
        ...
    </environment>
</environments>

环境总的来说分为两部分:事务管理器数据源,分别来说下

  1. 事务管理器
    1. 事务包含 3 个步骤,提交、回滚、关闭连接。为了统一,所有的数据库对应的数据管理器都会有这三个步骤,但是某些数据库不仅不需要,反而变麻烦了,比如 mysql 本身就是启用了自动提交,这里为了统一还是为 启用事务、然后再提交。可以配置 skipSetAutoCommitOnClose = true 来跳过自动提交步骤
    2. 可选的有 JDBCMANAGED。JDBC:使用 JDBC 的事务管理器,MANAGED:自身不会实现事务管理,使用 web 容器(如 EJB,webLogic)来实现,如果是不是 web 项目,意味着事务会无效。 JDBC 和 MANAGED 其实是个别名,分别对应 JdbcTransaction 和 ManagedTransaction 两个类来实现的
    3. 如果是 spring 项目,不用配置事务管理器了,因为 Spring 模块会使用自带的管理器来覆盖前面的配置,具体的实现类是 SpringManagedTransaction
  2. 数据源
    1. 包含数据库连接信息、用户名、密码、超时、隔离级别
    2. 可选的类型有三个:UNPOOLEDPOOLEDJNDI 。UNPOOLED:不适用池化技术;POOLED:使用池化技术,意味着配置信息在 UNPOOLED 的基础上还能配置连接池信息,比如 最大连接数、连接空闲存活时间等;JNDI:同事务管理的,也是兼容 EJB 这些容器的,现在的项目都没这些老古董了

databaseIdProvider

数据库厂商标识,卷不动了

mappers

mybatis 的全局配置已经 ok 了,现在就该轮到各个映射文件了 ,首先要知道这些文件在什么地方,多种方式来指定,如下:

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

<!-- 使用完全限定资源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

<!-- 将包内的映射器接口全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

mapper 映射文件

完整的配置

  • cache – 该命名空间的缓存配置。
  • cache-ref – 引用其它命名空间的缓存配置。
  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
  • parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
  • sql – 可被其它语句引用的可重用语句块。
  • insert – 映射插入语句。
  • update – 映射更新语句。
  • delete – 映射删除语句。
  • select – 映射查询语句。

这个打交道的次数很多了,namespace,id,select,update 这些已经神熟悉了,捡一些说一下

  1. cache、cache-ref:mybatis 分为 一级缓存、二级缓存、自定义的三级缓存,后面专门讲

  2. resultMap

    1. 配合 select 标签使用,处理查询结果的列和实体属性映射关系
    2. 当查询结果列和实体属性名不对应的时,使用 as 别名
    3. 一对多、多对多,后面专门讲
  3. sql:sql 片段,目的是将重复的 SQL 语句抽取出来,放到 <sql> 标签中,可以进行复用

    <!-- sql 片段 -->
    <sql id="where-title-author">
        <if test="title!=null">
            title like concat('%',#{title},'%')
        </if>
        <if test="author!=null">
            and author = #{author}
        </if>
    </sql>
    
    <!-- 使用 -->
    <select id="queryBlogIf" resultType="blog" parameterType="map">
        select * from blog
        <where>
            <include refid="where-title-author"></include>
        </where>
    </select>
    
    <!-- sql 片段 -->
    <sql id="querySql">
        ID, NAME, AGE
    </sql>
    
    <!-- 使用 -->
    <select id="queryAll" resultType="student">
        select <include refid="querySql" /> from t_student
    </select>
    
posted @ 2023-05-24 17:31  CyrusHuang  阅读(32)  评论(0编辑  收藏  举报