深度分析:mybatis的底层实现原理,看完你学会了吗?

前言最近在和朋友聊天的时候被问到jdbc和mybatis底层实现这一块的问题,而且还不止一个小伙伴问到,于是我似乎认识到了问题的严重性,我花了两天时间整理了一下自己的认识和网上查阅的资料写了这篇文章,话不多说,满满的干货都在下面了 。
在说mybatis底层实现之前,先看下基本的知识点jdbcjdbc是连接数据库的最基本实现,任何对数据库的操作都是基于jdbc
1. 注册驱动 Class.forName("com.MySQL.jdbc.Driver");2.获取数据库连接Connection conn=DriverManager.getConnection(url,user,p);3.创建向数据发送sql 的statement对象Statement stmt = conn.CreateStatement();4. 向数据库发送sqlResultSet rs= stmt.executeQuery(sql)//select语句int updateaSum = stmt.executeUpdate(sql)//insert,update delete语句5. 处理结果集while(rs.next()){ rs.getString(列名) rs.getInt(列名)}6. 关闭资源rs.close();stmt.close();conn.close();Mybatis之Sqlsession、Connection和Transaction解析关系与原理Connection JDBC 是我们用来与数据库交互最基础的API 。Connection 作为一个特定数据库的会话,在一个连接的上下文中,sql语句被执行,然后结果被返回 。我们先看下使用sqlsession进行数据库操作的基本流程 SqlSession 可以看作是对Connection 更加高级的抽象,从其方法上更加可以看出他具有更加明显的操作特征 。Transaction 事务(Transaction),正是对N(N>=1)个操作执行时,同时成功或同时失败的 关系 的具象 。
我们先看下sqlsession是如何进行数据库操作的:
String resource = "mybatis-config.xml";//获取数据配置流InputStream inputStream = Resources.getResourceAsStream(resource);//通过SqlSessionFactoryBuilder获取SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过sqlSessionFactory获取sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//对数据库执行操作try {TbUserMApper userMapper = sqlSession.getMapper(TbUserMapper.class);TbUser user = new TbUser("liybk", "liybk","186..","123");userMapper.insertUser(user);sqlSession.commit();// 这里一定要提交,不然数据进不去数据库中} finally {sqlSession.close();}我们先看SqlSessionFactoryBuilder().build(inputStream)方法:
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {SqlSessionFactory var5;try {XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);var5 = this.build(parser.parse());} catch (Exception var14) {throw ExceptionFactory.wrapException("Error building SqlSession.", var14);} finally {ErrorContext.instance().reset();try {inputStream.close();} catch (IOException var13) {}}return var5;}public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}最终执行通过一系列的xml文件解析,返回了DefaultSqlSessionFactory,进入DefaultSqlSessionFactory构造函数
public DefaultSqlSessionFactory(Configuration configuration) {this.configuration = configuration;}构造函数只是初始化了其configuration 属性,这个configuration 里面包含了一个Environment属性,而Environment属性里又有数据源,connect,事务等等一系列关于数据库操作的基本属性
public final class Environment {private final String id;private final TransactionFactory transactionFactory;private final DataSource dataSource;....}好的,我们回到主步骤SqlSession sqlSession = sqlSessionFactory.openSession()方法 其执行类是DefaultSqlSessionFactory,目的是获取sqlSession
public SqlSession openSession() {return //调用该类的openSessionFromDataSource方法this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);}//openSessionFromDataSource方法private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {Transaction tx = null;DefaultSqlSession var8;try {//获取EnvironmentEnvironment environment = this.configuration.getEnvironment();//从Environment中取得TransactionFactory;TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);//在取得的数据库连接上创建事务对象Transactiontx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);// 创建Executor对象Executor executor = this.configuration.newExecutor(tx, execType);//创建sqlsession对象 。var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);} catch (Exception var12) {this.closeTransaction(tx);throw ExceptionFactory.wrapException("Error opening session.Cause: " + var12, var12);} finally {ErrorContext.instance().reset();}return var8;}可以看到mybatis创建sqlsession经过了以下几个主要步骤:


推荐阅读