文章目录
- MyBatis的执行流程?
- Mybatis中的#{}和${}有什么区别?
- Mybatis是如何进行分页的?分页插件的原理?
- Mybatis的插件运行原理?怎样编写一个插件?
- 通常一个Xml映射文件都会有一个Mapper接口与之对应,这个接口的工作原理是什么?Mapper接口里的方法可以重载吗?
- Xml映射文件中,除了常见的select|insert|update|delete标签外,还有哪些标签?
- 动态sql的执行原理?
- Mybatis 批量添加用的什么标签?动态标签 foreach 有哪些属性?
- MyBatis 底层是如何将 resultSet 转换成对象的?
- Mybatis 的 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?不能重复的原因?
- MyBatis实现一对一、一对多有几种方式 ? collection 关联集合对象的延迟加载?
- 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
- 说一下MyBatis的SelectKey标签的使用?
- 说一下 SqlsessionfactoryBean 的作用?SqlSessionFactoryBean 和 和SqlSessionFactory 有什么区别?
- 了解 MyBatis 的缓存吗?简单说一下 ?
- 说一下 MyBatis 的 的 selectKey 标签的使用 ?
MyBatis的执行流程?
1.通过SqlSessionFactory创建SqlSessionFactory
在SqlSessionFactoryBuilder的build方法中使用XMLConfigBuilder用来解析
配置文件mybatis-config.xml 然后创建并返回一个DefaultSqlSessionFactory
2.通过SqlSessionFactory创建SqlSession,用于执行Sql语句
3.通过SqlSessionFactory创建SqlSession,用于执行Sql语句
4.通过MapperProxy调用Mapper中相应的方法。
5.提交或者回滚
6.关闭Session
Mybatis中的#{}和${}有什么区别?
#{}内部使用预编译PreparedStatement机制执行SQL,支持?占位符,可以防止SQL注入
{} 内部使用Statement机制将参数和SQL拼接在一起发送执行,不支持?占位符,参数只能拼接。
只有能用的占位符的地方,都建议使用#{}
如果是表名或字段名或者like 建议使用${}
Mybatis是如何进行分页的?分页插件的原理?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集进行的分页,非物理分页,假分页。
可以在sql内直接书写带物理分页的参数来完成物理分页,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件。
在插件的拦截方法内拦截待执行的Sql,然后重新Sql,添加分页语句。
Mybatis的插件运行原理?怎样编写一个插件?
Mybatis仅可以针对ParameterHandler、ResultSetHandler、StatementHandler、Excecutor这四种接口的插件
Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能。
每当执行这四种接口对象方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法
当然,它只会拦截你那些指定需要拦截的方法。
实现Mybatis的Interceptor接口并复写intercept方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,做完之后需要在配置文件中配置编写的插件
通常一个Xml映射文件都会有一个Mapper接口与之对应,这个接口的工作原理是什么?Mapper接口里的方法可以重载吗?
1.Mapper接口的全限定名,是映射文件中的namespace的值。
2.接口中的方法,就是映射文件中MappedStatement的id值。
3.接口方法内的参数,就是传递给sql的参数。
4.Mapper接口是每页实现类的,当调用接口方法时,接口的全限定名+方法名拼接
字符串作为key值,可唯一定位一个MapperStatement。
Mapper接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao
接口生成代理Proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement
所代表的Sql,然后将sql执行结果返回。
Mapper接口里的方法,是不能重置的,因为是全限定名+方法名的保存和寻找策略。
Xml映射文件中,除了常见的select|insert|update|delete标签外,还有哪些标签?
1.还有很多其它的标签
resultMap、parameterMap、sql、include、SelectKey
2.另外,还有动态标签
trim、here、set、foreach、if、choose、when、otherwise、bind等
动态sql的执行原理?
Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能
其执行原理是使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,最后来完成动态 sql 的功能
Mybatis 批量添加用的什么标签?动态标签 foreach 有哪些属性?
foreach标签
foreach标签的属性有
- collection:指定输入对象中集合属性
- index:这个属性用来指定用来访问迭代集合下标的名称。如:index=“myIndex”,则#{myIndex}用来访问当前迭代的下标。
- item:每次遍历生成的对象
- open:开始遍历时拼接的串
- close:结束遍历时两个对象需要拼接的串
- separator:用来分割 foreach 元素迭代的每个元素;
MyBatis 底层是如何将 resultSet 转换成对象的?
通过反射动态获得实体类的对象
通过反射给对象中的属性赋值
当实体类与表中字段不一致如何映射?
ResultMap标签、别名、开启下划线转驼峰
Mybatis 的 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?不能重复的原因?
不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复
由于 namespace 不是必须的,如果没有配置 namespace,那么 id 不能重复
namespace + id 是作为 Map<String, MappedStatement>的 key 使用的,如果没有 namespace,只剩下 id,这时 id 重复会导致数据互相覆盖。
MyBatis实现一对一、一对多有几种方式 ? collection 关联集合对象的延迟加载?
一对一
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置
association节点配置一对一的类就可以完成;
嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通
过association配置,但另外一个表的查询通过select属性配置。
一对多
有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的
collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的 结果的外
键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点
配置。
在 Mybatis 配置文件中,可以配置是否启用延迟加载<setting name=”lazyLoadingEnabled” value=true 或 false>
StudentMapper dao = Session.getMapper();
Student stu = Dao.selectById(id);
System.out.println(stu);
它的原理是使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,发送事先保存好的查询关联对象的 sql,把关联对象查询出来,然后进行赋值;
为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以称之为半自动 ORM 映射工具。
全自动 Hibernate :执行效率低 省事 不灵活 add(stu)
半自动:效率高 灵活
说一下MyBatis的SelectKey标签的使用?
SelectKey这个标签主要解决 "添加数据"时 不支持主键自动生成的问题,它可以很随意的设置生成主键的方式
SelectKey需要注意order属性
MySql这类支持自动增长的数据库中,order需要设置为after才会取到正确的值
Oracle这样取序列的情况 order需要设置为before,否则会报错
说一下 SqlsessionfactoryBean 的作用?SqlSessionFactoryBean 和 和SqlSessionFactory 有什么区别?
在 Spring 整合 MyBatis 的时,我们需要配值 SqlSessionFactoryBean 来充当 SqlSessionFactory;
SqlSessionFactoryBean 实现了 Spring 的 FactoryBean接口,实现在和接口的时候,泛型处就是写的
SqlSessionFactory,
所以说实际使用 SqlSessionFactoryBean 时候,实际上在 spring ioc 容器中的 Bean 是 SqlSessionFactory
当把这个 bean 注入到 Spring 中去了以后,IOC 容器中的其他类型就可以拿到 SqlSession 实例了,进而就可执行 SQL 任务了。
附:SqlSessionFactoryBean 的定义
public class SqlSessionFactoryBean implements
FactoryBean<SqlSessionFactory>,InitializingBean,ApplicationListener<ApplicationEvent> {
}
了解 MyBatis 的缓存吗?简单说一下 ?
MyBatis 提供了一级缓存和二级缓存的支持;
一级缓存:
- 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 SqlSession,当 SqlSession flush 或 close 之后,该 Session
中的所有 Cache 就将清空; - 另外不同的 SqlSession 之间的缓存数据是互相不影响的;
二级缓存: - 耳机缓存开启方式是在 Mapper 的配置文件配置;
- 与一级缓存其机制相同,不同在于其存储作用域为 Mapper,并且可自定义存储源,如 Ehcache;
- 二级缓存是跨 SqlSession 的,多个 SqlSession 可以共用二级缓存;
- 进行了“添加、更新和删除”操作后,会刷新对应的缓存的数据。
MyBatis 查询顺序:二级缓存→一级缓存→数据库
MyBatis 主要提供了以下几个刷新和置换策略: - LRU:(Least Recently Used),最近最少使用算法,即如果缓存中容量已经满了,会将缓存中最近做少被使用的缓存记录清除
掉,然后添加新的记录; - FIFO:(First in first out),先进先出算法,如果缓存中的容量已经满了,那么会将最先进入缓存中的数据清除掉;
- Scheduled:指定时间间隔清空算法,该算法会以指定的某一个时间间隔将 Cache 缓存中的数据清空;
- SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象;
- WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象。
说一下 MyBatis 的 的 selectKey 标签的使用 ?
selectKey 这个标签主要用于解决“添加数据”时不支持主键自动生成的问题,他可以很随意的设置生成主键的方式;
selectKey 需要注意 order 属性
MySql 这类支持自动增长类型的数据库中,order 需要设置为 after 才会