目录
1、Mybatis的功能架构
![](https://i-blog.csdnimg.cn/blog_migrate/9ae8930c29adf1f6933a864052c2763f.png)
Mybatis的功能架构分为三层:
(1) API接口层
提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
MyBatis和数据库的交互有两种方式:
-
传统的MyBatis提供的API;
-
Mapper接口;
a、传统的MyBatis提供的API
这是传统的传递Statement Id 和查询参数给 SqlSession 对象,使用 SqlSession对象完成和数据库的交互;MyBatis 提供了非常方便和简单的API,供用户实现对数据库的增删改查数据操作,以及对数据库连接信息和MyBatis 自身配置信息的维护操作。
上述使用MyBatis 的方法,是创建一个和数据库打交道的SqlSession对象,然后根据Statement Id 和参数来操作数据库,这种方式固然很简单和实用,但是它不符合面向对象语言的概念和面向接口编程的编程习惯。由于面向接口的编程是面向对象的大趋势,MyBatis 为了适应这一趋势,增加了第二种使用MyBatis 支持接口(Interface)调用方式。
b、Mapper接口
MyBatis 将配置文件中的每一个<mapper> 节点抽象为一个 Mapper 接口,而这个接口中声明的方法和跟<mapper> 节点中的<select|update|delete|insert> 节点项对应,即<select|update|delete|insert> 节点的id值为Mapper 接口中的方法名称,parameterType 值表示Mapper 对应方法的入参类型,而resultMap 值则对应了Mapper 接口表示的返回值类型或者返回结果集的元素类型。
根据MyBatis 的配置规范配置好后,通过SqlSession.getMapper(XXXMapper.class) 方法,MyBatis 会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper 实例,我们使用Mapper 接口的某一个方法时,MyBatis 会根据这个方法的方法名和参数类型,确定Statement Id,底层还是通过SqlSession.select("statementId",parameterObject);或者SqlSession.update("statementId",parameterObject); 等等来实现对数据库的操作。
MyBatis 引用Mapper 接口这种调用方式,纯粹是为了满足面向接口编程的需要。(其实还有一个原因是在于,面向接口的编程,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件,实现“0配置”)。
(2) 数据处理层
负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
a、参数映射和动态SQL语句生成
动态语句生成可以说是MyBatis框架非常优雅的一个设计,MyBatis 通过传入的参数值,使用 Ognl 来动态地构造SQL语句,使得MyBatis有很强的灵活性和扩展性。
参数映射指的是对于java 数据类型和jdbc数据类型之间的转换:
这里有包括两个过程:查询阶段,我们要将java类型的数据,转换成jdbc类型的数据,通过 preparedStatement.setXXX() 来设值;另一个就是对resultset查询结果集的jdbcType 数据转换成java 数据类型。
b、SQL语句的执行以及封装查询结果集成List<E>
动态SQL语句生成之后,MyBatis 将执行SQL语句,并将可能返回的结果集转换成List<E> 列表。MyBatis 在对结果集的处理中,支持结果集关系一对多和多对一的转换,并且有两种支持方式,一种为嵌套查询语句的查询,还有一种是嵌套结果集的查询。
(3) 基础支撑层
负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
2、与数据库交互(对应API接口层)
(1) 使用Mybatis自带的API
使用sqlSession对象完成与数据库的交互,将statementID和查询参数传给sqlSession,使用sqlSession的select、insert等方法完成查询、插入等操作。
![](https://i-blog.csdnimg.cn/blog_migrate/297d7391b46f2b38fc25b5ab15af2be9.png)
(2) 使用封装的Mapper接口
此方法纯粹是为了面向接口编程才封装出来的,底层仍然是sqlSession对象。
a、注解开发
直接在接口中的方法上,进行注解;
@Select等编写SQL语句、@ResultMap等设置结果集和JavaBean的映射关系,eg.
@Select("select * from users where id=#{id}")
@Results({
@Result(id=true, column="stud_id", property="studId"),
@Result(column="name", property="name"),
@Result(column="email", property="email"),
@Result(column="addr_id", property="address.addrId")
})
好处是不用再编写XML,实现零配置。
坏处是对于复杂sql语句排版难看,不易维护,而且不符合mybatis分离sql的思想。
b、XML开发
编写与接口对应的XML文件,接口中方法名和XML中的sql语句id唯一对应。
结果集和javaBean的关系映射,通过<resultMap>标签进行设置或者通过resultType+<typealias>标签进行设置,eg.
<resultMap type="Admin" id="adminResultMap">
<id property="id" column="id" jdbcType="INTEGER" />
<result property="username" column="username" jdbcType="VARCHAR" />
<result property="password" column="password" jdbcType="VARCHAR" />
</resultMap>
<select id="getAdminByConditions" resultMap="adminResultMap">
SELECT * FROM userinfo
</select>
或者
<typeAlias alias="userInfoVO" type="com.mobilecircle.entity.vo.UserInfoVO" />
<select id="gainUser" parameterType="userCond" resultType="userVO">
SELECT <include refid="userVOColumn" />
FROM user_info
</select>
3、Mybatis执行过程
(1) 加载配置文件并初始化(SqlSession)
配置文件来源于两个地方,一个是配置文件(主配置文件conf.xml,mapper文件*.xml),一个是java代码中的注释,将sql的配置信息加载成为一个mappedstatement对象,存储在内存之中(包括传入参数的映射配置,结果映射配置,执行的sql语句)。
(2) 接收调用请求
调用mybatis提供的api,传入的参数为sql的id(有namespase和具体sql的id组成)和sql语句的参数对象,mybatis将调用请求交给请求处理层。
(3) 处理请求
-
根据sql的id找到对应的mappedstatament对象。
-
根据传入参数解析mappedstatement对象,得到最终要执行的sql。
-
获取数据库连接,执行sql,得到执行结果。
-
Mappedstatement对象中的结果映射对执行结果进行转换处理,并得到最终的处理结果。
-
释放连接资源。
(4) 返回处理结果