mybatis面试题
-
#{} 和 \({} 区别是什么(\)读 dollar [ˈdɑːlər])
#{}
是预编译处理,${}
是字符串替换。 Mybatis在处理#{}
时,会将sql中的#{}
替换为?号,调用PreparedStatement的set方法来赋值; Mybatis在处理${}
时,就是把${}
替换成变量的值。 使用#{}
可以有效的防止SQL注入,提高系统安全性。
之前面试问过这个点,我按以上回答被打断了,它说区别就是#{}
会将参数加上引号。这也是一个点,虽然不是完全正确,待补充加上引号的条件。 -
实体类属性名称和表字段名不一致怎么办
一般都使用定义resultMap来处理属性名和字段名的映射。
还可以在sql中使用别名,不过用的比较少
《阿里巴巴开发手册》强制不直接使用 resultClass 进行映射返回,也即需要定义 resultMap -
模糊查询sql如何写
select * from table where filed like #{param}
,然后事先在入参中拼接好通配符(%、_)select * from table where filed like "%"#{param}"%"
,在SQL中使用"%"、"_",注意需要使用引号select * from table where filed like "%${param}%"
,注意和第二种拼写区别,存在SQL注入问题select * from table where filed like concat("%", #{param}, "%")
select * from table where filed like concat("%", "${param}", "%")
,注意需要使用引号
-
DAO 与 XML 配置文件映射原理?DAO 中的方法能重载吗?
- DAO 与 XML 是通过类全限定名匹配的,也即 xml 的 namespace 为对应类全限定名
- xml 中的每条 sql 的 id 对应 DAO 的方法,由于 id 即为方法名,因此 DAO 的方法不能重载
- 在Mybatis中,每一个标签,都会被解析为一个MapperStatement对象,Mapper 接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回
-
MyBatis 是如何进行分页的?MyBatis分页插件原理
- 本地提供了 RowBounds 进行分页(没使用过),利用 JDBC 驱动中的 ResultSet 结果集进行分页,不是完全的内存分页,也即不是全部加载入内存,然后 subList 截取一部分那种
- sql 中使用 limit 分页
- 分页插件分页,使用 MyBatis 提供的拦截器扩展 Interceptor,重写 sql,添加 limit 语句(根据dialect方言,添加对应的物理分页语句和物理分页参数)
-
如何批量插入
- 代码 foreach 插入,一般不使用,效率低
- 动态 sql, <foreach> 标签拼接插入,一般使用的都是这个
- executortype.batch 批量插入
- ?? 动态sql和batch插入哪个效率高?
-
插入后如何获取自动生成的主键值
<insert id="insertname" usegeneratedkeys="true" keyproperty="id"> insert into names (name) values (#{name}) </insert>
-
动态sql作用?执行原理?哪些动态sql
- 动态sql编写在xml中,根据入参不同生成不同的sql
- 执行原理是根据表达式的值 完成逻辑判断并动态拼接sql的功能。
- 9种动态sql标签 trim | where | set | foreach | if | choose | when | otherwise | bind
-
一对一查询
主要是association
标签
两种方式,一种是一次查询,通过sql关联表查询;还有一种是两次单表查询
不过两次查询这种有一定限制,毕竟是先单表查询的
??必须是两次单表查询?好像也不一定
<!-- 一对一根据id查询个人信息:级联查询的第一种方法(嵌套查询,执行两个SQL语句)-->
<resultMap type="com.po.Person" id="cardAndPerson1">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<!-- 一对一级联查询-->
<association property="card" column="idcard_id" javaType="com.po.Idcard"
select="com.dao.IdCardDao.selectCodeByld"/>
</resultMap>
<select id="selectPersonById1" parameterType="Integer" resultMap=
"cardAndPerson1">
select * from person where id=#{id}
</select>
<!--对一根据id查询个人信息:级联查询的第二种方法(嵌套结果,执行一个SQL语句)-->
<resultMap type="com.po.Person" id="cardAndPerson2">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<!-- 一对一级联查询-->
<association property="card" javaType="com.po.Idcard">
<id property="id" column="idcard_id"/>
<result property="code" column="code"/>
</association>
</resultMap>
-
一对多查询
主要就是collection
标签
要求两表查询出来的字段不一样不? -
MyBatis 延迟加载实现原理
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。 -
MyBatis 的一二级缓存
一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
二级缓存:与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
一级缓存为Session级别缓存,默认打开;二级缓存为Mapper级别缓存(跨Session),默认关闭
默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。 -
Spring 下 MyBatis 缓存失效
一级缓存失效,因为 MyBatis 的连接被交给 Spring 管理了,每次事务结束都 close 了 -
MyBatis 接口绑定
就是将接口方法与SQL进行映射,调用方法即执行对应SQL。
两种方法,一种注解,一种XML -
MyBatis 拦截器
Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。编写插件:实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
参考
- 2022 最新MyBatis 面试题 https://www.cnblogs.com/d102601560/p/15758723.html
- Mybatis面试题(2021最新版)https://cloud.tencent.com/developer/article/1814879
- MyBatis一对一关联查询(级联查询)http://c.biancheng.net/view/4368.html
- MyBatis一对多关联查询 http://c.biancheng.net/mybatis/one-to-many.html
- mybatis中批量插入的两种方式(高效插入) https://zhuanlan.zhihu.com/p/35305211
- 坑已踩好,MyBatis 几种批量插入性能比较 https://jishuin.proginn.com/p/763bfbd670ad
- Mybatis 批量插入 https://www.cnblogs.com/edda/p/14026230.html
- MyBatis原理分析之六:RowBounds分页原理 https://blog.csdn.net/cb_lcl/article/details/81867772
- Mybatis四种分页方式 https://www.w3cschool.cn/mybatis/mybatis-ypsj3bpi.html
- mybatis中四种模糊查询的方式 https://blog.csdn.net/Adobe_java/article/details/118460709