MyBatis源码分析SQL语句执行的流程.doc
- 文档编号:231371
- 上传时间:2022-10-07
- 格式:DOC
- 页数:11
- 大小:54KB
MyBatis源码分析SQL语句执行的流程.doc
《MyBatis源码分析SQL语句执行的流程.doc》由会员分享,可在线阅读,更多相关《MyBatis源码分析SQL语句执行的流程.doc(11页珍藏版)》请在冰豆网上搜索。
MyBatis源码分析-SQL语句执行的完整流程
MyBatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
MyBatis可以对配置和原生Map使用简单的XML或注解,将接口和Java的POJOs(PlainOldJavaObjects,普通的Java对象)映射成数据库中的记录。
如何新建MyBatis源码工程请点击MyBatis源码分析-IDEA新建MyBatis源码工程。
MyBatis框架主要完成的是以下2件事情:
根据JDBC规范建立与数据库的连接。
通过反射打通Java对象与数据库参数交互之间相互转换的关系。
MyBatis框架是一种典型的交互式框架,先准备好交互的必要条件,然后构建一个交互的环境,在交互环境中划分会话,在会话中与数据库进行交互数据。
1MyBatis主要的类
ConfigurationMyBatis所有的配置信息都维持在Configuration对象之中。
SqlSession作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
ExecutorMyBatis执行器,是MyBatis调度的核心,负责SQL语句的生成和查询缓存的维护
StatementHandler封装了JDBCStatement操作,负责对JDBCstatement的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler负责对用户传递的参数转换成JDBCStatement所需要的参数,
ResultSetHandler负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
TypeHandler负责java数据类型和jdbc数据类型之间的映射和转换
MappedStatementMappedStatement维护了一条
SqlSource负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
BoundSql表示动态生成的SQL语句以及相应的参数信息
以上几个类在SQL操作中都会涉及,在SQL操作中重点关注下SQL参数什么时候写入和结果集怎么转换为Java对象,这两个过程正好对应的类是PreparedStatementHandler和ResultSetHandler类。
(图片来自《深入理解mybatis原理》MyBatis的架构设计以及实例分析)
2SQL执行流程
MyBatis主要设计目的还是为了让我们在执行SQL时对输入输出的数据的管理更加方便,所以方便的让我们写出SQL和方便的获取SQL的执行结果是MyBatis的核心竞争力。
下面就用一个例子来从源码角度看一下SQL的完整执行流程。
新建配置文件conf.xml:
conf.xml
首先建立数据表,这里就以user表为例:
复制代码
DROPTABLEIFEXISTSuser;
CREATETABLEuser(
idINTNOTNULLPRIMARYKEYAUTO_INCREMENT,
nameVARCHAR(32)NOTNULL,
passwordVARCHAR(32)NOTNULL,
sexint,
emailVARCHAR(32),
phoneVARCHAR(16),
adminVARCHAR(16)
);
复制代码
然后新建与数据表对应的类User:
User
再新建usre表的配置文件:
userMapper.xml
最后新建测试类:
复制代码
/**
*MyBatis测试类
*/
publicclassTestMain{
publicstaticvoidmain(String[]args)throwsIOException{
Stringresouce="conf.xml";
InputStreamis=Resources.getResourceAsStream(resouce);
//构建sqlSession工厂
SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(is);
//获取sqlSession
SqlSessionsession=sqlSessionFactory.openSession();
Useruser;
try{
/**
*第一种方式:
直接执行已映射的SQL语句
*/
Stringstatement="com.luoxn28.dao.UserDao.getById";
user=session.selectOne(statement,1);
System.out.println(user);
}
finally{
session.close();
}
/**
*第二种方式:
执行更清晰和类型安全的代码
*/
//UserDaouserDao=session.getMapper(UserDao.class);
//user=userDao.getById
(1);
//System.out.println(user);
}
}
复制代码
由于我们分析的是SQL的执行流程,那就重点关注下user=session.selectOne(statement,1);这行代码~注意,传进去的参数是1。
session是DefaultSqlSession类型的,因为sqlSessionFactory默认生成的SqlSession是DefaultSqlSession类型。
selectOne()会调用selectList()。
复制代码
//DefaultSqlSession类
public
try{
MappedStatementms=configuration.getMappedStatement(statement);
//CURD操作是交给Excetor去处理的
returnexecutor.query(ms,wrapCollection(parameter),rowBounds,Executor.NO_RESULT_HANDLER);
}catch(Exceptione){
throwExceptionFactory.wrapException("Errorqueryingdatabase.Cause:
"+e,e);
}finally{
ErrorContext.instance().reset();
}
}
复制代码
在DefaultSqlSession.selectList中的各种CURD操作都是通多Executor进行的,这里executor的类型是CachingExecutor,接着跳转到其中的query方法中。
//CachingExecutor类
public
BoundSqlboundSql=ms.getBoundSql(parameterObject);//获取绑定的sql命令,比如"SELECT*FROMxxx"
CacheKeykey=createCacheKey(ms,parameterObject,rowBounds,boundSql);
returnquery(ms,parameterObject,rowBounds,resultHandler,key,boundSql);
}
getBoundSql为了获取绑定的sql命令,在创建完cacheKey之后,就进入到CachingExecutor类中的另一个query方法中。
复制代码
//CachingExecutor类
@Override
public
throwsSQLException{
Cachecache=ms.getCache();
if(cache!
=null){
flushCacheIfRequired(ms);
if(ms.isUseCache()&&resultHandler==null){
ensureNoOutParams(ms,parameterObject,boundSql);
@SuppressWarnings("unchecked")
List
if(list==null){
list=delegate.
tcm.putObject(cache,key,list);//issue#578and#116
}
returnlist;
}
}
returndelegate.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MyBatis 源码 分析 SQL 语句 执行 流程