zoukankan      html  css  js  c++  java
  • mybatis源码笔记

    mybatis设计总览

    目录结构:

    通过配置文件,获取SqlSessionFactory

    XMLConfigBuilder 解析配置文件,获取SqlSessionFactory

        private static SqlSessionFactory getSqlSessionFactory() {
            String resource = "mybatis/mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            return sqlSessionFactory;
        }
    
    

    mybatis-config.xml,数据源和mapper配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <typeAlias type="entity.User" alias="User"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost/mybatisLearn"/>
                    <property name="username" value="mysql"/>
                    <property name="password" value="mysql"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper resource="mapper/UserMapper.xml"/>
        </mappers>
    
    </configuration>
    

    SqlSessionFactory的属性和方法

        private final Configuration configuration;
    
        public SqlSession openSession() {
            return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
        }
    
        private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
            Transaction tx = null;
    
            DefaultSqlSession var8;
            try {
                Environment environment = this.configuration.getEnvironment();
                TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
                tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
                Executor executor = this.configuration.newExecutor(tx, execType);
                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;
        }
    
    
    

    SqlSessionFactory的功能就是获取SqlSession,默认实现类DefaultSqlSession,DefaultSqlSession可以执行curd,也可以通过获取mapper来执行curd
    DefaultSqlSession是直接执行sql操作数据库,mapper是通过接口方法(实际上还是要映射sql)
    sqlSession可以指定事务隔离级别

    TransactionIsolationLevel:

        NONE(0),
        READ_COMMITTED(2),
        READ_UNCOMMITTED(1),
        REPEATABLE_READ(4),
        SERIALIZABLE(8);
    

    DefaultSqlSession的属性和方法

        private Configuration configuration;
        private Executor executor;
        private boolean autoCommit;
        private boolean dirty;
        private List<Cursor<?>> cursorList;
    
        public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
            try {
                MappedStatement ms = this.configuration.getMappedStatement(statement);
                this.executor.query(ms, this.wrapCollection(parameter), rowBounds, handler);
            } catch (Exception var9) {
                throw ExceptionFactory.wrapException("Error querying database.  Cause: " + var9, var9);
            } finally {
                ErrorContext.instance().reset();
            }
    
        }
    
        public int update(String statement, Object parameter) {
            int var4;
            try {
                this.dirty = true;
                MappedStatement ms = this.configuration.getMappedStatement(statement);
                var4 = this.executor.update(ms, this.wrapCollection(parameter));
            } catch (Exception var8) {
                throw ExceptionFactory.wrapException("Error updating database.  Cause: " + var8, var8);
            } finally {
                ErrorContext.instance().reset();
            }
    
            return var4;
        }
    
       public void commit(boolean force) {
            try {
                this.executor.commit(this.isCommitOrRollbackRequired(force));
                this.dirty = false;
            } catch (Exception var6) {
                throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + var6, var6);
            } finally {
                ErrorContext.instance().reset();
            }
    
        }
    
       public <T> T getMapper(Class<T> type) {
            return this.configuration.getMapper(type, this);
        }
    
    

    Configuration是对mybatis-config.xml解析后的封装,配置文件的节点对应Configuration的属性
    例如:<environment 对应 protected Environment environment;

    注意Executor是在SqlSessionFactory中就获取的:Executor executor = this.configuration.newExecutor(tx, execType);
    实际上调用的configuration中的方法:

        public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
            executorType = executorType == null ? this.defaultExecutorType : executorType;
            executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
            Object executor;
            if (ExecutorType.BATCH == executorType) {
                executor = new BatchExecutor(this, transaction);
            } else if (ExecutorType.REUSE == executorType) {
                executor = new ReuseExecutor(this, transaction);
            } else {
                executor = new SimpleExecutor(this, transaction);
            }
    
            if (this.cacheEnabled) {
                executor = new CachingExecutor((Executor)executor);
            }
    
            Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
            return executor;
        }
    

    根据参数生成对应的executor的实现
    看看抽象类BaseExecutor的方法:

        protected Transaction transaction;
        protected Executor wrapper;
        protected ConcurrentLinkedQueue<BaseExecutor.DeferredLoad> deferredLoads;
        protected PerpetualCache localCache;
        protected PerpetualCache localOutputParameterCache;
        protected Configuration configuration;
        protected int queryStack = 0;
        private boolean closed;
    
    
       public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
            ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
            if (this.closed) {
                throw new ExecutorException("Executor was closed.");
            } else {
                if (this.queryStack == 0 && ms.isFlushCacheRequired()) {
                    this.clearLocalCache();
                }
    
                List list;
                try {
                    ++this.queryStack;
                    list = resultHandler == null ? (List)this.localCache.getObject(key) : null;
                    if (list != null) {
                        this.handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
                    } else {
                        list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
                    }
                } finally {
                    --this.queryStack;
                }
    
                if (this.queryStack == 0) {
                    Iterator i$ = this.deferredLoads.iterator();
    
                    while(i$.hasNext()) {
                        BaseExecutor.DeferredLoad deferredLoad = (BaseExecutor.DeferredLoad)i$.next();
                        deferredLoad.load();
                    }
    
                    this.deferredLoads.clear();
                    if (this.configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
                        this.clearLocalCache();
                    }
                }
    
                return list;
            }
        }
    
    

    看看其中的SimpleExecutor:

        public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
            Statement stmt = null;
    
            int var6;
            try {
                Configuration configuration = ms.getConfiguration();
                StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, (ResultHandler)null, (BoundSql)null);
                stmt = this.prepareStatement(handler, ms.getStatementLog());
                var6 = handler.update(stmt);
            } finally {
                this.closeStatement(stmt);
            }
    
            return var6;
        }
    
        public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
            Statement stmt = null;
    
            List var9;
            try {
                Configuration configuration = ms.getConfiguration();
                StatementHandler handler = configuration.newStatementHandler(this.wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
                stmt = this.prepareStatement(handler, ms.getStatementLog());
                var9 = handler.query(stmt, resultHandler);
            } finally {
                this.closeStatement(stmt);
            }
    
            return var9;
        }
    

    还是调用的configuration的方法

    处理sql相关的类

    MappedStatement,获取BoundSql

        public BoundSql getBoundSql(Object parameterObject) {
            BoundSql boundSql = this.sqlSource.getBoundSql(parameterObject);
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            if (parameterMappings == null || parameterMappings.isEmpty()) {
                boundSql = new BoundSql(this.configuration, boundSql.getSql(), this.parameterMap.getParameterMappings(), parameterObject);
            }
    
            Iterator i$ = boundSql.getParameterMappings().iterator();
    
            while(i$.hasNext()) {
                ParameterMapping pm = (ParameterMapping)i$.next();
                String rmId = pm.getResultMapId();
                if (rmId != null) {
                    ResultMap rm = this.configuration.getResultMap(rmId);
                    if (rm != null) {
                        this.hasNestedResultMaps |= rm.hasNestedResultMaps();
                    }
                }
            }
    
            return boundSql;
        }
    

    BoundSql,获取执行的sql

        private String sql;
        private List<ParameterMapping> parameterMappings;
        private Object parameterObject;
        private Map<String, Object> additionalParameters;
        private MetaObject metaParameters;
    

    BaseStatementHandler,获取Statement

        public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
            ErrorContext.instance().sql(this.boundSql.getSql());
            Statement statement = null;
    
            try {
                statement = this.instantiateStatement(connection);
                this.setStatementTimeout(statement, transactionTimeout);
                this.setFetchSize(statement);
                return statement;
            } catch (SQLException var5) {
                this.closeStatement(statement);
                throw var5;
            } catch (Exception var6) {
                this.closeStatement(statement);
                throw new ExecutorException("Error preparing statement.  Cause: " + var6, var6);
            }
        }
    
    

    SimpleStatementHandler,获取Statement

       protected Statement instantiateStatement(Connection connection) throws SQLException {
            return this.mappedStatement.getResultSetType() != null ? connection.createStatement(this.mappedStatement.getResultSetType().getValue(), 1007) : connection.createStatement();
        }
    
    
        public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
            String sql = this.boundSql.getSql();
            statement.execute(sql);
            return this.resultSetHandler.handleResultSets(statement);
        }
    

    最终还是JDBC的那一套。

  • 相关阅读:
    HDU——1061Rightmost Digit(高次方,找规律)
    HDU——1019Least Common Multiple(多个数的最小公倍数)
    HDU——1013Digital Roots(九余数定理)
    HDU——1020Encoding(水题,string过)
    HDU——2093考试排名(string类及其函数的运用以及istringstream)
    廖雪峰Java3异常处理-2断言和日志-4使用Log4j
    廖雪峰Java3异常处理-2断言和日志-3使用Commons Logging
    廖雪峰Java3异常处理-2断言和日志-2使用JDK Logging
    廖雪峰Java3异常处理-2断言和日志-1使用断言
    Charles问题
  • 原文地址:https://www.cnblogs.com/lanqie/p/9544631.html
Copyright © 2011-2022 走看看