目录
1、简述MyISAM和InnoDB的区别
2、简述Hash和B+树索引的区别
3、简述MyBatis的实现逻辑
4、#{}和${}的区别
5、简述Mybatis的优缺点
6、当实体类中的属性名和表中的字段名不一样时怎么办?
7、resultType与resultMap的区别
8、如何执行批量插入
9、Mybatis延迟加载的实现原理是什么?
10、Mybatis动态SQL是干什么的?都有哪些动态SQl?简述动态SQL的执行原理
1、简述MyISAM和InnoDB的区别
MyISAM和InnoDB的区别
名称 MyISAM InnoDB
事务处理 不支持 支持 数据行锁定 不支持 支持 外键约束 不支持 支持 全文索引 支持 不支持 表空间大小 较小 较大,约两倍 MyISAM不支持事务处理、数据行锁定和外键约束,支持全文索引,表空间大小较小
InnoDB支持事务处理、数据行锁定和外键约束,不支持全文索引,表空间大小较大
2、简述Hash和B+树索引的区别
Hash索引和B+树索引的主要区别在于数据组织方式和使用场景。
Hash索引:
- 数据以哈希表的形式存储,通过哈希函数确定存储位置。
- 适合等值查询,速度快,但不支持范围查询和排序。
- 不支持模糊查询和多列索引的最左前缀匹配。
- 无法避免回表查询,查询性能不稳定,可能受到哈希碰撞的影响。
B+树索引:
- 数据以B+树的形式存储,保持有序。
- 支持范围查询和排序。
- 在某些条件下可以避免回表查询,提高查询效率。
- 查询性能相对稳定,每次查询都在根节点到叶子节点的路径上完成,查询效率与树的高度相关。
总而言之,Hash索引适合等值查询但不适合范围查询和排序,而B+树索引则适合范围查询和排序,且查询性能相对稳定。
3、简述MyBatis的实现逻辑
- 在 MyBatis 的初始化过程中,会生成一个 Configuration 全局配置对象,里面包含了所有初始化过程中生成的对象
- 根据 Configuration 创建一个 SqlSessionFactory 对象,用于创建 SqlSession “会话”
- 通过 SqlSession 可以获取到 Mapper 接口对应的动态代理对象,去执行数据库的相关操作
- 动态代理对象执行数据库的操作,由 SqlSession 执行相应的方法,在他的内部调用 Executor 执行器去执行数据库的相关操作
- 在 Executor 执行器中,会进行相应的处理,将数据库执行结果返回
4、#{}和${}的区别
两者在 MyBatis 中都可以作为 SQL 的参数占位符,在处理方式上不同
#{}:在解析 SQL 的时候会将其替换成 ? 占位符,然后通过JDBC的 PreparedStatement 对象添加参数值,这里会进行预编译处理,可以有效地防止 SQL 注入,提高系统的安全性
${}:在 MyBatis 中带有该占位符的 SQL 片段会被解析成动态 SQL 语句,根据入参直接替换掉这个值,然后执行数据库相关操作,存在 SQL注入 的安全性问题
5、简述Mybatis的优缺点
优点:
- 消除了JDBC大量冗余的代码,不需要手动开关连接;
- 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,降低了sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
- 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
- 能够与Spring很好的集成;
- 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点:
- SQL语句的编写工作量较大,尤其当字段多、关联表多时,要有足够的SQL编写能力。
- SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
6、当实体类中的属性名和表中的字段名不一样时怎么办?
- 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
- 通过映射字段名和实体类属性名的方式进行一一对应。
7、resultType与resultMap的区别
resultmap与resulttype的区别为:对象不同、描述不同、类型适用不同
对象不同
- resultmap:resultMap如果查询出来的列名和pojo的属性名不一致,通过定义resultMap从而对列名和pojo属性名之间作映射关系。
- resultType:resultType使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
描述不同
- resultmap:resultMap对于一对一表连接的处理方式通常为在主表的pojo中添加嵌套另一个表的pojo,然后在mapper.xml中采用association节点元素进行对另一个表的连接处理。
- resulTtype:resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结构集查询遍历的需要选择使用resultType还是resultMap。适用于单表查询。
类型适用不同
- resultmap:mybatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap。
- resulttype:resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。
8、如何执行批量插入
<!--批量插入-->
<insert id="insertUserBatch" parameterType="User">insert into SMBMS_USER (userCode,userName,userPassword,birthday,userRole)values/* 类型 别名 分隔符 */<foreach collection="list" item="user" separator=",">(#{user.userCode},#{user.userName},#{user.userPassword},#{user.birthday},#{user.userRole})</foreach>
</insert>
9、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,支持延迟加载的原理都是一样的。
10、Mybatis动态SQL是干什么的?都有哪些动态SQl?简述动态SQL的执行原理
作用:
动态sql是指在进行sql操作的时候,传入的参数对象或者参数值,根据匹配的条件,有可能需要动态的去判断是否为空,循环,拼接等情况;
内容:
动态Sql大致有以下几种:if、where、choose-when、set、forEach、trim等
执行原理:
- 首先在解析xml配置文件的时候,会有一个SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass) 的操作
- createSqlSource底层使用了XMLScriptBuilder来对xml中的标签进行解析
- XMLScriptBuilder调用了parseScriptNode()的方法,
- 在parseScriptNode()的方法中有一个parseDynamicTags()方法,会对nodeHandlers里的标签根据不同的handler来处理不同的标签
- 然后把DynamicContext结果放回SqlSource中
- DynamicSqlSource获取BoundSql
- 在Executor执行的时候,调用DynamicSqlSource的解析方法,并返回解析好的BoundSql,和已经排好序,需要替换的参数
简单的说:就是使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql