小小小幸运 发表于 2025-1-13 15:34:10

Java MyBatis 面试题

谈谈MyBatis的启动过程?


[*]加载配置文件:

[*]MyBatis的配置文件是一个XML文件,包含了数据库连接信息、映射文件的位置等配置信息。在启动过程中,MyBatis会读取并解析这个配置文件。

[*]创建SqlSessionFactory对象:

[*]SqlSessionFactory是MyBatis的核心对象,用于创建SqlSession对象。在启动过程中,MyBatis会根据配置文件中的信息,创建一个SqlSessionFactory对象。

[*]创建SqlSession对象:

[*]SqlSession是MyBatis的会话对象,用于执行数据库操纵。在启动过程中,MyBatis会根据SqlSessionFactory对象,创建一个SqlSession对象。

[*]加载映射文件:

[*]映射文件是MyBatis的另一个紧张配置,用于界说SQL语句与Java方法之间的映射关系。在启动过程中,MyBatis会根据配置文件中的信息,加载映射文件。

[*]初始化Mapper接口:

[*]Mapper接口是用于执行SQL语句的Java接口,在启动过程中,MyBatis会根据映射文件中的信息,动态生成Mapper接口的实现类。

[*]完成启动:

[*]启动过程完成后,就可以使用SqlSession对象执行数据库操纵了。

何解决SqlSession的数据不安全的问题?


[*]在MyBatis中,SqlSession是一个线程不安全的对象,主要原因如下:

[*]SqlSession的底层实现是基于JDBC的Connection对象,而Connection对象是非线程安全的,因此SqlSession也是非线程安全的。
[*]SqlSession中包含了数据库连接和事务相关的操纵,假如多个线程共享同一个SqlSession实例,大概会导致数据的 不同等性或者 事务的混乱。
[*]SqlSession中的 缓存机制也是基于当火线程的,假如多个线程共享同一个SqlSession实例,大概会导致缓存的数据混乱或者不同等。

[*]怎样解决这个问题?

[*]为了保证数据的安全性和同等性,通常建议在每个线程中使用独立的SqlSession实例,可以通过工厂模式创建新的SqlSession对象,或者使用MyBatis提供的线程安全的SqlSessionFactory实例来创建SqlSession。另外,可以使用ThreadLocal来保证每个线程中使用的SqlSession对象是唯一的。

MyBatis中Mapper接口的实现类怎样生成的?


[*]界说Mapper接口
[*]编写Mapper XML文件(可选)
[*]配置MyBatis
[*]动态代理生成实现类:JDK动态代理机制生成一个Mapper接口的实现类。
MyBatis与JDBC的主要区别是什么?


[*]界说与用途:

[*]JDBC:允许Java程序与数据库进行交互,是一个底层的数据库访问技术。
[*]MyBatis:基于ORM的长期层框架。允许开发人员使用XML或注解来界说SQL映射,从而将数据库记录映射到Java对象。

[*]使用方式与操纵复杂度:

[*]JDBC:需手动编写SQL语句并处置惩罚结果集的转换。需处置惩罚数据库连接的创建和释放、SQL语句的编写以及结果集的解析等底层细节。需编写大量的样板代码,如注册驱动、创建连接、执行SQL语句、处置惩罚结果集以及关闭资源等。
[*]MyBatis:提供更简便、更易于维护的方式来访问数据库。封装常见的数据库操纵,不必处置惩罚底层的数据库连接、事务和非常处置惩罚等细节。通过XML或注解界说SQL映射,自动将数据库记录映射到Java对象。

[*]性能与缓存机制:

[*]JDBC:受到SQL语句的性能和数据库连接开销等因素影响。没有内置的缓存机制,需自行实现缓存逻辑。
[*]MyBatis:通过内置的缓存机制和优化技术,进步数据库访问性能。提供一二级缓存,其中一级缓存是SqlSession级别,二级缓存是Mapper级别。缓存机制可淘汰堆数据库的访问次数,进步查询效率。

[*]灵活性与可维护性:

[*]JDBC:提供了高度的灵活性,允许编写自界说的SQL语句。由于需要手动编写大量代码,代码复杂且不易维护。
[*]MyBatis:允许编写自界说的SQL语句,并提供丰富的配置选项来定制SQL映射和执行行为。由于使用了XML或注解来界说SQL映射,代码可维护性更高。

[*]应用场景:

[*]JDBC:适用需要高度自界说SQL语句的场景。适用对数据库操纵有较高要求的场景,如性能调优、复杂查询等。
[*]MyBatis:适用将数据库记录映射到Java对象的场景。适用需求变化多端的项目,如互联网项目等。适用快速开发、迭代的项目。

MyBatis的编程步调是怎样的?


[*]引入MyBatis依赖:Maven项目,在pom.xml中添加依赖。Gradle项目,在build.gradle中添加依赖。
[*]配置阶段:配置MyBatis核心文件、创建数据库连接配置、配置日志输出(可选)。
[*]编码阶段:创建实体类、创建Mapper接口、编写Mapper XML文件(或使用注解)。
[*]整合阶段:创建SqlSessionFactory、编写测试代码。
[*]运行和调试阶段:运行测试代码、调试和监控、优化性能(可选)。
MyBatis中,SqlSessionFactory的作用是什么?


