Mybatis精选18问

1、#{}和${}的区别是什么?

a、#{}是预编译处理,${}是字符串替换。

b、Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
c、Mybatis 在处理${}时,就是把${}替换成变量的值。
d、使用#{}可以有效的防止 SQL 注入,提高系统安全性

2、xml映射文件中,除了insert|select|update|delete标签之外,还有哪些标签

<resultMap>、<parameterMap>、<sql>、<include>、<selectKey>,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中<sql>为sql片段标签,通过<include>标签引入sql片段,<selectKey>为不支持自增的主键生成策略标签。

3、通常一个映射文件,都会写一个dao接口与之对应,请问这个dao接口的工作原理是什么?dao接口里的方法,参数不同时,方法能重载吗?

dao接口的全路径名就是映射文件namespace,方法名就是映射文件的MappedStatement的id,方法的参数,就是传递给sql的参数。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。

参考博客: 面试题:mybatis 中的 DAO 接口和 XML 文件里的 SQL 是如何建立关系的?_程序员囧辉-CSDN博客

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

4、mybatis是如何进行分页的?分页插件的原理是什么?

mybatis插件是通过jdk动态代理来实现的。

加入一个对象被代理多次,配置在前面的拦截器最后被执行。

pagehelper-spring-boot-autoconfigure 

5、简述mybatis插件的运行原理,以及如何编写一个插件?

mybatis四大核心对象:

(1)ParameterHandler:处理SQL的参数对象
(2)ResultSetHandler:处理SQL的返回结果集
(3)StatementHandler:数据库的处理对象,用于执行SQL语句
(4)Executor:MyBatis的执行器,用于执行增删改查操作

Executor是真正用来执行sql的语句的对象,调用sqlsession的方法,最终实际上是通过Executor来完成。

配置文件setting标签defaultExecutorType属性。默认simple。

ReuseExecutor相比较于SimpleExecutor做了一点优化,那就是将Statement对象进行了缓存处理,不会每次都创建Statement对象,这样做的话减少了SQL预编译和创建对象的开销。

BatchExecutor从名字上也可以看出来,这是一个支持批量操作的执行器。

三种常用批量插入方法:

       1、直接代码循环

        2、xml中批量标签foreach

        3、 BatchExecutor插入  

https://blog.csdn.net/zwx900102/category_8934270.html

mybats拦截器插件就是针对的这4个对象!

一针见血MyBatis插件机制 - MyBatis中文官网

mybatis-have-plugins.png

自定义mybatis插件,必须实现interceptor接口 

6、mybatis执行批量插入时,能返回数据库主键列表吗?

7、mybatis动态sql是做什么的?都有哪些动态sql简述一下动态sql的执行原理

8、mybatis如何将sql执行结果封装为目标对象并返回,都有哪些映射形式?

9、mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别

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

11、mybatis的xml映射文件中,不同的xml映射文件,id是否可以重复?

不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;

原因就是namespace+id是作为Map<String, MapperStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

但是,在以前的Mybatis版本的namespace是可选的,不过新版本的namespace已经是必须的了。

12、mybatis中如何执行批处理?

设置sqlsession为批量操作类型

sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
    try {
     namemapper mapper = sqlsession.getmapper(namemapper.class);
     for (string name : names) {
         mapper.insertname(name);
     }
     sqlsession.commit();
    }catch(Exception e){
     e.printStackTrace();
     sqlSession.rollback(); 
     throw e; 
    }
     finally {
         sqlsession.close();
    }

全局配置文件

<configuration>
    <!--  ...  -->
    <settings>
        <setting name="defaultExecutorType" value="BATCH"/>
    </settings>
    <!-- ... -->
</configuration>

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

1、SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。

 

2、ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。

 

3、BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

 

作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。

每次调用会使用一个新的sqlsession

14、mybatis中如何指定使用哪一种Executor执行器?

15、Mybatis是否可以映射枚举类?

16、mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是必须在前面?

17、简述mybatis的xml映射文件和mybatis内部数据结构之间的映射关系?

18、为什么说mybatis是半自动化的ORM映射工具?它与全自动的区别在哪里?

1、缓存

1、一级缓存:

