zoukankan      html  css  js  c++  java
  • Mybatis源码:查询流程

    测试方法:

        @Test
        public void test01() throws IOException {
            //1.根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
            SqlSession session = sqlSessionFactory.openSession();
            try {
                EmployeeMapper employeeMapper= session.getMapper(EmployeeMapper.class);
                Employee emp = employeeMapper.getEmpById(1);
                System.out.println(emp);
    
                session.clearCache();
    
                Employee emp2 = employeeMapper.getEmpById(2);
                System.out.println(emp2);
                System.out.println(emp==emp2);
            } finally {
                session.close();
            }
        }
    
        private SqlSessionFactory getSqlSessionFactory() throws IOException {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            return new SqlSessionFactoryBuilder().build(inputStream);
        }
    

    给mapper的查询方法打上断点,执行。发现方法最终执行的是MapperProxy的invoke方法,先执行Object类的方法,在执行cachedMapperMethod方法,返回一个MapperMethod类,然后执行MapperMethod的execute方法

    image-20210114122954361

    因为我设置查询方法且直接返回了对象,所以执行到selectOne方法

    image-20210114131227541

    而selectOne执行的还是selectList,然后获取了第一个元素并返回

    image-20210114131433758

    selectList最后由executor去执行query,因为我这里开启了二级缓存,所以这里executor是CachingExecutor

    image-20210114131603611

    query方法:先创建BoundSql,其中包含sql语句,查询参数等,然后创建一个CacheKey作为二级缓存的key

    image-20210114131914570

    image-20210114132411692

    执行了delegate的query方法,而这个delegate是SimpleExecutor

    image-20210114132903263

    我们去看queryFromDatabase方法

    image-20210114133708538

    doQuery方法,先去获取configuration,再根据configuration创建statementHandler,点击进去

    image-20210114134324201

    在newStatementHandler方法中,期间会被插件拦截器拦截处理image-20210114140928785

    跳出方法,点击prepareStatement方法,与编译产生statement对象,

    handler.parameterize(stmt):预编译sql,产生preparedStatement对象

    image-20210114141045578

    在BaseStatementHandler中设置了ParameterHandler和ResultSetHandler,这两个方法同样会被插件拦截器拦截处理。

    image-20210114144412881

    在DefaultParameterHandler中使用类型处理器(TypeHandler)设置sql参数

    image-20210114143822167

    在SimpleStatementHandler中执行query查询sql,并使用resultSetHandler处理查询结果

    image-20210114144039114

    resultSetHandler处理流程后面就不看了,比较复杂,不过最后还是由TypeHandler处理返回值类型。

    查询流程总结:

    image-20210114145259232

    注意:四大对象:Executor,StatementHandler,ParameterHandler,ResultSetHandler在创建的时候,都会被插件拦截器拦截。

  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/14277226.html
Copyright © 2011-2022 走看看