[*]创建SqlSession对象:SqlSessionFactory是MyBatis的核心接口,用于创建SqlSession对象。
[*]管理数据库连接池:负责管理数据库连接池。
[*]加载和解析配置文件:负责加载配置文件,并根据配置文件初始化数据库连接、事务管理等。
[*]线程安全性:SqlSessionFactory是线程安全的,可以在多个线程之间共享。
[*]单例模式:由于SqlSessionFactory的创建是比较消耗资源的操纵,通常建议使用单例模式管理SqlSessionFactory对象。
MyBatis中的SqlSession有什么作用?


[*]执行SQL语句
[*]事务管理
[*]获取Mapper接口实例
[*]缓存管理:负责管理一级缓存。
[*]管理数据库连接
MyBatis的Mapper接口是什么?它的作用是什么?


[*]界说操纵数据库的方法
[*]与XML映射文件关联
[*]简化数据库操纵
[*]进步代码的可维护性和可读性
[*]支持动态SQL
[*]支持注解和XML两种方式
[*]事务管理:通过Mapper接口,MyBatis可以管理数据库事务,可以与Spring框架集成,利用Spring的事务管理功能。
MyBatis中,怎样配置数据库连接信息?


[*]使用XML配置文件:在mybatis-config.xml文件中配置数据库连接信息。

[*]界说情况:<configuration>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><environments default="development">
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><environment id="development">
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC"/>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><dataSource type="POOLED">
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><property name="username" value="root"/>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><property name="password" value="password"/>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype></dataSource>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype></environment>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype></environments>
</configuration>
[*]指定事务管理器:支持JDBC和MANAGED两种类型。
[*]配置数据源:包罗数据库驱动类、数据库URL、用户名、密码等信息。

[*]使用注解配置

[*]添加依赖和数据库驱动依赖
[*]创建SqlSessionFactory:使用SqlSessionFactioryBuilder创建SqlSessionFactory。String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
[*]使用@Mapper注解:在Mapper接口上使用@Mapper注解。@Mapper
public interface MyMapper {
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>// 方法定义
}
[*]配置DataSource:在配置类中配置DataSource,并使用@MapperScan注解指定Mapper接口的位置。@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {

<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@Bean
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>public DataSource dataSource() {
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>DriverManagerDataSource dataSource = new DriverManagerDataSource();
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase");
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>dataSource.setUsername("root");
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>dataSource.setPassword("password");
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>return dataSource;
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>}

<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@Bean
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>sessionFactory.setDataSource(dataSource);
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>return sessionFactory.getObject();
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>}

[*]Spring Boot配置:在application.properties文件中配置数据库连接信息。# application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=root
spring.datasource.password=password
MyBatis支持哪些数据库?为什么?


[*]MySQL。支持原因:MySQL广泛应用于Web应用。
[*]Oracle。支持原因:Oracle支持复杂查询,具有高级的安全性和数据完整性。
[*]SQL Server。支持原因:SQL Server具有易用的管理工具、强大的集成安全性以及于其他微软产物的良好兼容性。
[*]DB2。支持原因:DB2具有高可靠性、高性能、可扩展性。
[*]PostgreSQL。支持原因:PostgreSQL支持复杂查询,具有高级的数据完整性和安全性,适用于需要高度定制化的应用。
[*]SQLite。支持原因:SQLite无需配置、零管理,嵌入式数据库引擎非常适合移动装备或桌面应用。
[*]MariaDB。支持原因:与MySQL高度兼容,具有更好的性能和可扩展性,适用于需要高性能和可靠性的应用。
MyBatis中的@Select、@Insert、@Update、@Delete注解分别用于什么场景?


[*]@Select:查询单个记录。查询记录列表。执行聚合查询(如COUNT、SUM、AVG等)。
[*]@Insert:插入新记录。批量插入记录。
[*]@Update:更新用户信息。更新多条记录(使用WHERE子句)。
[*]@Delete:删除特定用户记录、根据条件删除多条记录。
[*]注意事项:

[*]参数绑定:使用#{paramName}绑定方法参数到SQL语句中的占位符。
[*]结果映射:对于@Select注解, 可以使用@Results注解来界说结果集的映射。
[*]动态SQL:支持使用@SelectProvider注解来动态构建SQL语句。

MyBatis的XML映射文件中,可以包含哪些标签?


[*]cache:命名空间的缓存配置。
[*]cache-ref:引用其他命名空间的缓存配置。
[*]resultMap:界说结果集与Java对象之间的映射关系。
[*]parameterMap:参数映射。
[*]sql:界说可重复使用的SQL语句块。
[*]insert:映射插入语句。
[*]update:映射更新语句
[*]delete:映射删除语句。
[*]select:映射查询语句。
MyBatis中的#{}和${}有什么区别?在什么场景下应该使用它们?


[*]{} (预处置惩罚参数):

