Mybatis面试题

Q:什么是Mybatis?

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL存储过程以及高级映射

MyBatis 避免了几乎所有的 JDBC 代码手动设置参数以及获取结果集

MyBatis 可以使用简单的 XML注解来配置和映射原生信息、将接口Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)映射为数据库中的记录。


Q:MyBatis与Hibernate有哪些不同?

相同点
都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。

不同点
Hibernate:是一个全自动映射的框架,不需要编写SQL就能对数据库进行操作。对于SQL的修改和优化比较困难。比较适合需求变化不大的中小型项目:OA,ERP、管理系统等

MyBatis:是一种半自动映射的框架,专注于SQL本身,对SQL修改和优化比较简单,支持对象关系映射。需要是手动实现SQL。比较适合需求变化比较多的互联网项目。


Q:#{}和${}的区别是什么?

(1)#{}是预编译处理,${}是字符串替换
(2)Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
(3)Mybatis在处理${}时,就是把{}替换成变量的值。
(4)使用#{}可以有效的防止SQL注入,提高系统安全性


Q:当实体类中的属性名和表中的字段名不一样如何解决?

第1种: 让SQL语句字段名的别名和实体类的属性名一致。
第2种: 通过<resultMap>来映射字段名和实体类属性名一 一对应。

第1种:

<select id="getOrder" parameterType="int" resultType="com.jourwon.pojo.Order">
       select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>

第2种:

<select id="getOrder" parameterType="int" resultMap="orderResultMap">
	select * from orders where order_id=#{id}
</select>

<resultMap type="com.jourwon.pojo.Order" id="orderResultMap">
    <!–用id属性来映射主键字段–>
    <id property="id" column="order_id">

    <!–用result属性来映射非主键字段,property为实体类属性名,column为数据库表中的属性–>
    <result property ="orderno" column ="order_no"/>
    <result property="price" column="order_price" />
</reslutMap>

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

(1)<resultMap>结果集:配置实体类属性结果集列名的对应关系。

(2)<selectKey>:selectKey返回最近插入的id。

(3)多表配置关联关系:collection(对一),association(对多)

(4)定义常量及引用:<sql>封装重复的SQL片段,通过<include>标签引入sql片段

(5)格式化输出:where格式化 ,set格式化, trim。

(6)控制动态SQL拼接:if选择, foreach循环, choose (when otherwise)相当于switch。
在这里插入图片描述


Q:通常一个Xml映射文件,都会写一个Dao接口与之对应,这个Dao接口的工作原理是什么?

Dao接口即Mapper接口。

接口的全限名,就是映射文件中的namespace的值;(com.song.dao.IUserDao
接口的方法名,就是映射文件中Mapper的Statement的id值;(findAll
接口方法内的参数,就是传递给sql的参数。

Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement。在Mybatis中,每一个select、insert、update、delete标签,都会被解析为一个MapperStatement对象。

public interface IUserDao {
	List<User> findAll();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper  
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.song.dao.IUserDao">
	<!-- 配置查询所有 -->
	<!-- resultType="com.song.domain.User"将结果集封装到User对象 ,添加到List里边 -->
	<!-- id不能随便写,写的是方法名称 -->
	
	<select id="findAll" resultType="com.song.domain.User">
		<!-- 写的是SQL语句 -->
		select * from user
	</select>
	
</mapper>

在MyBatis启动时,会解析这些包含SQL的XML文件,并将其包装成为MapperStatement对象,并将MapperStatement注册到全局的configuration对象上。



Q:介绍一下mybatis缓存?

1.一级缓存: MyBatis在开启一个数据库会话时,会创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象(线程池)。Executor对象中持有一个新的PerpetualCache对象(缓存类);

何时清空一级缓存?
当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

2.二级缓存:二级缓存其作用域是SqlSessionFactory。其默认是不开启的,二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置就可以开启缓存了

注意: 对于缓存数据更新机制,当某一个作用域(一级缓存 SQLSession/二级缓存SQLSessionFactory)的进行了cud操作后,默认该作用域下所有select中的缓存将被clear掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。


Q:Mybatis是如何进行分页的?分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

举例:select * from student
拦截sql后重写为:select t.* from (select * from student) t limit 0, 10


Q:如何获取自动生成的id?

1    <insert id="xxx" usegeneratedkeys="true" keyproperty="id">
2         insert into xxxx (xxx) values (#{xxxx})
3    </insert>

Q:在mapper中如何传递多个参数?

1、对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数
2、使用 @param 注解
3、使用map封装参数


Q:MyBatis的mapper接口调用时有那些限定?

1、Mapper接口方法名和mapper.xml中定义的每个sql的id相同
2、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
3、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
4、Mapper.xml文件中的namespace即是mapper接口的类路径。



Q:Mybatis 与 JDBC 编程的比较

(1)数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。
解决:在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。

(2)Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。

(3)向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。

(4)对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。
解决:Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值