1.企业对开发者mybatis的要求是怎样的

作为一名java开发工程师,对我而言,最简单的了解技术发展趋势的方法是没事儿多看看招聘需求。
毕业后做了几年开发,到了需要记笔记,写博客的时候了,因为总结对于做技术的真的很重要;所以看了看招聘需求,并在网上查了查一些热门的面试题,并结合了自身的面试经历,做了一些对于学习mybatis要点的总结。

企业要求:

对mybatis有深入的应用和优化经验,掌握它的原理机制,有框架开发或重构经验者优先考虑。(这应该就是所谓精通)
 

面试常问的技术点:

什么是orm,说说你对mybatis的理解?
  在关系型数据库中,将表与java对象做了一个映射,通过操作java对象来实现对表的操作,使java开发者更加专注于java代码与流程的开发,更贴近面向对象的开发思想。而mybatis是一个半自动的orm框架,内部对jdbc进行了多层的封装与扩展,通过xml或者注解将接口与sql进行关联与定位,所以需要开发者编写原生sql,并且灵活度更高,更适合敏捷开发与产品的快速迭代。  
  
jdbc的缺点是什么,mybatis是如何解决mybatis缺点的? 
  jdbc需要手动创建和关闭数据库的连接,手动解析结果集,几乎全都需要手动处理,冗余代码极多;mybatis通过xml映射,使开发者关注于接口的设计与sql的编写,至于数据库的驱动和连接的创建销毁以及连接池的应用,都交给框架自己完成。
  
有哪些动态sql标签,动态sql的原理是什么?
  mybatis提供了9种动态标签:trim,where,set,foreach,if,choose,when,otherwise,bind;
  通过这些标签可以使编写的sql可以做一些简单的判断,本质上是一种sql的拼接。

模糊查询 like 语句该怎么写?     
    将%写在java程序的参数中参数上,然后xml文件中使用#{}做sql拼接;
    固定写法,写在xml中:%${value}%。
 
#{}和${}的区别是什么?
  看运行日志文件可以发现: 
  #代表preparestatement,生成?占位符;
  $代表statement,传递的就是参数,拼接的sql;

说说mybatis的接口绑定?
  将接口与sql进行绑定,使用的时候,只要调用接口的方法就可以了;
  可以在方法上使用select,update等注解,使用起来比较方便,但适合表简单,业务简单的情况;
  也可以使用xml配置的方式,dao的xml配置文件要与dao文件在同一个目录,而且xml文件中要使用<mapper namespace="">来指定dao文件,id要对应接口的方法名,适用于sql复杂的情况。
  
dao接口的工作原理是什么,里面的方法可以重载吗?
  不能重载,因为是根据全类名+方法名进行sql定位的,方法重载会使xml出现判断错误;
  dao的工作原理是jdk的动态代理,sqlSession通过getMapper()方法生成接口的代理对象,代理对象里的方法使用sqlsession里通过全类名+方法名和方法定位到xml中的sql语句,根据xml的select,update标签,判断使用jdbc里的execute方法执行。
  
插入数据时,如何获取自动生成的id值?
  原理:在执行insert后,执行一个select last_insert()语句;
  <insert><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"></></>;

怎样才能让接口中的方法传递多个参数?  
  1.接口方法中直接传,在xml中使用#{0},#{1},#{2}来代表参数的下标;
  2.接口中使用@param注解,然后在xml中用#{}来正常表示;
  3.封装成一个map;

如果实体类属性与sql的字段名不同,有哪些解决方式?
  1.编写sql时,查询的字段使用别名;
  2.<resultMap>标签做映射; 
  3.sql查询的结果集为设置为map,然后在java中设置值;
  4.当使用注解时,可以使用@Results和@Result标签设置对应关系;
  5.设置Configuration对象的setMapUnderscoreToCamelCase方法:当属性遵循驼峰命名法并且字段使用下划线,通过修改配置可以做到属性的自动映射;  

mybatis都有哪些Executor执行器?它们之间的区别是什么?

mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor;
SimpleExecutor:每执行一次update或select,就开启一个statement对象,用完立刻关闭statement对象;
ReuseExecutor:执行update或select,以sql作为key查找statement对象,存在就使用,不存在就创建,用完后,不关闭statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用statement对象;
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个statement对象,每个statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同;
Executor的这些特点,都严格限制在sqlSession生命周期范围内,可以在xml中配置sqlsession的ExecutorType。

如何批量插入,能返回生成的主键列表吗?

 能返回,连jdbc都能;
 1.for循环insert
 2.sqlsession设置ExecutorType.BATCH,然后正常使用for循环insert
 3.for循环生成一个list,然后调用insertBatch(),在xml<insert><foreach collection ="list" item="对象" separator =","></></> 

实现一对多有哪几种方式,实现一对一又有哪几种方式?
  一对一:
    从表包含主表的实体对象的引用,在<resultMap>中设置association;
    默认是立即加载;
  一对多:
    主表设置一个从表的list属性,然后在<resultMap>中设置collection;
    一般设置为延迟加载,原理是用cglib生成结果的代理对象,然后当调用代理对象的list属性时,判断代理对象的list是否为null,如果为null就查询list集合,延迟加载的属性为lazyLoadingEnabled=true

了解mybatis的缓存机制吗?
  一级缓存:
    sqlsession的缓存,存入的是对象
    连续两次查询,结果为同一个对象,因为只请求了一次数据库,将查询结果存入到sqlsession的map区域中,查询时先查询缓存
    清空缓存的方法:sqlsession.clearCache()
    当调用了sqlsession的删除修改添加,close,commit等方法,自动删除缓存

  二级缓存:
    sqlFactory的缓存,存的是类似json的数据,不是对象
    创建新对象,将数据写进对象中,所以对象要实现序列化接口
    由同一个sqlsessionfactory创建的sqlsession对象共享  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章