[*]用途:预处置惩罚语句,自动为SQL参数提供适当的转义,防止SQL注入攻击。
[*]参数替换:当使用#{}时,MyBatis会将传入的参数值替换为?,然后使用JDBC的setXxx方法来设置参数值。
[*]适用场景:当需要转达参数值到SQL语句中,而且这些值时不可预测的,使用#{}可以防止SQL注入。

[*]${} (字符串插值):

[*]用途:字符串插值,将传入的参数值拼接到SQL语句中。大概导致SQL注入攻击。
[*]字符串拼接:当使用${}时,MyBatis会将传入的参数值直接拼接到SQL语句中。
[*]适用场景:当需要动态构建SQL语句,如动态表名、列名、SQL函数名时,使用${}可满足这些需求。当确定传入的值是安全的,而且不会导致SQL注入,可以使用。

[*]推荐优先使用#{}。
MyBatis的一级缓存和二级缓存有什么区别?


[*]一级缓存:

[*]作用域:是SqlSession级别的。
[*]生命周期:与SqlSession雷同。当SqlSession被关闭时,一级缓存也会被清空。一级缓存的数据只在当前SqlSession内有效。
[*]默认状态:默认情况下是开启的,且无法关闭。
[*]配置方式:默认是开启的,不需要进行额外的配置。但可以通过设置来控制一级缓存的行为,如手动清空缓存等。
[*]缓存失效情况:在执行insert、update、delete操纵时失效,确保数据的同等性。

[*]二级缓存:

[*]作用域:是Mapper级别的。
[*]生命周期:比一级缓存长。与SqlSessionFactory相关,当SqlSessionFactory被销毁时,二级缓存才会失效。适用于需要长时间缓存数据的场景。
[*]默认状态:默认是关闭的,需要在配置文件中显式启用。
[*]配置方式: 需要显式配置才能启用。还可以使用第三方缓存框架(如EHCache、Redis等)来实现二级缓存。
[*]缓存失效情况:在执行insert、update、delete操纵时失效,确保数据的同等性。还可以通过配置来调解其失效策略,如设置失效时间、刷新条件等。

MyBatis的缓存机制是怎样工作的?


[*]一级缓存:当在同一个SqlSession中执行雷同的查询时,MyBatis会将查询结果缓存在一级缓存中,假如再次执行雷同的查询,MyBatis会直接从缓存中获取结果。
[*]二级缓存:当多个SqlSession实例执行雷同的查询时,MyBatis会从二级缓存中获取结果。假如二级缓存中没有结果,则会查询数据库并将结果放入二级缓存。
MyBatis中,怎样开启二级缓存?


[*]配置MyBatis全局设置:通常是在mybatis-config.xml中启用全局二级缓存。
[*]配置MapperXML文件:在对应的MapperXML文件中配置元素,以启用该Mapper的二级缓存。
[*]配置缓存策略(可选):可以通过标签来配置缓存策略,如。
[*]配置缓存实现(可选):如需实现自界说缓存,可以实现Cache接口,并在中使用type属性指定缓存实现类。
[*]配置实体类(可选):确保实体类实现了Serializable接口,便于缓存对象可以被序列化。
[*]使用缓存(查询和更新):Mybatis会自动管理缓存的插入、更新和失效。
[*]注意事项:

[*]二级缓存是跨SqlSession的,因此同一个SqlSession中进行更新操纵不会立刻影响缓存。
[*]假如应用是多线程,确保缓存实现是线程安全的。
[*]默认不支持分布式情况,假如应用部署在多个服务器上,需要自行实现分布式缓存解决方案。

MyBatis怎样进行分页?分页插件的原理是什么?


[*]分页通过两种方式实现:

[*]使用RowBounds对象进行分页:

[*]RouBounds是自带的一个对象,用于指定分页参数,包含offset和limit两个元素。offset表示结果集从哪一行开始返回,limit表示返回的行数。

[*]使用分页插件进行分页:PageHelper。

[*]分页插件工作原理:

[*]拦截器机制:通过实现MyBatis的Interceptor接口,拦截SQL语句的执行。
[*]自动添加分页语句:当拦截到查询方法时,插件会检测传入的参数是否包含分页信息。假如包含,插件会根据数据库类型自动为原始语句添加相应的分页语句。
[*]执行分页SQL:经过插件修改的SQL语句会被执行器执行,数据库返回分页后的结果集。
[*]封装结果:插件可以封装查询结果,将其封装为分页对象(如Page)。

MyBatis中的动态SQL是什么?它有哪些标签?


[*]动态SQL:是指在SQL语句中包含一些逻辑判定和变量,根据不同的条件动态地生成不同地SQL语句。
[*]动态SQL标签:

[*]:条件判定标签,SQL语句中添加条件判定。
[*]、、:类似JAVA中的Switch语句,用于在多个条件中选择一个执行。
[*]: 用于自界说SQL语句片段的修剪,可以去除开头或结尾的特定字符。通常处置惩罚动态拼接SQL语句中的逗号、AND、OR等问题。
[*]:用于拼接WHER子句,自动处置惩罚WHER关键字和多个条件之间地链接关系(AND或OR)。
[*]:用于拼接UPDATE语句地SET子句,自动处置惩罚SET关键字和多个字段更新。
[*]:用于遍历集归并拼接对应的SQL语句片段。
[*]:用于将一个表达式的结果绑定到一个变量上,便于在后续的SQL语句中使用。

