目录

Java 操作数据库(七) Mybatis基础

本节目标

  • 详解 Mybatis 配置

配置结构

  • configuration 配置
    • properties 属性
    • settings 设置
    • typeAliases 对象别名命名
    • typeHandlers 类型处理器
    • objectFactory 对象工厂
    • plugins 插件
    • environments 环境
      • environment 环境变量
        • transactionManager 事务管理器
        • dataSource 数据源
    • mappers

配置结构(XML 示例)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <properties/>
  <settings/>
  <typeAliases/>
  <typeHandles/>
  <objectFactory/>
  <plugins/>
  <environments>
    <environment>
      <transanctionManager/> <!-- 配置事务管理器 -->
      <dataSource/> <!-- 配置数据源 -->
    </environment>
  </environments>
  <databaseIdProvider/> <!-- 数据库厂商标识 -->
  <mappers/> <!-- 映射器 -->
</configuration>

配置的上下顺序不可调换

properties

将一些公用、经常变更的值单独声明,能在配置文件的上下文中使用它,MyBatis 提供了 3 种配置方式:

property 子元素

<properties>
  <property name="driver" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="jdbc:mysql://localhost:3306/mi-user"/>
  <property name="username" value="root"/>
  <property name="pwd" value="123456"/>
</properties>

properties 配置文件

创建一个配置文件 jdbc.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mi-user
username = root
password = 123456

设置 properties 配置文件

 <properties resource='jdbc.properties' />

程序参数传递

实际工作中,会遇到这种场景:系统由运维人员配置,生成数据库的密码对开发者是保密的,对用户名和密码进行了加密。可以通过程序参数传递的方式,先解密再设置 property。

 //读入配置文件流
InputStream cfgStream = Resources.getResourceAsStream("mybatis-config.xml");
Reader cfgReader = new InputStreamReader(cfgStream);

//读入属性文件流
InputStream proStream = Resources.getResourceAsStream("jdbc.properties");
Reader proReader = new InputStreamReader(proStream);

Properties properties = new Properties();
properties.load(proReader);

//转换为明文
properties.setProperty("username",decode(properties.getProperty("username")));
properties.setProperty("pwd",decode(properties.getProperty("pwd")));

//创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(cfgReader,properties);

如果 3 种配置同时出现,优先级为: 程序参数传递 > properties 配置文件 > property 子元素。

settings 设置

设置属性会改变 MyBatis 运行时的行为,这里介绍几个常用的设置项:

  • cacheEnabled,全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true;
  • lazyLoadingEnabled,延迟加载的全局开关,当开启时,所有关联对象都会延迟加载,特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态,默认为 false;
  • autoMappingBehavior,指定 MyBatis 应如何自动映射列到字段或属性,NONE 表示取消自动映射,PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集,FULL 会自动映射任意复杂的结果集,默认为 PARTIAL;
  • autoMappingUnknownColumnBehavior,指定发现自动映射目标未知列(或者未知属性类型)的行为,NONE: 不做任何反应,WARNING: 输出提醒日志,FAILING: 映射失败,默认为 NONE;
  • defaultStatementTimeout,设置超时时间,它决定驱动等待数据库响应的秒数;
  • mapUnderscoreToCamelCase,是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射,默认为 false;
  • defaultEnumTypeHandler,指定 Enum 使用的默认 TypeHandler,默认为 org.apache.ibatis.type.EnumTypeHandler;
  • returnInstanceForEmptyRow,当返回行的所有列都是空时,MyBatis 默认返回 null。 当开启这个设置时,MyBatis 会返回一个空实例,默认为 false;
  • localCacheScope,MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据,默认为 SESSION;
  • logImpl,指定日志的具体实现,比如 SLF4J|LOG4J|COMMONS_LOGGING 等;

typeAliases 别名

在配置映射文件中,需要指定类的全限定名,为了简化可以声明一个简短的名称去指代它,可以在 MyBatis 上下文中使用。 系统已经为我们定义了常用的类型别名,比如数值、字符串、日期、集合等。 对于自定义的业务 POJO,需要自定义别名。

<typeAliases>
  <typeAlias alias="role" type="com.bqteam.xxx.po.Role"/>
</typeAliases>

typeHandles 类型处理器

MyBatis 在预处理语句中设置一个参数或者从结果集中取出一个值时,都会用注册了的 TypeHandler 进行处理。 TypeHandler 的作用就是将参数从 javaType 转化为 jdbcType,或者从数据库取出结果时把 jdbcType 转化为 javaType。 系统内部已经定义了常用的类型处理器,如果有特殊需求,也可以自定义。

environments 配置环境

配置环境可以注册多个数据源,每个数据源包括基本配置和数据库事务配置。

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="autoCommit" value="false"/>
    </transactionManager>
    <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>

其中 transactionManager 标签用于指定数据库事务,有 3 种配置方法:

  • JDBC,采用 JDBC 方式管理事务,在独立编码中常常使用;
  • MANAGED,采用容器方式管理事务,在 JNDI 数据源中常用;
  • 自定义,由使用者自定义数据库事务管理方法;

dataSource 标签用于配置数据源连接信息,type 配置对数据库连接方式有以下几种:

  • UNPOOLED:非连接池数据库;
  • POOLED:连接池数据库;
  • JNDI:JNDI 数据源;
  • 自定义数据源;

mappers 映射器

映射器是 MyBatis 最复杂、最核心的配置,包括参数类型、动态 SQL、定义 SQL、缓存信息等功能。 通过映射器,可以很容易的进行数据的增删改查操作,我们抽象下进行这些操作的关键点:传递查询参数、组装各种场景下的查询条件、关联查询、将查询结果映射为 Java Bean 对象或集合等。另外,可以通过延迟加载、缓存提高数据查询的性能。

映射器的主要元素

映射器是由 Java 接口和 XML 文件(或注解)共同组成的,Java 接口主要定义调用者接口,XML 文件是配置映射器的核心文件,包括以下元素:

  • select 查询语句,可以自定义参数,返回结果集
  • insert 插入语句,返回一个整数,表示插入的条数
  • update 更新语句,返回一个整数,表示更新的条数
  • delete 删除语句,返回一个整数,表示删除的条数
  • sql 允许定义一部分 SQL,然后再各个地方引用
  • resultMap 用来描述从数据库结果集中来加载对象,还可以配置关联关系
  • cache 给定命名空间的缓存配置

每个元素都有可配置选项,具体可以查看官方文档。