三、MyBatis-全局配置文件
XML 映射配置文件(官方结构)
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置(settings)和属性(properties)信息。文档的顶层结构如下:
- configuration 配置
- properties 属性
- settings 设置
- typeAliases 类型别名
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
- environment 环境变量
- transactionManager 事务管理器
- dataSource 数据源
- environment 环境变量
- databaseIdProvider 数据库厂商标识
- mappers 映射器
以上是mybatis官方提供的全局配置文件的结构内容,下面我们来看看如何配置这些属性:
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> <!-- 1、mybatis可以使用properties来引入外部properties配置文件的内容; resource:引入类路径下的资源 url:引入网络路径或者磁盘路径下的资源 2.通过${属性key}来使用属性值 --> <properties resource="dbconfig.properties"> <!-- 其他属性,jdbc.url会被外部配置文件中的jdbc.url值覆盖 --> <property name="jdbc.url" value="jdbc:mysql://47.100.244.76:3306/mybatis01"/> </properties> <environments default="dev_mysql"> <environment id="dev_mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <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> <environment id="dev_oracle"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${orcl.driver}" /> <property name="url" value="${orcl.url}" /> <property name="username" value="${orcl.username}" /> <property name="password" value="${orcl.password}" /> </dataSource> </environment> </environments> </configuration>
如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载:
– 在 properties 元素体内指定的属性首先被读取。
– 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
也就是说:外部引入配置文件中的额属性值优先级比properties 元素体内的高。
settings属性配置
<?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> <!-- 1、settings包含很多重要的设置项 setting:用来设置每一个设置项 name:设置项名 value:设置项取值 --> <settings> <!-- 表字段名称转驼峰命名映射到javabean --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 解决Oracle对Null的值解析出错的处理 --> <setting name="jdbcTypeForNull" value="NULL"/><!-- 默认为OTHER,会使Oracle出错 --> <!--延迟加载开关,配置所有关联对象是否延迟加载,默认为false --> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> <!-- 开启二级缓存,默认为false --> <setting name="cacheEnabled" value="true"/> </settings> </configuration>
typeAliases 类型别名属性配置
给mybatis可以使用到的类型,取一个映射别名,可以用在SQL Mapper映射文件的resultType,parameterType等属性以及其他填写类型的属性值。
1)单个类型配置
<!-- 配置好了以后,以后再sql mapper映射文件中,resultType 就可以使用obj来代表全类名。 --> <typeAliases> <typeAlias type="java.lang.Object" alias="obj"/> </typeAliases>
2) 整包范围配置
<!-- 为某个包下的所有类批量起别名 ,类的别名为,类名首字母小写。 --> <typeAliases> <package name="com.atguigu.mybatis.bean"/> </typeAliases>
3)注解形式 (给实体类中添加注解@Alias("name"))
这种形式优先级最高,其次typeAlias,最后package形式。
示例:
mybatis内建类型别名:
typeHandlers 类型处理器
主要提供给mybatis在预编译时参数设值的时候做参数类型转换处理,以及结果集处理时数据类型转换。自定义的类型转换器需要实现接口org.apache.ibatis.type.TypeHandler。
以下为接口源码:
package org.apache.ibatis.type; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Clinton Begin */ public interface TypeHandler<T> { void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; T getResult(ResultSet rs, String columnName) throws SQLException; T getResult(ResultSet rs, int columnIndex) throws SQLException; T getResult(CallableStatement cs, int columnIndex) throws SQLException; }
StringTypeHandler.java源码:(处理String类型的参数和结果数据)
package org.apache.ibatis.type; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Clinton Begin */ public class StringTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return rs.getString(columnName); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return rs.getString(columnIndex); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getString(columnIndex); } }
1) 单个配置形式:
<typeHandlers> <typeHandler handler="org.apache.ibatis.type.IntegerTypeHandler" javaType="java.lang.Integer"/>
</typeHandlers>
2)整包配置形式:
<typeHandlers> <package name="org.apache.ibatis.type"/> </typeHandlers>
plugins 插件配置
插件是MyBatis提供的一个非常强大的机制,我们可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行。后面会有专门的章节我们来介绍mybatis运行原理以及插件
四大对象:
- Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
environments 环境
<?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> <!-- 1、environments:环境们,mybatis可以配置多种环境 ,default指定使用某种环境。可以达到快速切换环境。 environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识 transactionManager:事务管理器; type:事务管理器的类型;JDBC(JdbcTransactionFactory)|MANAGED(ManagedTransactionFactory) 自定义事务管理器:实现TransactionFactory接口.type指定为全类名 dataSource:数据源; type:数据源类型;UNPOOLED(UnpooledDataSourceFactory) |POOLED(PooledDataSourceFactory) |JNDI(JndiDataSourceFactory) 自定义数据源:实现DataSourceFactory接口,type是全类名,定义数据源的获取方式。 --> <environments default="dev_mysql"> <environment id="dev_mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <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> <environment id="dev_oracle"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${orcl.driver}" /> <property name="url" value="${orcl.url}" /> <property name="username" value="${orcl.username}" /> <property name="password" value="${orcl.password}" /> </dataSource> </environment> </environments> </configuration>
备注:实际开发中我们使用Spring管理数据源,并进行事务控制的配置来覆盖上述配置。
databaseIdProvider 数据库厂商标识配置
<!-- 1、databaseIdProvider:支持多数据库厂商的; type="DB_VENDOR":VendorDatabaseIdProvider 作用就是得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商标识来执行不同的sql; MySQL,Oracle,SQL Server,xxxx --> <databaseIdProvider type="DB_VENDOR"> <!-- 为不同的数据库厂商起别名 --> <property name="MySQL" value="mysql"/> <property name="Oracle" value="oracle"/> <property name="SQL Server" value="sqlserver"/> </databaseIdProvider>
1)如何使用呢?
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper"> <!-- namespace:名称空间;指定为接口的全类名 id:唯一标识 resultType:返回值类型 #{id}:从传递过来的参数中取出id值 --> <select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee"> select * from tbl_employee where id = #{id} </select> <select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee" databaseId="mysql"> select * from tbl_employee where id = #{id} </select> <select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee" databaseId="oracle"> select EMPLOYEE_ID id,LAST_NAME lastName,EMAIL email from employees where EMPLOYEE_ID=#{id} </select> </mapper>
在SQL标签中,可以通过databaseId属性来指定数据库来源,只有当前数据库与之匹配时才用这条定制化SQL。SQL方法ID相同的SQL,优先使用指定databaseId的SQL 。
如上,当数据库为mysql时,会使用第二个select sql,当数据库为sql server时,会使用第一个select sql。同时可以在mapper.xml文件中通过_databaseId获取当前数据库的所对应的databaseId值。
mappers 映射器设置
用来注册写好的SQL Mapper映射文件。
1)单个注册方式:
<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 --> <!-- 1、mappers:将sql映射注册到全局配置中 --> <mappers> <!-- mapper:注册一个sql映射 注册配置文件 resource:引用类路径下的sql映射文件 mybatis/mapper/EmployeeMapper.xml url:引用网路路径或者磁盘路径下的sql映射文件 file:///var/mappers/AuthorMapper.xml 注册接口 class:引用(注册)接口, 1、有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下; 2、没有sql映射文件,所有的sql都是利用注解写在接口上; 推荐: 比较重要的,复杂的Dao接口我们来写sql映射文件 不重要,简单的Dao接口为了开发快速可以使用注解; --> <!-- 注册单个配置文件 --> <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> <!-- 注册单个接口 --> <mapper class="com.atguigu.mybatis.dao.EmployeeMapperAnnotation"/> </mappers>
2)整包注册方式:
<mappers> <!-- 批量注册: --> <!-- 配置文件与包中接口的类路径保持一致 --> <!-- 简单来说就是默认注册classpath:/com/atguigu/mybatis/dao/下所有xml文件 和 com.atguigu.mybatis.dao包下的接口注册 --> <package name="com.atguigu.mybatis.dao"/> </mappers>
示例:
总结
1)通过配置文件的方式创建SqlSessionFactory时,会先通过org.apache.ibatis.builder.xml.XMLConfigBuilder解析全局xml配置文件,将解析的结果放到内存org.apache.ibatis.session.Configuration对象,这是一个全局对象,在mybatis整个生命周期都有效的内存对象。
2)同理,也可以直接创建org.apache.ibatis.session.Configuration对象,再由Configuration来创建SqlSessionFactory对象。
官方提供的创建SqlSessionFactory的硬编码方式:
//BlogDataSourceFactory为自定义的数据库连接池工厂 DataSource dataSource = BlogDataSourceFactory.getBlogDataSource(); TransactionFactory transactionFactory = new JdbcTransactionFactory(); Environment environment = new Environment("development", transactionFactory, dataSource); //直接创建Configuration 内存全局对象 Configuration configuration = new Configuration(environment); //硬编码的方式配置Mapper,也可以配置其他属性,不配置时使用mybatis内部默认值 configuration.addMapper(BlogMapper.class); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);