MyBatis怎样防止SQL注入?


[*]使用参数化查询:

[*]使用#{}占位符:MyBatis会将#{}中的参数绑定到SQL语句中,而不是直接将用户输入的内容嵌入到SQL语句中。
[*]预编译语句:默认使用预编译SQL语句,将SQL语句和参数分离,克制用户舒服的数据被直接插入到SQL语句中。

[*]动态SQL:使用动态SQL标签,根据条件动态生成SQL语句,同时保证参数的安全性。
[*]输入验证:对用户输入进行验证,在应用层面,对用户输入的数据进行严酷的验证和过滤,确保输入数据的合法性和安全性。
[*]限制使用${}插值:克制使用${},尽量使用#{}进行参数绑定,假如肯定要使用,则需要在代码中手工进行过滤和验证。
[*]数据库权限限制:为数据库用户分配适当的权限,克制拥有过多权限,淘汰SQL注入攻击的潜在风险。
[*]使用Web应用防火墙:可以进一步增强应用的安全性。
[*]定期更新MyBatis:及时更新MyBatis及相关依赖,获取最新安全补丁和更新。
MyBatis的映射标签有哪些?它们的作用是什么?


[*]select:用于执行查询操纵,将查询结果映射到Java对象。
[*]insert:用于执行插入操纵,将Java对象的属性插入到数据库中。
[*]update:用于执行更新操纵,更新数据库中已有的数据。
[*]delete:用于执行删除操纵,从数据库中删除记录。
[*]resultMap:用于界说结果集映射关系,将查询结果映射到Java对象。
[*]sql: 界说可重用的SQL片段,便于在多个SQL语句中引用。
[*]include:引用其他SQL片段,淘汰重复代码。
[*]if:条件判定标签,用于动态生成SQL语句的一部分。
[*]choose、when、otherwise:类似JAVA中的Switch语句,用于在多个条件中选择一个执行。
[*]trim: 用于自界说SQL语句片段的修剪,可以去除开头或结尾的特定字符。通常处置惩罚动态拼接SQL语句中的逗号、AND、OR等问题。
[*]where:用于拼接WHER子句,自动处置惩罚WHER关键字和多个条件之间地链接关系(AND或OR)。
[*]set:用于更新操纵,自动去除多余的逗号,确保每个更新的字段都有适当的逗号分隔。
[*]foreach:用于遍历集归并拼接对应的SQL语句片段,常用于IN语句的参数拼接。
MyBatis中的ResultMap是什么?它有什么作用?


[*]ResultMap:指定数据库查询结果映射到Java对象的映射关系。
[*]作用:

[*]界说映射规则:允许开发者显式地界说数据库表字段与Java对象属性之间地映射关系。
[*]处置惩罚复杂关系:可以处置惩罚一对一、一对多、多对多等复杂关系。通过association和collection标签,将关联的表数据映射到嵌套的Java对象中。
[*]自界说映射逻辑:使用discriminator标签根据某个字段的值来决定怎样映射不同的结果。

[*]特点:

[*]可选性:只有在需要处置惩罚复杂的映射关系时,才需要使用。
[*]XML配置:通常在XML中界说,通过resultMap标签来配置映射规则。
[*]灵活性:提供丰富的标签和属性,如id, result, association, collection, discriminator等,可以灵活的界说各种映射逻辑。

MyBatis支持哪些设计模式?请举例说明。


[*]Builder模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。SqlSessionFactoryBuild、XMLConfigBuilder、XMLStatementBuilder、CacheBuilder都采用了Builder模式。
[*]工厂模式:专门界说一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。SqlSessionFactory是工厂类,负责创建SqlSession实例。
[*]单例模式:确保某一个类只有一个实例,而且自行实例化并向整个体系提供整个实例。ErrorContext和LogFactory都是单例模式类。
[*]代理模式:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。MapperProxy是代理类。将Mapper接口的方法调用代理到实际的SQL执行过程。
[*]组合模式:将对象组合成树形布局表示"部分-整体"的层次架构。SqlNode和各个子类(如ChooseSqlNode)采用了组合模式。
[*]模板方法模式:在一个方法中界说一个算法的骨架,将一些步调延迟到子类中。BaseExecutor、SimpleExecutor等类采用了模板方法模式。
[*]适配器模式:将一个类的接口转换成客户端需要的接口,是本来由于接口不兼容而不能一起工作的类可以一起工作。Log接口和各种日志框架的适配实现采用了适配器模式。
[*]装饰者模式:动态给一个对象添加一些额外的职责。Cache包中的cache.decorators子包中的各个装饰者类采用了装饰者模式。
[*]迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需袒露该对象的内部表示。PropertyTokenizer类采用了迭代器模式。
MyBatis中的Executor类有什么作用?


