前面的文章分析过,Configuration与配置文件(或者配置类)相对应,SqlSessionFactoryBuilder构建而成,存放着mybatis所需要的配置项。
在单数据源的项目中,一般只会有一个Configuration实例,因为Configuration是与SqlSessionFactory相绑定的。SqlSessionFactory持有Configuration的引用,在创建SqlSession的过程中会把Configuration引用传递给SqlSession。
此篇博客的目的在于分析我们定义的接口、mapper文件等是如何抽象成配置类的。
测试数据
还是之前的测试类,不重复贴太多了。
接口
public interface RoleMapper{
Role getRole(@Param("id") Long id);
Role findRole(@Param("roleName") String roleName);
int deleteRole(Long id);
int insertRole(Role role);
}
xml
<?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="customer.mapper.RoleMapper">
<resultMap type="role" id="roleMap">
<id column="id" property="id" javaType="long" jdbcType="BIGINT" />
<result column="role_name" property="roleName" javaType="string"
jdbcType="VARCHAR" />
<result column="note" property="note"
typeHandler="customer.handler.MyStringHandler" />
</resultMap>
<select id="getRole" parameterType="long" resultMap="roleMap">
select
id,role_name as roleName,note from role where id=#{id}
</select>
<select id="findRole" parameterType="long" resultMap="roleMap">
select
id,role_name,note,status from role where role_name like CONCAT('%',#{roleName,
javaType=string,
jdbcType=VARCHAR,typeHandler=customer.handler.MyStringHandler},'%')
</select>
<insert id="insertRole" parameterType="role">
insert into
role(role_name,note) value(#{roleName},#{note})
</insert>
<delete id="deleteRole" parameterType="long">
delete from role where
id=#{id}
</delete>
</mapper>
debug
构建的过程就不重复看了,我们直接看构建结果。
获取SqlSession中的Configuration对象
environment
定义了mybatis所使用的数据源
mapperRegistry
映射器注册机
内部是以Map的数据结构存储MapperProxyFactory的,键值是Clas类。
对应我们的测试环境,key就是定义的RoleMapper接口
代理工厂可以根据接口生成对应的代理对象。
MapperRegistry本质上是一个map,用于存放mapper接口与其对应的代理类工厂。
typeHandlerRegistry
类型处理器注册机。
typeHandler用于类型处理,在预编译设置参数阶段以及获取方法返回值时,都用到了TypeHandler(详细见第二篇)。
Java类型(JDBC类型)与对应的处理器是如何关联起来的,以及如何把指定的类型和我们自己定义的处理器绑定起来的?
就需要用到TypeHandlerRegistry了。
当前测试环境只自定义了一个TypeHandler,其他的都是内置的一些处理器,基本已经符合我们的需求了。
typeAliasRegistry
类型的别名注册机。
又是一个朴实无华的map
同样内置了很多别名
mappedStatement
映射声明,sql规则的申明。
Key为对应的方法名
getRole与customer.mapper.RoleMapper.getRole存储的MappedStatement是同一个对象。
MappedStatement有如下内容:
以及Sql的执行类型、主键生成规则等等
resultMap
我在配置文件中定义了一个结果集映射
<resultMap type="role" id="roleMap">
<id column="id" property="id" javaType="long" jdbcType="BIGINT" />
<result column="role_name" property="roleName" javaType="string"
jdbcType="VARCHAR" />
<result column="note" property="note"
typeHandler="customer.handler.MyStringHandler" />
</resultMap>
经过解析后封装进了Configuration中的resultMap
mappedStatement中的resultMap来自于此。
其他
例如参数映射、主键生成器等,因为没有配置,所以不会产生对应的对象。
总结
Configuration对数据库的环境、sql调用的入口(Mapper接口)、sql的申明(xml文件)、类型映射规则、别名、结果集映射、参数映射等等都做了封装。
下一篇debug mybatis执行一个sql的全过程,进一步了解Configuration对象在sql执行过程中扮演着怎样的角色。