mybatis 因为其简单易用性,被广泛使用。它既简化了我们对DB curd操作,同时也保留了我们写sql语句的权利(不是自动生成),这样我们就可以基于sql做更多的优化(如加hint)。
下面我们来解析一下mybatis的配置文件
<?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 resource="application.properties">
<property name="username" value="db_user"/>
<property name="password" value="verysecurepwd"/>
</properties>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<typeAlias alias="Tutor" type="com.mybatis3.domain.Tutor"/>
<package name="com.mybatis3.domain"/>
</typeAliases>
<typeHandlers>
<typeHandler handler="com.mybatis3.typehandlers.PhoneTypeHandler"/>
<package name="com.mybatis3.typehandlers"/>
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<environment id="production">
<transactionManager type="MANAGED"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/jdbc/MyBatisDemoDS"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mybatis3/mappers/StudentMapper.xml"/>
<mapper url="file:///D:/mybatisdemo/mappers/TutorMapper.xml"/>
<mapper class="com.mybatis3.mappers.TutorMapper"/>
</mappers>
</configuration>
Environments
我们首先看其中最重要的部分 environments
mybatis支持配置多个数据源,这样可以带来两个好处
- 方便我们将程序部署到多个不同的环境上面。我们通常都会有dev环境,QA环境,prod环境等等。 我们将他们都配置到environments里面,当我们在不同环境切换的时候只需要简单的改动到连接到的environment id即可。这里我们默认连接的是development 环境。
- 有时候我们的程序需要同时连接多个db. 这种情况下,我们这里配置多个environments, 然后可以根据不同的environment 初始化出来多个sqlSessionFactory 即可。
inputStream = Resources.getResourceAsStream("mybatis-config.xml");
defaultSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
cartSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"development");
reportSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"production");
其中第二个参数为我们定义environment时给定的id,如果不提供这个参数则使用 default指定的environment.
dataSource
environment里面最重要的就是datasource了,它定义了我们连接db的各种属性。
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
其中, type 定义了数据源获取db连接的方式,它有以下三个取之:
- UNPOOLED 不使用缓存池,每次查询开启一个新的connection,执行结束后关闭该connection
- POOLED 使用缓存池,Mybatis 会提前创建一个连接池,每次db操作,从池中取一个空闲连接使用,操作完毕将该连接还回连接池。
- JNDI 从JNDI数据源获取连接。该方式通常用在生产环境中
其他参数看名字就很容易理解了,我们不再解释
TransactionManager
environment中另外一个属性是transactionManager, 它有两个取值
- JDBC application自己管理事务
- MANAGED application所在的服务器来帮我们管理事务,如weblogic
下面跳出environments,我们在看看其他配置
properties
<properties resource="application.properties">
<property name="jdbc.username" value="db_user"/>
<property name="jdbc.password" value="verysecurepwd"/>
</properties>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
properties可以指定一个外部文件作为resource,然后我们可以通过placeholder 读取其中的值。
假如application.properties的value如下
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatisdemo
jdbc.username=root
jdbc.password=admin
则dataSource中的placeholder在运行的时候的值将被application.properties中的值替代
我们也可以指定properties的默认值
TypeAlias
<typeAliases>
<typeAlias alias="Tutor" type="com.mybatis3.domain.Tutor"/>
<package name="com.mybatis3.domain"/>
</typeAliases>
当我们在sql mapper configuration 文件中指定javabean名字的时候,我们需要给定类的全名(包含package name). 这个时候如果包名很长的话将会显得很冗余。这是我们就可以为其取一个别名(alias) ,来缩短名字长度。
当我们要为某个包下面的多个javabean起别名的时候也可以通过指定<pacakge>的形式来简化。通过这种方式,它将会给com.mybatis3.domain下面的所有类都取一个将类名首字母小写的alias.
在spring中我们也可以以注解@Alias("aliasName")的方式指定,这种方式会覆盖我们在配置文件里面的Alias.
TypeHandler
接下来我们看一个结构和TypeAlias类似的TypeHandler
<typeHandlers>
<typeHandler handler="com.mybatis3.typehandlers.PhoneTypeHandler"/>
<package name="com.mybatis3.typehandlers"/>
</typeHandlers>
看它的名字,我们大概也能猜到,它的作用是进行类型转换。
对于java常用的基本数据类型,mybatis已经为我们自动提高了类型转换函数. 而对于一些用户自定义变了,我们则需要自己定义类型转换函数来告诉mybatis如果将它map成oracle数据库数据类型,反之亦然
mybatis提高了一个BaseTypeHandler<?>,我们可以通过继承它来提供我们自己的类型转换类
public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber>
{
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
PhoneNumber parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.getAsString());
}
@Override
public PhoneNumber getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return new PhoneNumber(rs.getString(columnName));
}
@Override
public PhoneNumber getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
return new PhoneNumber(rs.getString(columnIndex));
}
@Override
public PhoneNumber getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return new PhoneNumber(cs.getString(columnIndex));
}
}
Settints
设置一下db的配置参数
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25000"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
Mappers
指定了存储sql语句和statement id 映射关系的文件路径
<mappers>
<mapper resource="com/mybatis3/mappers/StudentMapper.xml"/>
<mapper url="file:///D:/mybatisdemo/app/mappers/TutorMapper.xml"/>
<mapper class="com.mybatis3.mappers.TutorMapper"/>
<package name="com.mybatis3.mappers"/>
</mappers>
其中根据mapper文件所在路径的不同,有四种指定方式
- resource 当mapper文件在classpath下面时使用
- url 当mapper文件在filesystem 或者 远程server时使用
- class 用来指定mapper interface
- package 在该目录下面找mapper interface