[*]执行SQL语句:负责将SQL语句转换成JDBC可执行的语句。
[*]缓存管理:管理一二级缓存,提供数据库操纵性能。
[*]事务管理:提供事务管理功能,包罗提交、回滚、关闭事务。
[*]批处置惩罚支持:通过BatchExecutor实现,Executor支持批量操纵,淘汰网络通信开销。
MyBatis的Configuration类包含哪些信息?
MyBatis怎样管理数据库会话?


[*]通过SqlSession对象管理数据库会话。
MyBatis中的SqlSessionTemplate与SqlSessionManager有什么区别?


[*]适用场景:

[*]SqlSessionTemplate:应用已适用Spring框架,而且需要集成MyBatis,推荐使用。
[*]SqlSessionManager:适用于不使用Spring框架的场景。

[*]事务管理:

[*]SqlSessionTemplate:依赖Spring的事务管理。
[*]SqlSessionManager:需要手动管理事务。

MyBatis怎样与Spring框架集成?


[*]添加依赖:在SpringBoot中,需要在pox.xml文件中添加MyBatis相关依赖。
[*]配置数据库连接:在application.yml文件中配置数据库连接信息。
[*]创建实体类:根据数据库表布局创建对应实体类。
[*]创建Mapper接口:界说Mapper接口,用于执行数据库操纵。
[*]配置MyBatis(可选):SpringBoot中通常不需要配置MyBatis,由于已经提供了自动配置。
[*]使用Mapper接口:在Service或Controller中,通过依赖注入方式使用Mapper接口。
MyBatis的批量插入数据有哪些方式?


[*]使用BatchExecutor
[*]使用foreach标签
[*]使用@Param注解与foreach标签
MyBatis怎样获取自动生成的键值?


[*]使用@Options注解:指定useGeneratedKeys和keyProperty属性。
[*]使用XML映射文件:在insert标签中使用useGeneratedKeys和keyProperty属性。
在Mapper中怎样转达多个参数?


[*]使用@Param注解
[*]使用参数对象、
[*]使用Map
MyBatis中的一对一、一对多关联查询怎样实现?


[*]一对一:

[*]使用XML配置:使用association元素来表示一对一关联。
[*]使用注解:使用@Results和@One注解。

[*]一对多:

[*]使用XML配置:使用collection元素表示一对多关联。
[*]使用注解:使用@Results和@Many注解。

当表中的字段名和实体类的属性名不一样时,应该怎么办?


[*]使用@Result注解
[*]使用XML映射文件:使用resultMap元素界说字段名与属性名的映射关系。
[*]使用@Column注解:实体类的属性使用@Column注解指定数据库表的字段名。
MyBatis中的模糊查询like语句应该怎么写?


[*]使用%和_通配符:% 表示任意数量的字符,_ 表示单个字符。
[*]使用bind元素:<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><select id="selectUsersByNamePattern" resultType="User">
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><bind name="pattern" value="'%' + namePattern + '%'"/>
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>SELECT * FROM User
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>WHERE name LIKE #{pattern}
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype></select>
[*]使用注解:使用@Select注解,SQL语句中使用CONCAT函数或字符串拼接。
MyBatis的Mapper接口方法能重载吗?为什么?


[*]不能重载。原因如下:

[*]动态代理机制:假如存在重载方法,无法通过方法名唯一地确定要执行的SQL语句,由于方法名雷同,参数不同,无法区分要调用哪个方法。
[*]XML映射文件的限制:XML中每个元素都有一个唯一的id属性,这个id属性与Mapper接口的方法名对应,假如接口方法重载,那么XML无法为每个重载方法提供唯一的id。
[*]参数解析的复杂性:解析Mapper接口方法的参数时,需要根据参数的类型和名称来确定怎样转达参数到SQL语句中,假如存在重载方法,需要处置惩罚更多的参数解析逻辑,这增加了实现的复杂性。

MyBatis的Mapper接口工作原理是什么?


[*]动态代理机制:

[*]JDK动态代理:主要使用JDK动态代理来创建Mapper接口的代理对象。要求代理对象必须实现一个或多个接口,因此Mapper接口必须被界说为接口。
[*]代理对象创建:MyBatis配置文件中,通常会指定Mapper接口的位置。启动时会自动扫描这些位置,并创建对应的代理对象。被存储在SqlSession中。
[*]方法调用拦截:当调用Mapper接口的方法时,调用会被代理对象拦截,代理对象会根据方法名称和参数,在配置文件或注解中找到对应的SQL语句。

[*]SQL映射:

[*]XML配置文件:使用select、insert、update、delete等标签来界说SQL语句,这些标签的id属性与Mapper接口中的方法名称相对应。
[*]注解:使用Select、Insert、Update、Delete等注解来指定SQL语句。

[*]参数处置惩罚和结果映射:

[*]参数处置惩罚:MyBatis能自动处置惩罚Mapper接口方法中的参数,并将其正确的转达给SQL语句。包罗基本数据类型、Pojo对象、Map对象等。还提供@Param注解指定参数名称。
[*]结果映射:执行SQL语句得到的结果集,MyBatis根据配置的结果类型将其映射为相应的Java对象返回。

MyBatis中的namespace有什么作用?


