摘要:理解与掌握原理分析框架功能架构接口层提供给外部使用的接口,开发人员通过这些本地来操作数据库。流程分析数据处理过程根据的查找相应的对象。预处理对象,得到对象。传入和结果处理对象,通过的方法来执行,并对执行结果进行处理。
MyBatis理解与掌握(原理分析)
@(MyBatis)[Java, 框架, MyBatis]
功能架构(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操作数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理
(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果处理等。它主要的目的是根据调用的请求来完成一次数据库操作。
(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层数据处理层提供最基础的支撑。
(4)引导层:配置和启动MyBatis配置信息的方法。
数据处理过程:
(1)根据SQL的ID查找相应的MappedStatement对象。
(2)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(3)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果
(4)根据MappedStatement对象中的结果映射对得到的执行结果进行转换处理,并得到最终的处理结果
(5)释放连接资源
通过调用DefaultSqlSessionFactory的openSession方法返回一个SqlSession实例,我们看一下具体是怎么得到一个SqlSession实例的。
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Connection connection = null; try { //获取配置信息里面的环境信息,这些环境信息都是包括使用哪种数据库,连接数据库的信息,事务 final Environment environment = configuration.getEnvironment(); //根据环境信息关于数据库的配置获取数据源 final DataSource dataSource = getDataSourceFromEnvironment(environment); //根据环境信息关于事务的配置获取事务工厂 TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); connection = dataSource.getConnection(); if (level != null) { //设置连接的事务隔离级别 connection.setTransactionIsolation(level.getLevel()); } //对connection进行包装,使连接具备日志功能,这里用的是代理。 connection = wrapConnection(connection); //从事务工厂获取一个事务实例 Transaction tx = transactionFactory.newTransaction(connection, autoCommit); //从配置信息中获取一个执行器实例 Executor executor = configuration.newExecutor(tx, execType); //返回SqlSession的一个默认实例 return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeConnection(connection); throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } }
总结一下上面的过程,总共有三个步骤:
步骤一:读取MyBatis的主配置文件,并将文件读成文件流形式(InputStream)。 步骤二:从主配置文件中读取文件的各个节点信息并存放到Configuration对象中。读取mappers节点的引用文件,并将这些文件的各个节点信息存放到Configuration对象。 步骤三:根据Configuration对象的信息获取数据库连接,并设置连接的事务隔离级别等信息,将经过包装数据库连接对象SqlSession接口返回,DefaultSqlSession是SqlSession的实现类,所以这里返回的是DefaultSqlSession,SqlSession接口里面就是对外提供的各种数据库操作。SQL查询的源码
SqlSession session = sessionFactory.openSession(); session.update("updateUser", 1);
------------------------源码-----------------------------------------
private SqlSession openSessionFromDataSource(...) { ....... //从配置信息中获取一个执行器实例 Executor executor = configuration.newExecutor(tx, execType); //返回SqlSession的一个默认实例 return new DefaultSqlSession(configuration, executor, autoCommit); ...... } DefaultSqlSession实现了SqlSession接口,里面有各种各样的SQL执行方法,主要用于SQL操作的对外接口,它会的调用执行器来执行实际的SQL语句。 public class DefaultSqlSession implements SqlSession { private Configuration configuration; private Executor executor ; ....... @Override (1)根据SQL的ID到配置信息中找对应的MappedStatement,在之前配置被加载初始化的时候我们看到了系统会把配置文件中的SQL块解析并放到一个MappedStatement里面,并将MappedStatement对象放到一个Map里面进行存放,Map的key值是该SQL块的ID。 (2)调用执行器的update方法,传入MappedStatement对象、SQL参数对象、范围对象(此处为空)和结果处理方式。 public int update(String statement, Object parameter) { try { dirty = true; MappedStatement ms = configuration.getMappedStatement(statement); return executor .update(ms, wrapCollection(parameter)); } catch (Exception e) { throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } ...... } public class SimpleExecutor extends BaseExecutor { ........ @Override (1) 获取配置信息对象。 (2)通过配置对象获取一个新的StatementHandler,该类主要用来处理一次SQL操作。 (3)预处理StatementHandler对象,得到Statement对象。 (4)传入Statement和结果处理对象,通过StatementHandler的update方法来执行SQL,并对执行结果进行处理。 public int doUpdate(MappedStatement ms, Object parameter) throws SQLException { Statement stmt = null; try { Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null); stmt = prepareStatement(handler, ms.getStatementLog()); return handler.update(stmt); } finally { closeStatement(stmt); } } ......... }
根据 MappedStatement对象的StatementType来创建不同的StatementHandler,这个跟前面执行器的方式类似。StatementType有STATEMENT、PREPARED和CALLABLE三种类型,跟JDBC里面的Statement类型一一对应。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77086.html
摘要:容器自动完成装载,默认的方式是这部分重点在常用模块的使用以及的底层实现原理。 对于那些想面试高级 Java 岗位的同学来说,除了算法属于比较「天方夜谭」的题目外,剩下针对实际工作的题目就属于真正的本事了,热门技术的细节和难点成为了主要考察的内容。 这里说「天方夜谭」并不是说算法没用,不切实际,而是想说算法平时其实很少用到,甚至面试官都对自己出的算法题一知半解。 这里总结打磨了 70 道...
摘要:目录其中每个章节知识点都是相关连由浅入深的一步步全面分析了技术原理以及实战由于文案较长想深入学习以及对于该文档感兴趣的朋友们可以加群免费获取。这些场景在大量的编码中使用,具备较强的实用价值,这些内容都是通过实战得来的,供读者们参考。 前言系统掌握MyBatis编程技巧已经成了用Java构建移动互联网网站的必要条件 本文主要讲解了Mybatis的应用,解析了其原理,从而形成一个完整的知识...
摘要:从使用到原理学习线程池关于线程池的使用,及原理分析分析角度新颖面向切面编程的基本用法基于注解的实现在软件开发中,分散于应用中多出的功能被称为横切关注点如事务安全缓存等。 Java 程序媛手把手教你设计模式中的撩妹神技 -- 上篇 遇一人白首,择一城终老,是多么美好的人生境界,她和他历经风雨慢慢变老,回首走过的点点滴滴,依然清楚的记得当初爱情萌芽的模样…… Java 进阶面试问题列表 -...
阅读 2657·2023-04-25 17:21
阅读 2485·2021-11-23 09:51
阅读 2765·2021-09-24 10:32
阅读 3676·2021-09-23 11:33
阅读 1926·2019-08-30 15:44
阅读 3416·2019-08-30 11:18
阅读 3401·2019-08-30 10:53
阅读 591·2019-08-26 13:25