Mybatis

  1. #{}和${}的区别是什么?
    • #{}:预编译处理,将SQL语句#{}使用?代替,能够防止SQL注入
    • ${}:直接替换变量的值
  2. 通常一个XML映射文件,都写一个Dao接口与之对应,请问Dao接口的工作原理是什么?Dao接口内的方法,参数不同时,方法能重载吗?
    • Dao接口就是我们常说的Mapper接口,接口的权限名就是映射文件中的namespace的值,接口中的方法就是映射文件MappedStatement中的id值,方法中的参数就是SQL需要的参数
    • 工作原理:
      • 当我们在调用接口中的方法时,Java使用JDK动态代理为Dao接口创建动态代理对象proxy,代理对象就会拦截接口方法,从而执行对应的MappedStatement的SQL语句
    • 接口方法不能够重载,因为是通过 【接口权限名+方法名】来寻找对应的MappedStatement
  3. Mybatis有几种分页方式?这些分页方式的区别是什么?分页插件的原理是什么?
    • 两种分页方式:
      • 逻辑分页和物理分页
    • 两者的区别:
      • 逻辑分页:Mybatis自带的分页方式,一次性获取很多条数据,并对这些数据进行检索分页
      • 物理分页:需要我们自己手写SQL语句或使用外部插件PageHelper来完成分页
    • 分页插件的原理:
      • 我们通过Mybatis提供的外部插件接口,实现外部插件,在插件方法内拦截SQL语句,重写SQL语句,根据不同的dialect方言,来设置物理分页语句和物理分页参数
  4. RowBounds是一次性查询全部结果吗?为什么?
    • 从结果来看是一次性查询所有结果,但实际上是查询出一些结果,因为Mybatis是对JDBC进行封装,而JDBC的配置中有Fetch size参数,规定每次查询出的结果条数,假如我们需要查询更多的数据,它会在我们调用next()的时候,查询更多的数据。就好比我们去ATM机取10k,而ATM机限制每次只能去5k,我们就需要取两次才能取完。这样做的好处就是能够防止内存泄漏的问题
  5. 如何获取自动生成的主键值?
    • 在配置文件中配置 usegeneratedkeys="true"
  6. Mybatis动态SQL是做什么的?都有哪些动态SQL?能简述一下动态SQL的执行原理吗?
    • Mybatis的动态SQL就是可以在xml配置文件中通过标签来写SQL,完成逻辑判断和动态拼接SQL的功能
    • Mybatis提供了9个标签:trim|where|set|foreach|if|otherwise|bind|choose|when
    • 其执行原理为,使用OGNL计算出SQL参数对象表达式的值,通过表达式的值来动态拼接SQL,从而完成动态SQL的功能
  7. Mybatis的XML映射文件中,不同的XML映射文件,id是否可以重复?
    • 不同的XML映射文件中,如果设置了namespace的值那么id可以重复;如果没有设置namespace的值那么id不能重复,因为在使用XML中的方法时,通过namespace+id来定位方法的,如果相同就会导致数据相互覆盖,所以当设置了namespace的值id则能重复,否则id不能重复
  8. 为什么说Mybatis是半自动化的ORM映射文件?它与自动化的区别在哪里?
    • Hibernate全自动ORM框架在进行对象关联查询或对象集关联查询时,能够通过对象的关系模型直接获得结果,而Mybatis在进行对象关联查询或对象集关联查询时,需要程序员自己手写SQL语句完成,所以被称为半自动ORM框架
  9. 接口绑定有几种实现方式,分别是怎么实现的?
    • 一共有两种:
      • 在方法上面直接使用@select()、@update()等后面直接写SQL语句
      • 在XML文件中写SQL来进行绑定,需要指定XML映射文件中的namespace必须是mapper接口的全路径名
  10. Mybatis的缓存机制?
    • 一级缓存:
      • SqlSession级别的缓存,缓存数据存储在HashMap中,在进行第一次查询时,首先会从数据库中查询出结果,然后将结果存在一级缓存中;当我们第二次查询时,首先会查询一级缓存,如果一级缓存没有在查询数据库。在进行CUD操作并执行了commit或关闭Sqlsession后会将缓存清空,如果二级缓存是开启的那么会将数据缓存到二级缓存中。默认一级缓存是开启的
    • 二级缓存:
      • Mapper级别的缓存,拥有多个SqlSession,执行同一Mapper中的SQL语句,数据也存储在HashMap中,并且每个SqlSession中的缓存内容共享。Java类若要使用二级缓存则需要实现Serializable接口。在进行第一次查询时,首先会从数据库中查询出结果,然后将结果存在二级缓存中;当我们第二次查询时,先在二级缓存中查询,没有就查询一级缓存,最后才会进行数据库的查询。在进行CUD操作并执行了commit,缓存会被清空,默认不开启,开启需要在配置文件中设置“<setting name="cacheEnabled"value="true"/>”
  11. Mybatis的基本工作流程?
    • 读取Mybatis的配置文件,配置文件中包含了数据库连接信息和Mapper映射文件或Mapper包路径
    • 通过这些信息能够创建SqlSessionFactory,SqlSessionFactory的生命周期是程序级的,程序启动时创建,程序结束时销毁
    • SqlSessionFactory负责创建Sqlsession,Sqlsession负责执行SQL语句,Sqlsession生命周期是过程级的,方法执行时创建,方法结束时关闭
    • 在使用mapper.xml时,Mybatis会先解析SQL动态标签为指定数据库形式的SQL,然后封装到MapperStatement对象中,通过executor将SQL语句注入数据库中执行,并返回结果
    • 最后将结果通过映射,包装到java对象
  12. Mybatis如何开启延迟加载?延迟加载的原理?
    • 在配置文件中设置“<setting name="LazyLoadingEnable"value="true"/>”即可
    • 延迟加载原理:
      • 通过执行触发加载,而不是程序启动就已经加载。比如:在执行a.getB().getName()时,发现a.getB()为null,那么就单独触发已经关联好的B对象的SQL,查询出B对象,进行a.setB(b),最后再执行a.getB().getName()就会有值了
  13. Mybatis都有哪些Executor的执行器?他们之间的区别是什么?
    • Mybatis的三大基本Executor执行器:
      • SimpleExecutor:当每执行一次CURD时,都会创建一个Statement对象,使用完毕关闭Statement对象
      • ReuseExecutor:当执行CURD时,以SQL作为key进行查找Statement对象,有则使用,没有则创建,使用完毕不会直接关闭,而是将其放入Map<String,Statement>中,以供下次使用
      • BatchExecutor:当执行CUD时(select没有批处理操作),将已经写好的SQL语句放入批处理方法(addBatch())中,等待批处理统一执行(executeBatch()),它缓存了多个Statement对象,并且这些对象都已经通过addBatch()处理,等待统一执行
  14. Mybatis的优点是什么?
    • Mybatis将SQL分离出来放在一个XML文件中,便于维护,并且我们可以自己手写SQL语句,对SQL语句进行优化以及能够写复杂SQL,从而效率就全自动ORM框架要高
    • Mybatis封装了底层的JDBC API,能够将结果转换为JavaBean对象,减少了数据库代码的重复工作
 
posted @ 2019-10-12 16:45  SvaloR  阅读(267)  评论(0)    收藏  举报