61道MyBatis高频题整理(附答案背诵版)
1、介绍下MyBatis?
MyBatis是一个基于Java的持久层框架,它封装了底层的JDBC操作,大大简化了数据库操作的复杂性。MyBatis的主要特点包括:
-
SQL语句与Java代码的分离:MyBatis允许你直接在XML文件中编写SQL语句,这样可以将SQL语句从Java代码中分离出来,使得代码更加清晰,易于维护。
-
强大的映射能力:MyBatis可以将数据库中的记录映射为Java对象,这样可以方便地处理数据库的数据。映射的方式主要有两种:一种是通过XML文件进行配置,另一种是通过注解来实现。
-
支持动态SQL:MyBatis支持动态SQL,这意味着你可以根据不同的条件动态生成SQL语句。这对于处理复杂的查询需求非常有用。
-
支持一级缓存和二级缓存:MyBatis内置了一级缓存和二级缓存,可以提高查询的效率。一级缓存默认开启,它是基于SqlSession的,当SqlSession关闭或提交时,一级缓存就会清空。二级缓存是基于Mapper的,多个SqlSession可以共享该缓存。
-
提供了丰富的API:MyBatis提供了丰富的API,包括SqlSession、SqlSessionFactory、Mapper等,这些API提供了许多方便的方法,使得数据库操作变得简单易用。
总的来说,MyBatis是一个功能强大的持久层框架,它的出现大大简化了Java对数据库的操作,提高了开发效率。
2、MyBatis 框架的应用场景?
MyBatis作为一款优秀的持久层框架,主要应用在以下的场景中:
-
需要与关系型数据库交互的项目:MyBatis支持对各类SQL查询,更新,删除的操作,包括复杂查询,联合查询等,因此对于需要与关系型数据库交互的项目,MyBatis是一个很好的选择。
-
需要编写复杂SQL语句的场景:MyBatis允许开发者直接编写原生态SQL语句,相比于其他ORM框架,如Hibernate,更适合需要编写复杂SQL语句的场景。
-
需要进行SQL性能优化的场景:在MyBatis中,SQL语句是可见的,开发者可以直接对SQL语句进行优化,因此,对于需要进行SQL性能优化的场景,MyBatis也是一个不错的选择。
-
需要缓存优化的场景:MyBatis提供了一级缓存和二级缓存的功能,可以有效地提升数据库查询的效率。例如,在一个电商网站中,商品的信息一般变动较小,但查询非常频繁,这时候,就可以使用MyBatis的二级缓存功能,将商品的信息缓存起来,提高系统的性能。
-
动态SQL的场景:MyBatis支持动态SQL,可以根据不同的条件动态生成SQL语句,这对于处理复杂的查询需求非常有用。例如,用户的查询条件可能有多种,有的用户可能只提供用户名,有的可能只提供用户ID,有的可能两者都提供,这时我们就可以使用MyBatis的动态SQL来实现这个需求。
综上所述,MyBatis适用于各种复杂度的Java项目,特别是对SQL性能,缓存优化,动态SQL有一定需求的项目。
3、MyBatis 有哪些优点?
MyBatis作为一款优秀的持久层框架,具有以下几个主要优点:
-
深度解耦SQL和Java代码:MyBatis允许将SQL语句写在XML文件中,大大降低了代码的耦合度。SQL语句和Java代码分离,使得代码更加清晰,易于维护。
-
支持定制化SQL和存储过程:MyBatis允许开发者编写几乎任何的SQL语句,包括存储过程。这给开发者提供了极大的灵活性,特别是在处理复杂的数据库操作时。
-
提供映射标签,支持对象与数据库的ORM字段关系映射:MyBatis通过XML或注解将Java对象和数据库中的记录进行映射,简化了数据库操作。
-
提供SQL标签,支持编写动态SQL:MyBatis提供了丰富的SQL标签,可以编写动态SQL,根据不同的条件生成不同的SQL语句。
-
提供一级、二级缓存,提高查询效率:MyBatis内置了一级和二级缓存,可以有效地提高查询的效率。一级缓存是SqlSession级别的,用于减少同一会话多次查询的数据库访问。二级缓存是mapper级别的,可以被多个SqlSession共享,用于减少跨会话的数据库访问。
-
允许延迟加载,提高系统性能:MyBatis支持延迟加载,只有当关联对象被真正使用时才进行查询,可以有效地提高系统的性能和响应速度。
-
支持插件,扩展性强:MyBatis提供了插件接口,开发者可以通过编写插件来扩展MyBatis的功能。
-
代码量少,学习曲线平缓:相比于其他ORM框架,MyBatis的代码量更少,学习曲线更平缓,更容易上手。
总的来说,MyBatis的优点主要体现在其灵活性、效率和易用性上。
4、MyBatis 有哪些缺点?
虽然MyBatis是一个非常受欢迎的持久层框架,但它也存在一些缺点:
-
没有完全实现ORM:与Hibernate这样的全功能ORM框架相比,MyBatis并没有完全实现对象关系映射。开发者需要手写SQL,这可能会增加一些开发工作量。
-
缓存管理:虽然MyBatis提供了一级和二级缓存,但是对于复杂的缓存场景,比如缓存失效、缓存更新等,管理起来可能会有些复杂。
-
对于大型项目,XML配置可能变得冗长:随着项目的增长,MyBatis的XML配置文件可能会变得非常冗长,这可能会导致管理和维护的困难。
-
可能存在SQL注入风险:如果不小心编写或配置SQL语句,可能会导致SQL注入的风险。尽管MyBatis提供了防止SQL注入的机制,但开发者仍然需要时刻保持警惕。
-
学习成本:对于新手来说,需要学习MyBatis的配置、SQL映射以及其他特性,这可能会增加一定的学习成本。
-
和某些框架整合时可能需要额外的配置:尽管MyBatis本身配置简单,但在与Spring、Shiro等框架整合时,可能需要额外的配置工作。
-
过多依赖XML:对于一些开发者来说,过多的依赖XML可能不是他们喜欢的方式,他们可能更偏向于使用基于注解的配置。
-
不如其他ORM框架在数据持久化上自动化:例如,与Hibernate比较,MyBatis在实体的增删改查操作上没有那么自动化,可能需要编写更多的代码。
尽管MyBatis存在以上所述的缺点,但由于其灵活性和高效性,它仍然是Java持久层框架中的一个重要选手。在选择使用MyBatis之前,开发者应该根据项目需求和个人喜好进行权衡。
5、MyBatis 用到了哪些设计模式?
MyBatis在其设计和实现过程中使用了多种设计模式,以下是其中的一些:
-
工厂模式:在MyBatis中,SqlSessionFactory负责创建SqlSession,这是典型的工厂模式。工厂模式提供了一个创建对象的接口,但允许子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
-
单例模式:SqlSessionFactoryBuilder在构建SqlSessionFactory的时候,使用了单例模式。SqlSessionFactory一旦被创建,应在应用执行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。使用SqlSessionFactory的最佳实践是在应用运行期间不要重复创建多次,多次创建SqlSessionFactory被视为一种代码“坏习惯”。因此,最佳范围是应用范围。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
-
建造者模式:SqlSessionFactoryBuilder使用了建造者模式。建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。在MyBatis中,使用SqlSessionFactoryBuilder可以通过XML配置文件或者一个Java Configuration类构建出SqlSessionFactory。
-
代理模式:MyBatis对Mapper接口实现了Java动态代理,用户可以直接通过接口和接口方法调用数据库操作,而无需手动编写DAO实现。代理模式为其他对象提供一种代理以控制对这个对象的访问。
-
模板方法模式:MyBatis的Executor执行器,是基于模板方法模式设计的。模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
-
装饰器模式:在MyBatis的缓存设计中,为了增加缓存的各种行为,比如定时清空、LRU淘汰等,采用了装饰器模式。装饰器模式可以动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式相比生成子类更为灵活。
-
策略模式:在MyBatis处理类型转换时,采用了策略模式。策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,策略模式让算法的变化独立于使用算法的客户。
以上就是MyBatis中用到的一些设计模式,通过这些设计模式的使用,MyBatis的代码结构更加清晰,扩展性和可维护性也更强。
6、MyBatis常用注解有哪些?
MyBatis框架提供了一系列注解,用于简化XML映射文件的使用。以下是一些常用的MyBatis注解:
-
@Select:这个注解用于指定用来从数据库中查询数据的SQL语句。
@Select("SELECT * FROM users WHERE id = #{id}") User selectUser(int id); ```
-
@Insert:这个注解指定了用来向数据库插入数据的SQL语句。
@Insert("INSERT INTO users(name, age) VALUES(#{name}, #{age})") void insertUser(User user); ```
-
@Update:这个注解指定了用来修改数据库中数据的SQL语句。
@Update("UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id}") void updateUser(User user); ```
-
@Delete:这个注解指定了用来从数据库中删除数据的SQL语句。
@Delete("DELETE FROM users WHERE id = #{id}") void deleteUser(int id); ```
-
@Results 和 @Result:这两个注解用于映射数据库表中的列到对象的属性。
@Results({ @Result(property = "id", column = "id"), @Result(property = "name", column = "name"), @Result(property = "age", column = "age") }) @Select("SELECT * FROM users") List<User> selectAllUsers(); ```
-
@Param:这个注解用于给方法参数命名,参数名就能直接在SQL语句中使用。
@Select("SELECT * FROM users WHERE name = #{name}") User selectUserByName(@Param("name") String name); ```
-
@Mapper:这个注解用于标记接口为一个MyBatis的mapper接口,MyBatis会自动扫描标记了@Mapper的接口并生成实现。
@Mapper public interface UserMapper { // ... } ```
-
@Options:这个注解用于设置一些MyBatis的特性,比如是否使用缓存,是否自动获取生成的数据库键等。
-
@ResultMap:这个注解引用定义在Mapper XML文件中的一个ResultMap。
-
@SelectProvider, @InsertProvider, @UpdateProvider, @DeleteProvider:这些注解用来动态构建SQL语句。
这些注解提供了一种更简洁的方法来写SQL语句,无需在XML文件中书写大量的映射代码。但请注意,注解的方式可能不适合处理复杂的SQL语句和动态SQL语句。对于这些情况,你可能需要使用XML映射文件。
7、MyBatis 有哪些核心组件?
MyBatis 的主要核心组件包括以下几个部分:
-
SqlSessionFactoryBuilder: 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。
-
SqlSessionFactory: SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
-
SqlSession: 每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态字段或实例字段中。
-
Mapper: Mapper 是创建出来用来绑定映射语句的接口。Mapper 的方法对应 SQL 映射文件中的一个 SQL 语句,这些接口在动态代理实现中,开发者无需手动实现,只需定义方法和相应 SQL 语句即可。
-
Executor: Executor 是 MyBatis 的执行层,负责 SQL 语句的生成和查询缓存的维护。它主要负责两部分内容,一部分是根据 statement id 找到相应的映射语句,将输入的参数转换为 SQL 语句;另一部分是将 SQL 语句交给 JDBC 执行,并将查询结果映射成 Java 对象返回。
这些是 MyBatis 的核心组件,通过这些组件的协同工作,MyBatis 可以高效、灵活的完成持久层的操作。
8、MyBatis编程步骤是什么样的?
使用MyBatis进行数据库操作的基本步骤如下:
-
添加MyBatis的依赖: 在项目的pom.xml文件中,添加MyBatis的依赖。
-
创建数据库表: 根据业务需求,创建相应的数据库表。
-
创建实体类: 根据数据库表,创建相应的Java实体类,字段要与数据库表的字段对应。
-
创建映射文件: 编写MyBatis的映射文件,文件中定义SQL语句和结果映射规则。通常,一个映射文件对应一个实体类,文件中的一个SQL语句对应实体类的一个操作。
-
配置MyBatis: 创建MyBatis的核心配置文件,配置文件中主要包含数据库连接信息,事务管理器类型,以及映射文件的路径。
-
编写Dao接口: 编写Dao接口,接口中的方法与映射文件中的SQL语句一一对应。
-
创建SqlSessionFactory: 在程序中创建SqlSessionFactory对象,这个对象是MyBatis的核心对象,它代表和数据库的会话,可以通过它获取SqlSession对象。
-
执行操作: 通过SqlSessionFactory获取SqlSession对象,然后调用SqlSession的方法,传入Dao接口的全限定名和方法参数,从而完成数据库的增删改查操作。
-
释放资源: 操作完成后,关闭SqlSession,释放资源。
以上就是使用MyBatis进行数据库操作的基本步骤,这个过程涵盖了MyBatis的主要功能,使得数据库操作更加简单、高效。
9、MyBatis 和JDBC有什么区别?
MyBatis 和 JDBC 是 Java 中操作数据库的主要方式,它们各有自己的特点和优势:
-
编程复杂度: JDBC 是 Java 的标准数据库连接工具,它提供了一套完整的数据库操作接口。使用 JDBC 可以完成所有的数据库操作,但是编程复杂度高,需要手动编写大量的 SQL 语句以及手动处理结果集。
MyBatis 是一个持久层框架,它建立在 JDBC 之上,简化了 JDBC 的操作。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs (Plain Old Java Objects, 普通的 Java 对象) 映射成数据库中的记录。
-
SQL 语句的编写和控制: 使用 JDBC,开发人员需要手动编写 SQL 语句,并且对 SQL 语句的控制度较高,可以灵活地进行各种复杂的数据库操作。但是,这同时也导致了开发的复杂度。
使用 MyBatis,SQL 语句主要在 XML 配置文件中编写,开发人员可以更清晰地看到 SQL 语句的结构,并且 MyBatis 支持动态 SQL,可以在运行时动态生成 SQL 语句。
-
数据库结果集的处理: 在 JDBC 中,开发人员需要手动对数据库结果集进行处理,将结果集转换为 Java 对象。这个过程需要编写大量的代码,并且容易出错。
在 MyBatis 中,开发人员可以通过 XML 配置或注解方式,声明结果集与 Java 对象的映射关系,MyBatis 会自动将数据库结果集转换为 Java 对象。
所以,MyBatis 与 JDBC 相比,主要优势在于简化了 JDBC 的操作,使得 SQL 语句更加清晰,减少了开发人员手动处理结果集的工作,大大提高了开发效率。
10、MyBatis 中的缓存机制有啥用?
MyBatis 提供了一级缓存和二级缓存两种缓存机制,主要用于提高查询性能,减少数据库的访问次数。
-
一级缓存(Session Cache): 一级缓存是 SqlSession 级别的缓存,当我们执行查询时,会先从缓存中获取数据,如果没有,就从数据库查询数据,并将查询出的数据放入缓存中。一级缓存会在 SqlSession 关闭或提交时清空。
一级缓存的主要目的是为了防止一个 SqlSession 内部多次查询相同数据,导致多次向数据库发出查询请求。通过使用一级缓存,可以在 SqlSession 生命周期内提高查询效率。
-
二级缓存(Mapper Cache): 二级缓存是 Mapper 级别的缓存,多个 SqlSession 可以共享二级缓存中的数据,即使 SqlSession 关闭,二级缓存中的数据也不会被清空,只有在同一个 SqlSessionFactory 中的 SqlSession 才能共享同一个二级缓存。
二级缓存的主要目的是为了防止多个 SqlSession 查询相同的数据,导致多次向数据库发出查询请求。通过使用二级缓存,可以跨 SqlSession 提高查询效率。
需要注意的是,尽管缓存可以提高查询的性能,但是如果数据的一致性要求很高,或者数据的更新频率很快,使用缓存可能会导致数据的不一致,因此在使用缓存时需要考虑其适用场景。
11、MyBatis 一级缓存和二级缓存的区别?
MyBatis 的一级缓存和二级缓存主要有以下几个区别:
-
缓存级别: 一级缓存是基于 SQL Session 的,即一级缓存的生命周期与 SQL Session 相同,只作用在这个 SQL Session 中。当 SQL Session 结束的时候,一级缓存也就结束了。而二级缓存是基于 SQL Session Factory 的,它可以跨 SQL Session,只要在同一个 SQL Session Factory 中,就能够共享二级缓存。
-
缓存的数据: 一级缓存默认情况下会开启,MyBatis 在执行查询操作时,会先从一级缓存中查询数据,如果没有找到数据,才会执行 SQL 查询数据库,并将查询到的结果存入一级缓存中。二级缓存需要在 MyBatis 的配置文件中进行配置,只有在进行配置后,二级缓存才会开启。
-
数据共享: 一级缓存不能实现多个 SQL Session 之间的数据共享,因为一级缓存是基于 SQL Session 的。而二级缓存可以实现多个 SQL Session 之间的数据共享,因为二级缓存是基于 SQL Session Factory 的。
-
缓存的清空: 当 SQL Session 执行了增删改(包括 commit 操作)操作时,就会清空一级缓存。而二级缓存只有在调用了
clearCache()
方法时才会清空。 -
使用场景: 一级缓存主要适用于一个业务操作中频繁操作同一份数据的情况,能够减少与数据库的交互次数,提高系统的性能。二级缓存主要适用于多个业务操作中频繁操作同一份数据的情况,同样可以减少与数据库的交互次数,提高系统的性能。
总的来说,一级缓存主要解决的是重复查询的问题,而二级缓存则主要解决了多次查询相同数据的问题。
12、MyBatis 一级缓存和二级缓存是什么数据结构?
MyBatis 的一级缓存和二级缓存的数据结构主要是基于HashMap
实现的。
-
一级缓存(Session Cache): MyBatis 的一级缓存是基于
PerpetualCache
(永久缓存)实现的,而PerpetualCache
内部使用了 Java 的HashMap
作为存储结构。每个SqlSession
都有一个自己的一级缓存,当SqlSession
关闭或提交时,该SqlSession
的一级缓存就会清空。 -
二级缓存(Mapper Cache): MyBatis 的二级缓存同样是基于
PerpetualCache
实现的,PerpetualCache
内部使用HashMap
作为存储结构。二级缓存是跨SqlSession
的,对于同一个SqlSessionFactory
,多个SqlSession
可以共享其二级缓存。当调用SqlSession
的clearCache
方法时,就会清空当前SqlSessionFactory
的二级缓存。
在实际使用中,二级缓存还可以通过装饰者模式添加各种装饰器,例如FifoCache
(先进先出缓存)、LruCache
(最少使用缓存)、SoftCache
(软引用缓存)等,以实现更多的缓存策略。
需要注意的是,无论是一级缓存还是二级缓存,都不适合用于存储大量数据,因为它们都是基于内存的缓存,如果存储大量数据,可能会导致内存溢出。同时,MyBatis 的缓存都是本地缓存,不适合在分布式环境中使用。如果在分布式环境中需要使用缓存,可以考虑使用如Redis等分布式缓存解决方案。
13、MyBatis 中的缓存有哪些实现类型?
MyBatis 提供了两级缓存:一级缓存和二级缓存,它们的实现方式如下:
一级缓存:
一级缓存是 SqlSession 级别的缓存,非全局的,它的生命周期与 SqlSession 一致。当我们在同一个 SqlSession 中执行相同的 SQL 语句时,第一次查询后的结果会被缓存在这个 SqlSession 中,如果我们再次执行相同的 SQL 语句,MyBatis 就会直接从缓存中取出结果,而不需要再次访问数据库。
二级缓存:
二级缓存是全局的,它的生命周期与 SqlSessionFactory 一致。二级缓存是跨 SqlSession 的,多个 SqlSession 可以共享这个缓存。只要一个 SqlSession 查询过一段数据,其他的 SqlSession 就可以直接从二级缓存中取出结果,而不需要再次访问数据库。
MyBatis 默认提供了基于内存的缓存实现(PerpetualCache),但是你也可以通过实现 Cache 接口来定制自己的缓存策略,例如,使用 EhCache、Redis 等技术实现分布式缓存。
要注意的是,虽然缓存可以提高性能,但是也可能会导致数据不一致的问题,因此在使用缓存时需要考虑到这个问题,并采取合适的策略来处理。
以上就是关于 MyBatis 中的缓存实现类型的介绍,希望对您有所帮助。如果您有其他问题,欢迎继续提问。
14、MyBatis 默认会开启缓存机制吗? 怎么开启?
一级缓存:
MyBatis 默认开启一级缓存,一级缓存是 SqlSession 级别的缓存,它的生命周期与 SqlSession 一致。当我们在同一个 SqlSession 中执行相同的 SQL 语句时,第一次查询后的结果会被缓存在这个 SqlSession 中,如果我们再次执行相同的 SQL 语句,MyBatis 就会直接从缓存中取出结果,而不需要再次访问数据库。
二级缓存:
MyBatis 的二级缓存默认是不开启的,需要我们手动去开启。二级缓存是跨 SqlSession 的,多个 SqlSession 可以共享这个缓存。
开启二级缓存的步骤如下:
- 在 MyBatis 的全局配置文件中开启二级缓存:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- 在需要使用二级缓存的 mapper 映射文件中添加如下配置:
<cache/>
或者如果你想自定义缓存的行为,你可以这样配置:
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
以上就是关于 MyBatis 缓存的开启方法。但是需要注意的是,虽然缓存可以提高性能,但是也可能会导致数据不一致的问题,因此在使用缓存时需要考虑到这个问题,并采取合适的策略来处理。
15、MyBatis 为什么默认不会开启二级缓存?
虽然二级缓存可以提高查询的性能,但是开启二级缓存也有一些潜在的问题需要注意:
-
数据一致性问题:二级缓存是跨SqlSession的,多个SqlSession可以共享这个缓存,这就意味着如果在一个SqlSession中更新了数据,而这个数据在其他SqlSession中也被缓存了,那么这些缓存的数据就会变得不一致。这是一个非常棘手的问题,要解决这个问题需要使用一些复杂的策略,如缓存同步,这可能会加大系统的复杂性。
-
可能产生脏读:如果多个SqlSession同时操作同一份数据,由于二级缓存数据的更新是在SqlSession提交或关闭时才会进行,这就可能导致一个SqlSession读到的是其他SqlSession尚未提交的脏数据。
-
内存消耗问题:二级缓存是存储在内存中的,如果缓存的数据量过大,会增加内存的消耗,可能会导致内存溢出。
因此,MyBatis默认是不开启二级缓存的,需要开发者根据实际的业务需求和系统环境来决定是否需要开启二级缓存,以及如何设置二级缓存的参数,以达到最优的效果。
由于内容太多,更多内容以链接形势给大家,点击进去就是答案了
21. MyBatis 映射时 A 引用了 B,如果 B 在 A 后面会怎样?
22. MyBatis 中 Mapper 接口的实现原理是?
23. MyBatis用注解绑定和用XML文件绑定有什么区别?
24. MyBatis通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应, Dao 的工作原理,是否可以重载?
25. MyBatis 中 Mapper 中的 SQL 语句可以重载吗?
26. MyBatis动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?
27. MyBatis实体类中的属性名和表中的字段名不一样 ,怎么办 ?
28. MyBatis 配置文件中的 SQL id 是否能重复?
35. MyBatis 是如何进行分页的?分页插件的原理是什么?
42. MyBatis 中jdbcType 和javaType 的区别?
43. MyBatis 什么时候必须指定jdbcType 和javaType?
44. MyBatis 什么时候必须指定jdbcType 和javaType?
48. MyBatis 事务和 Spring 事务有什么区别?
53. MyBatis 中 StatementHandler 和 MappedStatement 区别?
54. MyBatis 常用的 TypeHandler 有哪些?
55. MyBatis 怎么实现自定义的 TypeHandler?
57. MyBatis 中的 SglSession 是线程安全的吗?
58. MyBatis 中的 SglSession 有哪些实现类?
59. MyBatis 中的 DefaultSqlSession 为什么不是线程安全的?