zoukankan      html  css  js  c++  java
  • mybaits(十)mybatis常见面试

     
    面试题总结
    1、MyBatis 解决了什么问题?
    或:为什么要用 MyBatis?
    或:MyBatis 的核心特性?
    1)资源管理(底层对象封装和支持数据源)
    2)结果集自动映射
    3)SQL 与代码分离,集中管理
     
    4)参数映射和动态 SQL
    5)其他:缓存、插件等
    2、MyBatis 编程式开发中的核心对象及其作用?
    SqlSessionFactoryBuilder 创建工厂类
    SqlSessionFactory 创建会话
    SqlSession 提供操作接口
    MapperProxy 代理 Mapper 接口后,用于找到 SQL 执行
    3、Java 类型和数据库类型怎么实现相互映射?
    通过 TypeHandler,例如 Java 类型中的 String 要保存成 varchar,就会自动调
    用相应的 Handler。如果没有系统自带的 TypeHandler,也可以自定义。
    4、SIMPLE/REUSE/BATCH 三种执行器的区别?
    SimpleExecutor 使用后直接关闭 Statement:closeStatement(stmt);
    // SimpleExecutor.java
    public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    Statement stmt = null;
    //中间省略……
    } finally {
    closeStatement(stmt);
    }
    }
    20咕泡出品,必属精品 www.gupaoedu.com
    ReuseExecutor 放在缓存中,可复用:PrepareStatement——getStatement()
    // ReuseExecutor.Java
    public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    //中间省略……
    Statement stmt = prepareStatement(handler, ms.getStatementLog());
    //中间省略……
    }
    private Statement prepareStatement(StatementHandler handler, Log statementLog) throws
    SQLException {
    Statement stmt;
    //中间省略……
    if (hasStatementFor(sql)) {
    stmt = getStatement(sql);
    //中间省略……
    }
    private Statement getStatement(String s) {
    return statementMap.get(s);
    }
    BatchExecutor 支持复用且可以批量执行 update(),通过 ps.addBatch()实现
    handler.batch(stmt);
    // BatchExecutor.Java
    public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
    //中间省略……
    final Statement stmt;
    //中间省略……
    stmt = statementList.get(last);
    //中间省略……
    statementList.add(stmt);
    batchResultList.add(new BatchResult(ms, sql, parameterObject));
    }
    handler.batch(stmt);
    }
     
    7、MyBatis 一级缓存与二级缓存的区别?
    一级缓存:在同一个会话(SqlSession)中共享,默认开启,维护在 BaseExecutor
    中。
    二级缓存:在同一个 namespace 共享,需要在 Mapper.xml 中开启,维护在
    CachingExecutor 中。
    8、MyBaits 支持哪些数据源类型?
    UNPOOLED:不带连接池的数据源。
    POOLED : 带 连 接 池 的 数 据 源 , 在 PooledDataSource 中 维 护
    PooledConnection。
    PooledDataSource 的 getConnection()方法流程图:
     
    JNDI:使用容器的数据源,比如 Tomcat 配置了 C3P0。
    自定义数据源:实现 DataSourceFactory 接口,返回一个 DataSource。
    当 MyBatis 集成到 Spring 中的时候,使用 Spring 的数据源。
    9、关联查询的延迟加载是怎么实现的?
    动态代理(JAVASSIST、CGLIB),在创建实体类对象时进行代理,在调用代理
    对象的相关方法时触发二次查询。
    10、MyBatis 翻页的几种方式和区别?
     
    逻辑翻页:通过 RowBounds 对象。
    物理翻页:通过改写 SQL 语句,可用插件拦截 Executor 实现。
    11、怎么解决表字段变化引起的 MBG 文件变化的问题?
    Mapper 继 承 : 自 动 生 成 的 部 分 不 变 , 创 建 接 口 继 承 原 接 口 , 创 建
    MapperExt.xml。在继承接口和 MapperExt.xml 中修改。
    通用 Mapper:提供支持泛型的通用 Mapper 接口,传入对象类型。
    13、解析全局配置文件的时候,做了什么?
    创建 Configuration,设置 Configuration
    解析 Mapper.xml,设置 MappedStatement
    14、没有实现类,MyBatis 的方法是怎么执行的?
    MapperProxy 代理,代理类的 invoke()方法中调用了 SqlSession.selectOne()
    15、接口方法和映射器的 statement id 是怎么绑定起来的?
    (怎么根据接口方法拿到 SQL 语句的?)
    MappedStatement 对象中存储了 statement 和 SQL 的映射关系
     
    16、四大对象是什么时候创建的?
    Executor:openSession()
    StatementHandler、ResultsetHandler、ParameterHandler:
    执行 SQL 时,在 SimpleExecutor 的 doQuery()中创建
    17、ObjectFactory 的 create()方法什么时候被调用?
    第一次被调用,创建 DefaultResultHandler 的时候:
    DefaultResultSetHandler 类中:
    handleResultSet new DefaultResultHandler()
    第二次被调用,处理结果集的时候:
    DefaultResultSetHandler
    handleResultSets——
    handleRowValues——
    handleRowValuesForSimpleResultMap——
    getRowValue——
    createResultObject——
    createResultObject——
     
    18、MyBatis 哪些地方用到了代理模式?
    接口查找 SQL:MapperProxy
    日志输出:ConnectionLogger、StatementLogger
    连接池:PooledDataSource 管理的 PooledConnection
    延迟加载:ProxyFactory(JAVASSIST、CGLIB)
    插件:Plugin
    Spring 集成:SqlSessionTemplate 的内部类 SqlSessionInterceptor
    19、MyBatis 主要的执行流程?涉及到哪些对象?
     
    20、MyBatis 插件怎么编写和使用?原理是什么?(画图)
    使用:继承 Interceptor 接口,加上注解,在 mybatis-config.xml 中配置
    原理:动态代理,责任链模式,使用 Plugin 创建代理对象
    在被拦截对象的方法调用的时候,先走到 Plugin 的 invoke()方法,再走到
    Interceptor 实现类的 intercept()方法,最后通过 Invocation.proceed()方法调用被
    拦截对象的原方法
    21、JDK 动态代理,代理能不能被代理?能
    22、MyBatis 集成到 Spring 的原理是什么?
    SqlSessionTemplate 中有内部类SqlSessionInterceptor对DefaultSqlSession
    进行代理;
    MapperFactoryBean继承了SqlSessionDaoSupport获取
    SqlSessionTemplate;
    接口注册到 IOC 容器中的 beanClass 是 MapperFactoryBean。
    23、DefaulSqlSession 和 SqlSessionTemplate 的区别是什么?
    1)为什么 SqlSessionTemplate 是线程安全的?
    其内部类 SqlSessionInterceptor 的 invoke()方法中的 getSqlSession()方法:
    如果当前线程已经有存在的 SqlSession 对象,会在 ThreadLocal 的容器中拿到
    SqlSessionHolder,获取 DefaultSqlSession。
    如果没有,则会 new 一个 SqlSession,并且绑定到 SqlSessionHolder,放到
    ThreadLocal 中。
    SqlSessionTemplate 中在同一个事务中使用同一个 SqlSession。
    调用 closeSqlSession()关闭会话时,如果存在事务,减少 holder 的引用计数。否
    则直接关闭 SqlSession。
    2)在编程式的开发中,有什么方法保证 SqlSession 的线程安全?
    SqlSessionManager 同时实现了 SqlSessionFactory、SqlSession 接口,通过
    ThreadLocal 容器维护 SqlSession。 
  • 相关阅读:
    4.4 Iterator(迭代器)
    4.6 Memento(备忘录)
    4.1 Chain of Responsibility(职责链)
    4.5 Mediator(中介者)
    4.7 Observer(观察者)
    4.8 State(状态)
    4.11 Visitor(访问者)
    4.2 Command(命令)
    3.7 Proxy(代理)
    4.10 Template Method(模板方法)
  • 原文地址:https://www.cnblogs.com/flgb/p/12688499.html
Copyright © 2011-2022 走看看