[*]区分不同的Mapper接口
[*]与XML映射文件关联
[*]唯一标识SQL映射语句:namespace + id 共同构建了SQL映射语句的唯一标识符。
[*]支持多模块开发
MyBatis怎样支持多种数据库?需要做什么配置?


[*]SpringBoot项目配置步调:

[*]配置文件中配置多个数据库的连接信息:# 数据库1配置
spring.datasource.db1.url=jdbc:mysql://localhost:3306/db1
spring.datasource.db1.username=root
spring.datasource.db1.password=123456
spring.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driver

# 数据库2配置
spring.datasource.db2.url=jdbc:oracle:thin:@localhost:1521:ORCL
spring.datasource.db2.username=user1
spring.datasource.db2.password=password1
spring.datasource.db2.driver-class-name=oracle.jdbc.driver.OracleDriver
[*]在Spring配置类中为每个数据库创建数据源、SqlSessionFactory、事务管理器:@Configuration
public class MyBatisConfig {

<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@Bean(name = "dataSource1")
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@ConfigurationProperties(prefix = "spring.datasource.db1")
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>public DataSource dataSource1() {
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>return DataSourceBuilder.create().build();
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>}

<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@Bean(name = "sqlSessionFactory1")
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>public SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource1") DataSource dataSource) throws Exception {
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>factoryBean.setDataSource(dataSource);
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>// 其他配置(如 mybatis-config.xml 文件的路径)
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>return factoryBean.getObject();
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>}

<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@Bean(name = "transactionManager1")
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>public DataSourceTransactionManager transactionManager1(@Qualifier("dataSource1") DataSource dataSource) {
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>return new DataSourceTransactionManager(dataSource);
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>}

<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>// 为数据库2配置类似的数据源、SqlSessionFactory 和事务管理器
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>// ...
}
[*]配置Mapper接口:

[*]为每个数据库创建对应的Mapper接口和XML映射文件(假如使用XML配置的话)。
[*]在Mapper接口的方法上,可以使用自界说注解(如@dataSource)来指定使用哪个数据源,需要通过AOP来实现数据源的动态切换。

[*]使用AOP动态切换数据源:通过AOP在执行Mapper接口方法时动态切换数据源。

MyBatis中的SqlSessionFactoryBuilder类有什么作用?


[*]解析配置文件:负责解析MyBatis的配置文件。
[*]创建SqlSessionFactory:根据解析的配置信息,创建一个SqlSessionFactory实例。
MyBatis中的事务管理是怎样实现的?


[*]基于JDBC的事务管理:

[*]配置事务管理:<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>
[*]事务的提交与回滚:

[*]通过SqlSession对象实现。
[*]获取到SqlSession对象时,默认开启一个事务,执行完一系列数据库操纵后,调用SqlSession的commit方法提交事务,假如操纵失败,调用rollback方法往返滚事务。
[*]底层实现:通过JdbcTransaction类实现。


[*]基于MANAGED的事务管理:

[*]配置事务管理器:
[*]事务的管理:依赖容器的事务管理机制。

[*]基于注解的事务管理:

[*]在需要进行事务管理的方法上添加@Transactional注解,并指定事务的流传行为、隔离级别等属性。
[*]通常与Spring框架一起使用,Spring提供了对@Transactional注解的支持。

MyBatis的延迟加载是什么?它的实现原理是什么?


[*]延迟加载:一种数据查询策略,允许仅在需要时才从数据库获取数据。
[*]实现原理:

[*]动态代理:当查询主对象时,不会立刻加载关联对象的数据,而是为关联对象生成代理对象。
[*]拦截器机制:当访问代理对象的属性或方法时,代理对象会触发真实的数据库查询操纵。
[*]配置控制:在MyBatis配置文件中,通过LazyLoadingEnabled属性来全局控制延迟加载的开关。在详细的resultMap中,也可以通过fetchType属性来控制某个关联关系是否使用延迟加载。

MyBatis中的XML映射文件和注解方式各有什么优缺点?


[*]xml映射文件:

[*]优点:

[*]灵活性:允许编写复杂的SQL语句,包罗动态SQL和条件判定等。
[*]易于维护:SQL语句和映射关系被分离到XML文件中,有助于管理和维护,当需要修改SQL语句或映射关系时,只需关注XML文件,而不必深入代码逻辑。
[*]可读性:对于复杂的SQL逻辑,XML文件大概比注解更容易明白和维护。

[*]缺点:

[*]增加学习成本:需要学习XML语法和MyBatis的XML映射标签。
[*]修改和维护麻烦:每次修改SQL语句或映射关系时,需要重新编译和部署XML文件。


[*]注解:

[*]优点:

[*]简便性:使代码更简便,淘汰了配置文件的数量。
[*]易于明白:对于简单的SQL语句或映射关系,比XML文件更容易明白。

[*]缺点:

[*]功能限制:对于复杂的SQL语句和映射关系,无法满足需求。
[*]修改和维护困难:修改SQL语句通常需要修改代码,涉及到更多的代码更改和重新编译,也不利于SQL的重用和维护。


