SqlSession源码分析(代完成)

前言

在Mybatis中的核心操作是:SqlSession实例对象是Mybatis中用来执行sql语句的核心类。sql语句在Mybatis中的核心执行简化后逻辑如下(好好看注释内容):

//1.通过mybatis-config.xml来获取一个输入流
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml")
//2.通过该输入流来建造一个SqlSessionFactory对象factory,
//注意:这里使用了匿名构造对象,没有具体的引用指向它,因此只能用一次,用完后垃圾回收器会自动调用Fianlization函数把它给回收了
factory = new SqlSessionFactoryBuilder().build(inputStream);
//3.通过factory创建一个SqlSession对象
SqlSession sqlSession = factory.openSession();
//4.把SqlSession对象放入ThreadLocal变量中(将不会被其他线程所获取)
private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
local.set(sqlSession);
//5.可通过get方法来获取本线程中的sqlSession。
SqlSession session=local.get()

一.这三个重要类的生命周期和作用域

  【SqlSessionFactoryBuilder生命周期】:在创建了SqlSessionFactory创建了之后将失效,因此我们将它放在静态代码块中,整个程序中,只执行一次。
  【SqlSessionFactory生命周期】:可以看做一个数据库连接池。SqlSessionFactory一个程序只需要有一个就行,一旦创建后就会一直存在(也可以创建多个,但是会引起资源的浪费)。最好使用单例模式或者静态单例模式
  【SqlSession生命周期】:可以看做是连接到连接池的一个请求(需要开启和关闭请求)。每个线程都要有一个SqlSession,且用完要赶紧关闭不然会造成资源浪费。它是非线程安全的


二.源码分析

1.SqlSessionFactoryBuilder分析(还需要去读XMLConfigBuilder的parse源码,很难,待完成)

  SqlSessionFactoryBuilder是专门用来创建SqlSessionFactory,其内部全是用来创建SqlSessionFactory的Build()函数的多个重载方法。在创建SqlSessionFactory的创建过程中,会使用到XMLConfigBuilder的parse函数。XMLConfigBuilder的parse,它的作用是把MyBatis的XML及相关配置解析出来,然后保存到 Configuration中

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.apache.ibatis.session;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;

public class SqlSessionFactoryBuilder {
    public SqlSessionFactoryBuilder() {
    }

    public SqlSessionFactory build(Reader reader) {
        return this.build((Reader)reader, (String)null, (Properties)null);
    }

    public SqlSessionFactory build(Reader reader, String environment) {
        return this.build((Reader)reader, environment, (Properties)null);
    }

    public SqlSessionFactory build(Reader reader, Properties properties) {
        return this.build((Reader)reader, (String)null, properties);
    }

    public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                reader.close();
            } catch (IOException var13) {
            }

        }

        return var5;
    }

    public SqlSessionFactory build(InputStream inputStream) {
        return this.build((InputStream)inputStream, (String)null, (Properties)null);
    }

    public SqlSessionFactory build(InputStream inputStream, String environment) {
        return this.build((InputStream)inputStream, environment, (Properties)null);
    }

    public SqlSessionFactory build(InputStream inputStream, Properties properties) {
        return this.build((InputStream)inputStream, (String)null, properties);
    }
//以下这个函数是SqlSessionFactoryBuilder的核心代码。但是会跳转到XMLConfigBuilder中去,由于看不懂其源码,我就先不讲了,以后再说
    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);
    }
}

2.SqlSessionFactory源码分析

  SqlSessionFactory是SqlSession的抽象工厂,是一个接口,其内部所有函数都是用来构造SqlSession的openSession抽象函数。这样也会引出一个问题,既然SqlSessionFactory是一个接口,那它是怎么产生的SqlSession类的对象的呢?实际上,SqlSessionFactoryBuilder通过builder方法会产生一个SqlSessionFactory接口的实现类,该类中已经实现了openSession方法了。

package org.apache.ibatis.session;
import java.sql.Connection;
public interface SqlSessionFactory {
    SqlSession openSession();
    SqlSession openSession(boolean var1);
    SqlSession openSession(Connection var1);
    SqlSession openSession(TransactionIsolationLevel var1);
    SqlSession openSession(ExecutorType var1);
    SqlSession openSession(ExecutorType var1, boolean var2);
    SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);
    SqlSession openSession(ExecutorType var1, Connection var2);
    Configuration getConfiguration();
}
3.SqlSession源码分析

SqlSession是一个用来执行sql语句的接口,其内部几乎所有的函数都是与sql语句相关的。但是

  通过查看SqlSession的源码(下面会查看),我们会发现SqlSession中除了是增删改查,提交和回滚操作外,还有几个重要的方法,它们的作用我写在了注释中了。

package org.apache.ibatis.session;
import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;

public interface SqlSession extends Closeable {
    <T> T selectOne(String var1);
    <T> T selectOne(String var1, Object var2);
    <E> List<E> selectList(String var1);
    <E> List<E> selectList(String var1, Object var2);
    <E> List<E> selectList(String var1, Object var2, RowBounds var3);
    <K, V> Map<K, V> selectMap(String var1, String var2);
    <K, V> Map<K, V> selectMap(String var1, Object var2, String var3);
    <K, V> Map<K, V> selectMap(String var1, Object var2, String var3, RowBounds var4);
    <T> Cursor<T> selectCursor(String var1);
    <T> Cursor<T> selectCursor(String var1, Object var2);
    <T> Cursor<T> selectCursor(String var1, Object var2, RowBounds var3);
    void select(String var1, Object var2, ResultHandler var3);
    void select(String var1, ResultHandler var2);
    void select(String var1, Object var2, RowBounds var3, ResultHandler var4);
    int insert(String var1);
    int insert(String var1, Object var2);
    int update(String var1);
    int update(String var1, Object var2);
    int delete(String var1);
    int delete(String var1, Object var2);
    void commit();//提交操作。由于Mybatis对数据库的操作是在缓存中进行的,如果不提交,讲不会对数据库有任何影响。
    void commit(boolean var1);
    void rollback();//回滚,使得所有未提交的sqlSession操作的撤回
    void rollback(boolean var1);
    List<BatchResult> flushStatements();
    void close();//关闭SqlSession
    void clearCache();//清除缓存,Mybatis有三级缓存机制。
    Configuration getConfiguration();//?
    <T> T getMapper(Class<T> var1);//
    Connection getConnection();//?
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值