1. MyBatis是什么?
MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几
乎所有的 JDBC 代码和手动设置参数以及 获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的
POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
ORM是什么
ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数 据与简单Java对象(POJO)的映射关系的技术。简
单的说,ORM是通过使用描述对象和 数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。
为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时, 可以根据对象关系模型直接获取,所以它是全自
动的。
而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半 自动ORM映射工具。
Mybatis优缺点
MyBatis是一款优秀的ORM框架,它的主要优点和缺点如下:
优点:
- 灵活性高:MyBatis支持自定义SQL语句、存储过程和高级映射,可以根据业务需求自由编写SQL语句。
- 简单易用:MyBatis的API设计简单明了,易于上手和使用。
- 轻量级:MyBatis的代码量较少,启动速度快,适合于小型项目和快速开发。
- 支持多种数据库:MyBatis支持主流的关系型数据库,如MySQL、Oracle、SQL Server等。
- 易于集成:MyBatis可以与Spring框架无缝集成,方便进行依赖注入和AOP编程。
缺点:
- 对SQL的直接操作:MyBatis需要对SQL语句进行解析和执行,这会增加一定的性能开销。
- 学习成本较高:MyBatis的API设计较为复杂,需要一定的学习成本才能熟练掌握。
- 不支持缓存:MyBatis不支持缓存机制,对于大量数据的访问可能会影响性能。
- 不支持复杂查询:MyBatis对于复杂查询的支持有限,需要手动编写复杂的SQL语句。
- 不适合大型项目:MyBatis适合于中小型项目,对于大型项目来说,可能需要使用其他ORM框架来提高性能和可维护性。
MyBatis的解析和运行原理
MyBatis是一款优秀的ORM框架,它的解析和运行原理如下:
- 解析过程
MyBatis的解析过程主要分为三个步骤:
(1)XML配置文件解析:MyBatis使用XML配置文件来定义SQL语句、映射关系等信息。当应用程序启动时,MyBatis会读取XML配置文件并将其转换为Java对象。
(2)SQL语句解析:MyBatis将XML配置文件中的SQL语句解析成Java代码,并生成对应的SqlSessionFactory对象。
(3)SqlSessionFactory对象创建:MyBatis通过SqlSessionFactory对象来创建SqlSession对象,SqlSession对象是MyBatis的核心组件,它负责执行SQL语句并将结果映射到Java对象中。
- 运行过程
MyBatis的运行过程主要分为两个阶段:
(1)预处理阶段:在执行SQL语句之前,MyBatis会对SQL语句进行预处理,包括参数绑定、缓存查询结果等操作。
(2)执行阶段:在执行SQL语句之后,MyBatis会将SQL语句的结果映射到Java对象中,并返回给应用程序。
总之,MyBatis的解析和运行原理非常复杂,需要深入了解MyBatis的内部机制才能更好地理解它的工作方式。
为什么需要预编译
SQL 预编译指的是数据库驱动在发送 SQL 语句和参数给 DBMS 之前对 SQL 语句进行编 译,这样 DBMS 执行 SQL 时,就不需要重新编译。
Mybatis都有哪些Executor执行器?它们之间的区别是什么?
Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、 BatchExecutor。
ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使 用,不存在就创建,用完后,不关闭Statement对
象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添 加到批处理中(addBatch()),等待统一执行
(executeBatch()),它缓存了多个 Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行 executeBatch()批处理。
与JDBC批处理相同。
作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。 Mybatis中如何指定使用哪一种Executor执行器?
在Mybatis配置文件中,在设置(settings)可以指定默认的ExecutorType执行器类型,也 可以手动给DefaultSqlSessionFactory的创建
SqlSession的方法传递ExecutorType类型参 数,如SqlSession openSession(ExecutorType execType) 。
配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句 (prepared statements); BATCH 执行器将重用语句
并执行批量更新。
Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
MyBatis支持延迟加载,它的实现原理是通过使用一级缓存和二级缓存来实现的。
一级缓存是MyBatis默认开启的缓存机制,它会将查询结果缓存到内存中,当再次执行相同的查询语句时,MyBatis会直接从缓存中获取结果,而不需要再次查询数据库。一级缓存的有效期默认为15秒,可以通过配置文件中的cache-enabled属性进行修改。
二级缓存是MyBatis提供的一种高级缓存机制,它可以将查询结果缓存到磁盘中,以提高查询性能。二级缓存的有效期默认为30分钟,可以通过配置文件中的cache-enabled属性进行修改。在二级缓存中,MyBatis会为每个Mapper接口创建一个缓存实例,并将查询结果存储在该实例中。当再次执行相同的查询语句时,MyBatis会先检查二级缓存中是否存在该查询结果,如果存在,则直接从缓存中获取结果;否则,MyBatis会执行查询操作,并将查询结果存储到二级缓存中,以便下次使用。
需要注意的是,延迟加载只对查询结果进行缓存,对于实体类对象等其他数据类型不进行缓存。此外,延迟加载也不是所有情况下都适用,需要根据具体的业务场景和性能需求进行选择和优化。
#{}和${}都是MyBatis中的占位符,用于在SQL语句中插入变量。它们的区别如下:
- #{}是普通占位符,它会将变量的值替换为占位符本身,然后再执行SQL语句。例如:
sql复制代码
<select id="getUserById" resultMap="userMap">
SELECT #{userId} FROM user WHERE id = #{id}
</select>
在上面的代码中,#{userId}会被替换为查询参数userId的值,然后再执行SELECT语句。
- ${}是动态占位符,它会将变量的值替换为占位符本身,并在执行SQL语句时动态生成SQL语句。例如:
sql复制代码
<select id="getUserById" resultMap="userMap">
SELECT #{userId} FROM user WHERE id = #{id}
</select>
在上面的代码中,#{userId}会被替换为查询参数userId的值,并在执行SELECT语句时动态生成SQL语句。这种方式可以避免SQL注入攻击,但需要手动编写SQL语句。