MyBatis中的ResultHandler接口有什么作用?


[*]自界说处置惩罚逻辑:允许对查询结果的每一行数据进行自界说处置惩罚。
[*]优化性能:在处置惩罚大量数据时,使用可以克制一次性将全部结果加载到内存中,淘汰内存消耗。
[*]灵活的数据处置惩罚:可以根据详细的业务需求,对结果进行复杂的处置惩罚和操纵,而不需要依赖于MyBatis的默认结果处置惩罚方式。
MyBatis中的TypeHandler接口是什么?它用于什么场景?


[*]TypeHandler:负责Java类型和JDBC类型之间的映射和转换。
[*]应用场景:

[*]数据类型不匹配:当Java类型与数据库字段类型不同等时,可以使用TypeHandler实现转换。
[*]数据格式转换:当数据库存储格式与盼望格式不同等时,可以使用TypeHandler进行格式化。
[*]处置惩罚复杂数据类型:对于复杂数据类型(如自界说对象、集合等),允许自界说TypeHandler实现复杂的类型转换逻辑。
[*]数据加密解密:生存敏感数据时,使用TypeHandler实现数据的加解密。

MyBatis中的Plugin机制是什么?它怎样工作?


[*]Plugin:允许开发者通过自界说插件来扩展和修改MyBatis的核心行为。基于Java的动态代理机制,通过拦截器模式实现对MyBatis核心对象的方法调用拦截和处置惩罚。
[*]工作原理:

[*]拦截器界说:需要实现Interceptor接口。
[*]插件配置:在mybatis-config.xml中,通过plugin标签配置插件。
[*]代理对象生成:MyBatis初始化时,根据配置创建拦截器实例,并在创建核心对象时,通过InterceptorChain的pulginAll方法,将拦截器应用于目的对象,生成代理对象。
[*]方法调用拦截:当调用目的对象的方法时,检查是否存在对应的拦截器,假如存在且方法签名匹配,则调用拦截器的intercept方法执行自界说逻辑。

[*]应用场景:

[*]日志记录
[*]性能监控
[*]SQL修改
[*]缓存管理

MyBatis中的拦截器(Interceptor)有哪些用途?


[*]拦截MyBatis执行器方法的执行:允许拦截和自界说MyBatis执行器的行为。例如添加缓存、日志记录、审计功能到执行器中。
[*]拦截SQL语句的执行:可以在SQL语句执行前修改它们。例如可以向WHERE子句添加额外的条件或记录执行的语句。
[*]拦截SQL语句的参数设置:允许将参数设置到SQL语句之前修改或验证它们。例如可以对参数转达的敏感信息加解密。
[*]拦截从SQL语句返回的结果集的处置惩罚:可以将结果集返回给应用程序之前修改或分析它们。例如可以对结果集进行转换或执行额外的盘算。
[*]数据操纵审计:记录SQL语句的执行情况,包罗执行时间、执行参数、返回结果等。
[*]性能优化:记录SQL的执行时间,进行性能分析和日志记录。
[*]事务管理:通过拦截Executor接口的相关方法,实现自界说的事务管理逻辑。
[*]通用业务逻辑:拦截器可以用于插入同一的业务逻辑,如自动填充创建时间、更新时间、操纵人信息等。
MyBatis中的别名(Alias)机制是什么?它怎样工作?


[*]别名机制:一种用于简化类型引用的机制,允许开发者为Java类型或类型指定一个简短的别名,在MyBatis的配置文件和映射文件中替代完整的类名或类型名称。
[*]工作原理:

[*]注册别名:

[*]自动注册
[*]手动注册:

[*]mybatis-config.xml中使用 typeAlias 标签注册别名。
[*]Java代码中使用@Alias注解为类指定别名。
[*]MyBatis配置类中使用 typeAliasRegistry注册别名。


[*]使用别名:

[*]在MyBatis映射文件中,可以在resultMap、parameterMap、select、insert等元素中使用别名来引用类型。例如:<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>
[*]在MyBatis的接口方法中,可以使用别名作为参数类型或返回类型。例如:public interface UserMapper {<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>User selectUserById(int id);}


MyBatis中的日志功能是怎样实现的?可以配置哪些日志框架?


[*]实现:通过LogFactory实例化创建的,该工厂类会按照优先级顺序尝试创建各种日志技术的对象。
[*]日志优先级:SLF4J > Jakarta Commons Loggin(JCL) > Log4j2 > Log4j > Java Util Logging(JUL) > 不使用日志
[*]可配置日志框架:SLF4J、Logback、Log4j2、Commons Loggin
MyBatis中的多表关联查询怎样实现?有哪些注意事项?


[*]实现方式:

[*]使用 association 和 collection 标签:一对一使用association标签,一对多使用collection标签。
[*]嵌套查询:在resultMap中界说嵌套查询,通过子查询获取关联数据。
[*]手动SQL拼接:在MyBatis映射文件中编写SQL语句,使用SQL的JOIN操纵进行多表关联查询,通过resultMap将结果映射到对象属性中。

[*]注意事项:

