深入MyBatis配置文件

我们都知道MyBatis的持久化操作离不开SqlSessionFactory对象,这个对象是整个数据库映射关系经过编译后的内存镜像,该对象的openSession()方法可以打开SqlSession对象.该对象由由SqlSessionFactoryBuilder加载MyBatis的配置文件产生.

先贴一张MyBatis初始化的基本过程,如下图:


上图所示,MyBatis初始化要经过以下几步:

  1. 调用SqlSessionFactoryBuilder对象的build(inputStream)方法;
  2. SqlSessionFactoryBuilder会根据输入流inputStream等信息创建XMLConfigBuilder对象;
  3. SqlSessionFactoryBuilder调用XMLConfigBuilder对象的parse()方法;
  4. XMLConfiguBuilder对象解析XML配置文件返回Configuration对象;
  5. SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象;
  6. SqlSessionFactoryBuilder返回DefaultSessionFactory对象给客户端,供客户端调用;

由此可见,SqlSessionFactory是根据MyBatis的配置文件mybatis-config.xml创建的,接下来我们就来重点研究下MyBatis配置文件中常用属性的意义.

MyBatis的配置文件结构

MyBatis的配置文件包含了影响MyBatis行为的信息,文档的结构如下:
顶层configuration配置

  • properties 属性
  • settings 设置
  • typeAliases 类型命名
  • typeHandlers 类型处理器
  • objectFactory 对象工厂
  • plugins 插件
  • environments 环境
    • environment 环境变量
      • transactionManager 事务管理器
      • dataSource 数据源
  • databaseIdProvider 数据库厂商标识
  • mappers 映射器

properties属性

这些属性都是可外部配置且可动态替换的,既可以在典型的Java属性文件中配置,亦可通过properties元素的子元素来传递.

可以再CLASSPATH中增加一个db.properties的Java属性文件.

driver=oracle.jdbc.driver.OracleDriver
ur=jdbc:oracle:thin:@127.0.0.1:1526:mybatis
username=root
password=root

在配置文件中配置<properties.../>属性:
<properties resource="db.properties"/>
其中的属性就可以在整个配置文件中使用来替换需要动态配置的属性值.

 <dataSource type="POOLED">
   <property name="driver" value="${driver}"/>
   <property name="url" value="${url}"/>
   <property name="username" value="${username}"/>
   <property name="password" value="${password}"/>
 </dataSource>

settings设置

一个配置完成的settings元素示例如下,具体含义这里不再列举,可以自行google.


typeAliases 类型命名

类型别名是为Java类型设置的一个短的名字.它只和XML配置有关,存在的意义仅在于用来减少类完全限定名的冗余.

<typeAliases>
  <typeAlias alias="user" type="org.ccgogoing.domian.User"/>
</typeAliases>

当这样配置时,user可以用在任何使用org.ccgogoing.domain.User的地方.
也可以指定一个包名,MyBatis会在包名下面搜索需要的Java Bean

<typeAliases>
  <package name="org.ccgogoing.domian"/>
</typeAliases>

每一个在包org.ccgogoing.domain中的Java Bean,在没有注解的情况下,会使用Bean的首字母小写的非限定类名来作为它的别名.比如org.ccgogoing.domain.User的别名为user,若有注解,则别名为其注解值.

@Alias("user")
public class User {
    ...
}

typeHandlers 类型处理器