也叫本地缓存,在会话(sqlsession)层面进行的缓存。默认开启

DefaultSqlSession只有两个属性:Configuration(全局的)和Executor(存放缓存)。

在同一会话里面,多次执行相同的sql,会直接从内存取到缓存的结果,不再发送sql到数据库。

生命周期

开启一个数据库会话时,会创建一个sqlsession对象,SqlSession对象中会有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache对象。当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用。

如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用。

SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用。

工作流程

 不足:

多个会话和分布式环境下,可能有不一样的缓存,存在脏数据。

关闭:

一级缓存无法关闭,但是有俩个级别可以选择。可以设置成statement级别,这样每次查询结束都会清掉一级缓存。

 2、二级缓存

范围是namespace级别,可以被多个sqlsession共享。

Mybatis查询数据的顺序是:二级缓存 -> 一级缓存 -> 数据库。

作为一个范围更广的缓存,在sqlsession的外面,否则不能被多个sqlsession共享。而一级缓存在sqlsession内部。

并且,工作在一级缓存之前,只有取不到二级缓存的情况下才到一个会话中取一级缓存。

那么,二级缓存放在哪个对象维护呢?要跨会话共享的话,sqlsession和BaseExecutor一级满足不了要求。实际上,Mybatis用一个装饰器的类,就是CacheExecutor。对于查询请求,会判断二级缓存是否有缓存结果,如果没有,才会委派给真正的查询器Executor实现类,比如SimpleExecutor。    --装饰器模式

开启二级缓存的方法

1、<setting cacheEnable value="true" /> 

默认开启的,只要没有显示设置false,都会用CacheExecutor装饰基本的执行器

2、在mapper.xml中配置 <cache />标签

启动的时候会创建这个mapper的cache对象,存放在MappedStatement这个对象里(id是mapper接口的全路径.方法名)

增删改标签,默认有flushCache标签=true,会在增删改操作时清空缓存(只清空当前namespace的缓存)。

查询标签,默认有useCache标签=true。

事务提交后,才会添加到二级缓存!!

3、可以使用useCache=“false”属性在单个statementID上关闭二级缓存 

注意

1、适合查询为主的应用中使用

2、多个namespace中有针对同一张表的使用,在一个namespace中刷新了缓存,另一个namespace没有刷新,就会出现读到脏数据。所以,推荐在一个mapper操作单表。

3、<cache-ref>可以解决跨namespace的缓存共享问题。代表引用别的namespace的Cache配置,两个namespace的操作使用的是同一个Cache。

参考博客:  Mybatis#{}和${}的区别是什么?,Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?_yuanaili的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Mybatis是一个流行的Java持久层框架,它提供了许多优点和核心组件。在面试中,以下是一些可能会被到的题和答案: 1. Mybatis的优点有哪些? Mybatis有以下几个优点: - Mybatis提供了灵活且强大的映射机制,可以通过XML或注解来配置和映射原生信息,将POJO映射成数据库的记录。这样可以避免编写大量的JDBC代码,并且不需要手动设置参数和获取结果集。 - Mybatis支持动态SQL,可以根据不同的条件动态生成SQL语句,提供了更好的灵活性和可扩展性。 - Mybatis具有良好的性能和可维护性,可以通过缓存机制来提升查询性能。 - Mybatis与现有的数据库交互技术无缝集成,可以很方便地与Spring等框架集成。 2. Mybatis如何处理#{}? 在处理#{}时,Mybatis会将其转换为?,然后使用PreparedStatement的set方法来设置参数的值。 3. 在使用Mybatis的<if>标签时,为什么需要@Param注解? 当只有一个参数并且在<if>标签里使用时,Mybatis需要通过@Param注解来指定参数的名称,以便正确地组装SQL语句。 4. Mybatis的核心组件有哪些? Mybatis的核心组件包括: - SqlSessionFactory:用于创建SqlSession对象的工厂。 - SqlSession:用于执行数据库操作的核心接口。 - Mapper接口:用于定义数据访接口,通过调用Mapper接口的方法来执行SQL语句。 - Configuration:用于配置并管理Mybatis的各种设置和属性。 以上是一些关于Mybatis的面试常见题和答案,希望对你有帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值