[*]性能优化:克制N+1查询问题。使用嵌套查询时,大概导致主查询执行依次,而关联查询执行多次。
[*]结果映射:确保resultMap中的属性映射正确,克制因字段名或属性名不匹配导致数据丢失。使用fetchType属性控制关联查询的加载策略。
[*]SQL语句优化:编写高效SQL语句,克制不必要的复杂查询和数据冗余。注意SQL语句的可读性和维护性。

MyBatis中的子查询和外连接查询有什么区别?


[*]界说与用途:

[*]子查询:在另一个查询之前或之中执行的查询。查询结果可以被著查询使用,通常作为筛选条件或数据源。
[*]外连接查询:用于返回两个表中符合连接条件的数据行,同时还会返回左表或右表中不符合连接条件但符合其他筛选条件的数据行。

[*]执行方式与效率:

[*]子查询:通常先执行,其结果作为主查询的条件或数据源。子查询假如返回多个结果,主查询会对结果进行筛选。子查询大概会多次遍历数据,特殊是当子查询嵌套在循环或多次调用的上下文时,效率大概较低。
[*]外连接查询:在一次查询中同时处置惩罚两个表的数据,根据连接条件返回结果。只遍历一次数据,效率相对较高。假如连接条件复杂或涉及大量数据,连接查询也大概变得缓慢。

[*]适用场景:

[*]子查询:适用需要从一个表中筛选符合另一个表中条件的数据时。当查询涉及多个层次或嵌套关系时,子查询大概更加直观和易于明白。对于大数据量或复杂查询,子查询不是最优选择。
[*]外连接查询:适用需要同时查看两个表的数据,而且保留其中一个表中不符合连接条件但符合其他筛选条件的数据行时。适用数据完整性要求高的场景,如需要表现全部订单及其客户信息,即使某些订单没有客户信息。

MyBatis中的团结查询(UNION)怎样实现?


[*]使用XML映射文件:在XML映射文件中,可以直接编写包含UNION或UNION ALL的SQL语句。<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>SELECT id, name FROM user WHERE age > 18<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>UNION ALL<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>SELECT id, name FROM user WHERE name LIKE '%John%'<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>
[*]使用注解:可以直接在Mapper接口方法上使用@Select注解编写包含UNION的SQL语句。public interface UserMapper {<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>@Select("SELECT id, name FROM user WHERE age > 18 " +<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>"UNION ALL " +<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>"SELECT id, name FROM user WHERE name LIKE '%John%'")<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>List selectUsersByUnion();}
[*]使用动态SQL:如foreach等。<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype><transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>SELECT id, name FROM user WHERE ${item.condition}<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManagertype>
MyBatis在处置惩罚大数据量时,有哪些优化策略?


[*]查询优化:

[*]分页查询:设置每页表现的条目淘汰一次性查询的数据量,克制内存溢出和性能下降。
[*]流式查询:建立长连接,利用服务端游标,每次读取一条数据加载到JVM内存,淘汰内存占用。设置fetchSize参数控制每次读取的数据量。
[*]游标查询:通过fetchSize参数控制一次读取多少条数据,进一步淘汰内存占用。
[*]优化查询逻辑:克制N+1查询问题,通过团结查询或批量查询淘汰数据库交互次数。只选择需要的字段,克制select *查询。

[*]批量操纵优化:

[*]批量插入:使用foreach标签构建批量插入的SQL语句,淘汰数据库交互次数。MyBatis-Plus的saveBatch方法也可以实现批量数据插入。
[*]批量更新和删除:使用updateBatch和deleteBatch方法,一次性执行多条SQL语句。在XML映射文件中,使用foreach标签遍历需要更新或删除的数据集合。
[*]事务管理:进行批量操纵时,建议使用事务来确保操纵的原子性。通过在方法上添加@Transactional注解或使用编程式事务管理来实现。
[*]批量执行器:配置MyBatis使用批量执行器(BATCH),进一步提升批量操纵性能。

[*]缓存优化:

[*]一级缓存:默认启用一级缓存,即会话级别的缓存。同一会话中,雷同的查询结果会被缓存,淘汰数据库查询次数。
[*]二级缓存:启用二级缓存,实现跨会话的查询缓存。根据详细业务需求,配置缓存策略(如LRU、FIFO等),确保数据同等性和性能的均衡。

[*]数据库和连接池优化:

[*]数据库优化:根据详细情况,优化数据库性能,例如调解数据库缓存、优化SQL查询等。确保需要查询或操纵的数据库表有符合的索引。
[*]连接池优化:使用符合的数据库连接池(如Druid、HikariCP等),公道配置连接池参数(如最大连接数、最小连接数、连接超时时间等)。确保数据库驱动支持批处置惩罚操纵(如MySQL的rewriteBatchedStatements=true)。

[*]分段处置惩罚:将大查询拆分成多个小查询,分段处置惩罚数据。
[*]淘汰不必要的数据传输:查询结果只包含必要的字段,克制传输不必要的数据。
[*]代码和配置优化:确保MyBatis的配置文件和映射文件的优化和正确配置。Java代码中实现公道的逻辑控制和非常处置惩罚。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Java MyBatis 面试题