无论是MyBatis在预处理语句(preparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成Java类型,下图描述了一些默认的类型处理器.

objectFactory 对象工厂

MyBatis每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成.默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要买在参数映射存在的时候通过参数构造方法来实例化.如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现.

environments 配置环境

MyBatis的环境配置实际就是数据源的配置.MyBatis可以配置多种环境,这种机制使得MyBatis可以将SQL映射应用于多种数据库中.例如,开发,测试盒生产环境需要不同的配置;多个生产数据库想使用相同的sql映射,等等.

尽管可以配置多个环境,但是每个SqlSessionFactory实例只能选择一个环境,即每个数据库对应一个SqlSessionFactory实例.所以如果你想连接两个数据库,就需要创建两个SqlSessionFactory实例,每个数据库对应一个.

环境配置示例如下:

    <environments default="development">
        <environment id="development">
            <!--指定事务管理类型,type="JDBC"指直接简单使用了JDBC的提交和回滚事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- dateSource指定数据源配置,POOLED是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>

默认的环境ID(default="development");
每个environment元素定义的环境ID(比如,id="development").
环境ID可以随意命名,建议简洁有意义,而默认环境一定要匹配定义的其中一个环境ID.
<transactionManager.../>表示事务管理配置,在MyBatis中有JDBCMANAGED两中类型的事务管理器:

  • JDBC.这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围.
  • MANAGED. 这个配置几乎没做什么.它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如JAVAEE应用服务器的上下文).默认情况下它会关闭连接,然而一些容器并不希望这样,可以将closeConnection属性设置为false来阻止它的默认关闭行为.
            <transactionManager type="MANAGED">
                <property name="closeConnection" value="false"/>
            </transactionManager>

提示: 如果开发使用Spring+MyBatis,则没有必要配置事务管理器,因为Spring模块会使用自带的管理器来覆盖前面的配置.

<dataSource.../>表示数据源配置,在MyBatis中有UNPOOLED、POOLED和JNDI三种数据源类型:

  • UNPOOLED.这个数据源的实现只是每次被请求时打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。不同的数据库在这方面表现也是不一样的。
    UNPOOLED类型的数据源仅仅需要配置一下5种属性:
    drive、url、username、password、defaultTransactionIsolationLevel。默认的连接事务隔离级别。

  • POOLED:这种数据源的实现利用“池”的概念将JDBC连接对想组织起来,避免了创建新的连接实例时所必需的初始化时间和认证时间。这是一种使得并发Web应用快速响应请求的流行处理方式,除了上述提到的UNPOOLED的5中属性外,还可以使用更多的属性来配置POOLED的数据源:

    • poolMaximumActiveConnections.在任意时间可以存在的活动(也就是正在使用)连接数量,默认值是10.
    • poolMaximumIdleConnections.任意时间可能存在的空闲连接数.
    • poolMaximunCheckoutTime.在被强制返回之前,池中连接被检出时间,默认值为20000毫秒(即20秒).
    • poolTimeToWait.这是一个底层设置,如果获取连接花费相当长的时间,它会给连接池打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静地失败),默认值为20000毫秒(20秒).
    • poolPingQuery.发送到数据库的侦测查询,用来检验连接是否处于正在工作秩序中并准备接受请求.默认是"NO PING QUERY SET",这会导致多数数据库驱动失败时带有一个恰当的错误消息.
    • poolPingEnabled.是否启用侦测查询.若开启,也必须使用一个可执行的sql语句设置poolPingQuery属性(最好是一个非常快的sql),默认值为false.
    • poolPingConnectionsNotUsedFor.配置poolPingQuery的使用频度.这可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值为0(即所有连接每一时刻都被侦测,当然仅当poolPingEnabled为true时适用).
  • JNDI.这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用.这种数据源配置只需要两个属性如下图所示:


mapper 映射器

MyBatis需要开发者自己写sql语句,mapper映射器正是告诉MyBatis到哪里去找映射文件,进而找到这些sql语句.实际开发中可以使用相对于类路径的资源引用或完全限定资源定位符(包括file:///的URL),以及类名和包名等,例如:

    <!-- 使用类路径查找资源文件 -->
    <mappers>
        <mapper resource="com/ccgogoing/fileupload/mapper/sqlmap-mapping-user.xml"/>
    </mappers>
    <!-- 使用本地文件 -->
    <mappers>
        <mapper url="file:///C:/mapper/UserMapper.xml">
    </mappers>
    <!-- 使用接口类 -->
    <mappers>
        <mapper class="org.ccgogoing.mapper.UserMapper"
    </mappers>
    <!-- 使用包名 -->
    <mappers>
        <package name="org.ccgogoing.mapper"/>
    </mappers>

mapper映射器会告诉MyBatis去哪里找映射文件,剩下的细节就是每个SQL映射文件了,我会在接下来的文章中详细说明这部分知识.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354