1. 什么是ORM框架?

    ORM框架全称: Object Retional Mapping, 做数据库列名

  2. 使用JDBC手写一个连接关闭, 然后查询一条sql.

    public static final String CONNECTION_URL = "jdbc:mysql://***.***.***.***:3306/questions";
        public static final String USERNAME = "root";
        public static final String PASSWORD = "*****";
        public static final String DRIVE_NAME = "com.mysql.cj.jdbc.Driver";
    
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            // 获取驱动, Java1.6和mysql驱动5.1之后,不再需要这个了.
            Class.forName(DRIVE_NAME);
            // 输入账密
            Connection connection = DriverManager.getConnection(CONNECTION_URL, USERNAME, PASSWORD);
            // 输入sql
            String sql = "select question_id, question_text, question_score, create_time, create_by, type, exam_id,\n" +
                    "               question_comment,question_tag,question_img_url\n" +
                    "               from questions.question WHERE question_id=2 ";
            PreparedStatement ps = connection.prepareStatement(sql);
            // 获得结果
            ResultSet resultSet = ps.executeQuery();
            while (resultSet.next()) {
                String question_text = resultSet.getString("question_text");
                System.out.println(question_text);
            }
            // 关闭连接
            ps.close();
            connection.close();
        }
    
  3. JDBC的弊端

    1. 更新sql需要重新编译, 因为sql是嵌入在Java代码中.
    2. 需要自己处理ResultSet, 手动映射数据表和对象, 不利于维护.
    3. 自己管理资源的申请和关闭, 每次连接数据库都需要重连Connection, 不友好, 需要自己封装.
    4. JDBC底层没有用连接池, 操作数据库需要频繁的创建和销毁连接.
    5. 正是因为这些弊端, 所以产生了ORM框架.
  4. Mybatis数据处理层分为那四步?

    1. 参数映射, 包含"参数配置映射", “参数映射解析”,“参数类型解析”, 对应的类为ParameterHander
    2. Sql解析, 包含"SQL语句解析", “SQL语句配置"和"SQL语句动态生成”, 对应的类为SqlSource
    3. Sql执行, 主要交给Executor去执行, 对应的实现为:“SimpleExecutor”, “ReuseExecutor”, “BatchExecutor”
    4. 结果处理和映射, 包含"结果映射配置", “结果类型转换”, 对应的类为:ResultSetHandler

  5. 解析Mapper.xml文件在那个包下? 解析config.xml是在那个包下?

    • builder报下, 建造器类中处理解析这两个xml
  6. SqlSession都提供了那些方法?

  7. Mybatis结构分成三层?分别是什么作用?

    1. 接口层: 提供给外部使用的接口API, 开发人员通过这些API来操作数据库, 接口层只负责接受, 实际处理交给核心处理层, 这一点类似我们的Controller层
    2. 核心处理层: 类似我们的Service层, 主要负责配置解析, 参数映射=>SQL解析与SQL执行, 并将执行结果压到对应的对象中.
    3. 基础支撑层 : 这一类类似我们的util包和DAO层, 主要提供包括不限于"缓存", “事务”,“数据源管理”, “日志”, "资源加载"等基础功能.
  8. Mybatis如何获取数据源

    • Mybatis在XMLConfigBuilder里有一个environmentsElement() 的方法,在这里会取到Config.xml中配置的jdbc属性.从而获取到DataSource.
  9. Mybatis如何获取执行sql

    1. 在配置解析里, 所有我们写的Sql都被加载为MappedStatement对象了
    2. 当接口层被调用时, 会通过调用的接口的全限定名和接口方法名拼接成一个字符串,然后去Configuration中获取对应的MappedStatement对象.
    3. 此外将接口方法的参数传给MappedStatemnt, 通过SqlSource来解析出一条BoundSql对象. 然后通过MappedStatemnt和BoundSql这两个对象, 获取最终的PreparedStatement. 完成Sql解析和参数映射. `
  10. Mybatis如何完成参数映射和结果封装

    • 首先是在StatementHandler的时候, 制造一个映射, <key,value>, key的内容是 如果有@Param注解的话, 使用value作为key, 如果没有使用arg + i作为key. 然后当执行sql之前, 会通过ParamterHandler来处理, 遍历所有的占位符, 并尝试从键值对中取value.
  11. Mybatis如何操作数据库

    • 通过SqlSession暴露接口给应用层, 使用Executor接口去操作数据库.
    • 当然Executor底层还是最终调用了Statement接口的execute接口.
  12. SqlSession是个接口, 其作用是什么? 底层真正干活的是哪个类? 这是什么设计思想? 有哪些好处?

    • 作用是对外提供接口, 真正干活的是Executor接口, 用的是门面设计模式, 对使用者屏蔽掉复杂的内部实现, 只提供若干接口供外部使用.
  13. 简要描述一下Configuration类的作用. 什么时候被创建呢?

    • 配置文件的对象类, 在应用读取mybatis-config.xml的时候, 使用建造器模式, 将xml中的内容全部读入到java对象中.
  14. Executor接口有哪些实现类, 分别有什么区别?

    1. CachingExecutor是一个包装增强类, 主要用于第二层缓存. 真正的很多逻辑都是在Base中
    2. Simple是最简实现, 其他的几个都是在Simple上对某一方面的优化.
    3. Reuse是对同一个事务中的sql进行预编译缓存.
    4. Batch是对批量更新/插入的sql 进行优化.
    5. ClosedExecutor不常用.
  15. Mybatis都用了什么设计模式?

    1. 装饰者模式, 比如CachingExecutor和cache包下的各个装饰者.
    2. 建造器模式 , 例如SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder
    3. 门面模式, SqlSession和底层实现.
    4. 工厂模式, 例如SqlSessionFactory、MapperProxyFactory
    5. 单例模式, ErrorContext和LogFactory
    6. 代理模式 , Mybatis实现的核心,比如MapperProxy、ConnectionLogger,用的jdk的动态代理;还有executor.loader包使用了cglib或者javassist达到延迟加载的效果;
    7. 模板方法, BaseExecutor和SimpleExecutor,还有BaseTypeHandler和所有的子类例如IntegerTypeHandler
    8. 迭代器模式
    9. 组合模式 , 例如SqlNode和各个子类ChooseSqlNode等;
  16. 里面有几种配置的方式?

    1. 三种
    2. 一种
  17. 把xml文件转为对象,然后再去解析对象, 进行java操作, 这一点与安卓相同. xml在Mybatis中做输入接口, 在安卓/前端里做布局. 那么一条sql语句会被封装成对象吗? 如果封装的话, 是哪个类?

    • MappedStatement对象
  18. Mybatis的cache有哪几种evication算法

    • PERPETUAL, 不设置过期算法, 旨在调用clear的时候, 清楚缓存
    • LRU, LinkedListHashMap
    • FIFO, Queue
    • SOFT, 软引用,移除基于垃圾回收器状态和软引用规则的对象
    • WEAK, 弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象
  19. 实现一下FIFO和LRU算法 (理解LinkedHashMap)

  20. 为什么需要先向缓存中放一个占位符?

    • 解决循环依赖
  21. Mybatis 默认一级缓存是开启还是关闭的?

    1. 一级缓存默认开启, 二级缓存在3.0之后也是默认开启的, 不过需要在Mapper.xml里加上注解.
  22. loadCustomVfs(settings); 这个VFS是什么?

    • loadCustomVfs 是获取Vitual File System 的自定义实现类,比如我们要读取本地文件,或者FTP 远程文件的时候,就可以用到自定义的VFS 类。我们根据标签里面的标签,生成了一个抽象类VFS 的子类,并且赋值到Configuration中。
  23. properties节点, resource和url的区别是什么? 能同时写吗?

    • 不能同时写, resource是读取本地文件, url是读取远程文件. 互斥的.
  24. MetaClass中, 如果处理getter方法和setter的冲突, 那些原因造成的冲突呢?

  25. 配置解析主要是那两个包?

    1. session和builder包, builder包是解析xml, 最终生成Configuration和SelSession.
      
  26. SqlSource有哪些实现类, 分别作用是什么?

  27. Mybatis基础支撑层都有哪些功能, 试举例三种以上.

  28. CacheKey的作用是什么?

  29. XPath 怎么知道按照什么规则进行解析? 如何获取这个规则的?

  30. 里面的有几种属性, 还有其他方案吗?

  31. ResueExecutor和Simple区别是什么? 具体是怎么实现的这些区别?

  32. 一级缓存什么时候会被清除?

  33. Executor何时创建的? 支持自定义type吗?

  34. Mybatis如何把Xml里的Sql转为可执行的

更多推荐

Mybatis源码面试题汇总(持续更新中, 答案收集中)