关于Mybatis精致面试题

1. 用过 MyBatis 吧,说一下 MyBatis 流程

1.通过 SqlSessionFactoryBuilder 创建 SqlSessionFactory:
在 SqlSessionFactoryBuilder 的 build()方法中使用 XMLConfigBuilder 用来解析配置文件 mybatis-config.xml,
2.并将数据存放到 Configuration 对象中,然后创建并返回一个 DefautSqlSessionFactory。
3.通过 SqlSessionFactory 创建 SqlSession,用于执行 sql 语句;
4.通过 SqlSession 拿到 Mapper 对象的代理;
5.通过 MapperProxy 调用 Maper 中相应的方法;
6.提交或者回滚
7.关闭 Session

2. MyBatis 中的#{}和${}有什么区别?

#{}内部使用预编译 PreparedStatement 机制执行 SQL,支持?占位符,可以防止 SQL 注入;
- ${}内部采用 Statement 机制将参数和 SQL 拼装在一起发送执行,不支持?占位符,参数只能拼接;
- 只要能用占位符的地方,都建议使用#{}
- 如果是表名或字段名或者 like ‘’位置,建议使用${}

3. Mybatis 是怎么进行分页的?分页插件的原理是什么?

Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页,假分页
可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,
在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。

4.请说一下 Mybatis 的插件运行原理? 怎么编写一个插件?

Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,
Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,
每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法,
当然,它只会拦截那些你指定需要拦截的方法。
实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,做完之后需要在配置文件中配置编写的插件。

5. 通常一个 Xml 映射文件,都会写一个 Mapper 接口与之对应,这个接口的工作原理是什
么?Mapper 接口里的方法能重载吗?

1. 要求 StudentMapper.add()--->Student.xml <INSERT ID=”ADD”>
1.Mapper 接口的全限名,是映射文件中的 namespace 的值,
 2. 接口的方法名,就是映射文件中 MappedStatement 的 id 值,
 接口方法内的参数,就是传递给 sql 的参数;
2. Mapper 接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为 key 值,可唯一定位一个
MappedStatement3. Mapper 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象,
 代理对象 proxy 会拦截接口方法,转而执行 MappedStatement 所代表的 sql,然后将 sql 执行结果返回;
4. Mapper 接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。

6. Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?

1. 还有很多其他的标签:
 <resultMap><parameterMap><sql><include><selectKey>
2. 另外,还有动态 sql 标签:
 <trim><here><set><foreach><if><choose><when><otherwise><bind><sql>为 sql 片段标签,通过<include>标签引入 sql 片段,<selectKey>为不支持自增的主键生成策略标签。

7. Mybatis 都有哪些动态 sql?能说一下动态 sql 的执行原理吗?

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能;
- Mybatis 提供了 9 种动态 sql 标签<trim><here><set><foreach><if><choose><when><otherwise><bind>;
 其执行原理是使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,最后来完成动态 sql 的功能。

8. Mybatis 批量添加用的什么标签?动态标签 foreach 有哪些属性?

<foreach>标签;
<foreach>标签的属性有
- collection:指定输入对象中集合属性
- index:这个属性用来指定用来访问迭代集合下标的名称。如:index="myIndex",则#{myIndex}用来访问当前迭代的下标。
- item:每次遍历生成的对象
- open:开始遍历时拼接的串
- close:结束遍历时两个对象需要拼接的串
- separator:用来分割 foreach 元素迭代的每个元素;

9. Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?MyBatis 怎么生成实体类
的?都有哪些映射形式?DBUitls?Spring?

MyBatis 底层是如何将 resultSet 转换成对象的?反射
<select paraMeterType=”” resultType=com.etoak.Student>
Class cls = Class.forName(com.eotak.Student);
//反射构造目标对象 new 无参构造()
Object target = Cls.newInstance();
//给对象中的属性赋值
Field[] fs = Cls.getDeclaredFields();
For(Field f:fs){
 String fName = f.getName();
 Class fType = f.getType();
 String setter = “set”+fName.substring(0,1).toUpperCase()+fName.substring(1);
Method m = Cls.getDeclaredMethod(setter,fType);
//select sid as id ,sname as name from s;
m.invoke(target,rs.getObject(fName));
}
Return target;MyBatis 中如何配置:
第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系;
第二种是使用 sql 列的别名功能,将列别名书写为对象属性名;
有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是
无法完成赋值的。

10. Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?

- Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载;
 association 指的就是一对一,collection 指的就是一对多查询;
 在 Mybatis 配置文件中,可以配置是否启用延迟加载 <setting name=”lazyLoadingEnabled” value=truefalse>
StudentMapper dao = Session.getMapper();
Student stu = Dao.selectById(id);
System.out.println(stu);
- 它的原理是使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,发送事先保存好的查询关联对象的 sql,
把关联对象查询出来,然后进行赋值;

11.说一下 MyBatis 的 selectKey 标签的使用

selectKey 这个标签主要用于解决“添加数据”时不支持主键自动生成的问题,他可以很随意的设置生成主键的方式;
selectKey 需要注意 order 属性
- MySql 这类支持自动增长类型的数据库中,order 需要设置为 after 才会取到正确的值。
- Oracle 这样取序列的情况,order 需要设置为 before,否则会报错。

12.说一下 MyBatis 和 Hibernate 的区别

1. Hibernate 是全自动,而 MyBatis 是半自动
 Hibernate 完全可以通过对象关系模型实现对数据库的操作,拥有完整的 JavaBean 对象与数据库的映射结构来自动生成 sql。
 而 MyBatis 仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写 sql 来实现和管理。
2. Hibernate 数据库移植性大于 MyBatis ,Hibernate 自动生成 SQL,MyBatis 自己写 SQL
 Hibernate 通过它强大的映射结构和 hql 语言,大大降低了对象与数据库(oracle、mysql 等)的耦合性;
 MyBatis 由于需要手写 sql,因此与数据库的耦合性取决于写 sql 的方式,如果 sql 不具通用性而用了很多某数据库特性的 sql
语句的话,移植性会降低很多,成本高。
3. Hibernate 拥有完整的日志系统,MyBatis 则欠缺一些
 Hibernate 日志系统非常健全,包括:sql 记录、关系异常、优化警告、缓存提示、脏数据警告等;
 MyBatis 则除了基本记录功能外,其它功能薄弱很多。
4. MyBatis 相比 Hibernate 需要关心很多细节
 Hibernate 配置要比 mybatis 复杂的多,学习成本也比 mybatis 高。
5. Sql 直接优化上,Mybatis 要比 Hibernate 方便很多
 Mybatis 的 sql 都是写在 xml 里,因此优化 sql 比 hibernate 方便很多。
 hibernate 的 sql 很多都是自动生成的,无法直接维护 sql;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值