📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)、《解密程序员的思维密码——沟通、演讲、思考的实践》作者、清华大学出版社签约作家、Java领域优质创作者、优快云博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。
📙不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

🍊 MyBatis核心知识点之SqlSessionTemplate:概述
在当今的Java开发领域,MyBatis作为一款优秀的持久层框架,以其简洁的配置和强大的功能,深受广大开发者的喜爱。然而,在实际应用中,我们常常会遇到一个场景:在多个地方需要执行数据库操作时,频繁地创建和关闭SqlSession,这不仅增加了代码的复杂性,而且降低了系统的性能。为了解决这一问题,MyBatis提供了SqlSessionTemplate,它是一个线程安全的SqlSession实现,可以有效地管理SqlSession的生命周期,从而提高应用程序的执行效率。
SqlSessionTemplate的重要性在于,它简化了数据库操作的过程,减少了资源消耗,提高了代码的可维护性。在传统的MyBatis使用中,每次执行数据库操作都需要手动创建和关闭SqlSession,这在多层架构中尤为繁琐。而SqlSessionTemplate的出现,使得开发者无需关心SqlSession的创建和关闭,只需关注业务逻辑的实现,大大降低了开发难度。
接下来,我们将对SqlSessionTemplate进行深入探讨。首先,我们将介绍其概念,阐述SqlSessionTemplate是如何工作的,以及它与传统SqlSession的区别。其次,我们将探讨SqlSessionTemplate的作用,分析它在提高应用程序性能和简化开发流程方面的具体体现。最后,我们将详细分析SqlSessionTemplate的特点,包括其线程安全性、可配置性以及与Spring框架的集成等。
通过本节内容的介绍,读者将能够全面了解SqlSessionTemplate,掌握其在MyBatis框架中的应用,为后续深入学习和实践打下坚实的基础。在接下来的内容中,我们将依次展开对SqlSessionTemplate的详细阐述,帮助读者逐步建立起对该知识点的整体认知。
// SqlSessionTemplate 概念介绍
/**
* SqlSessionTemplate 是 MyBatis 提供的一个线程安全的 SqlSession 实现类。
* 它封装了对数据库的操作,使得开发者可以更加方便地使用 MyBatis 进行数据库操作。
* SqlSessionTemplate 在 MyBatis 中扮演着至关重要的角色,它负责管理数据库连接、事务和 SQL 执行。
*/
// SqlSessionTemplate 的作用与意义
/**
* SqlSessionTemplate 的主要作用是简化 MyBatis 的使用,提高开发效率。
* 它通过封装数据库操作,使得开发者无需关心数据库连接的创建和销毁,以及事务的管理。
* 此外,SqlSessionTemplate 还提供了丰富的 API,方便开发者进行 SQL 执行、结果集处理等操作。
*/
// SqlSessionTemplate 的生命周期管理
/**
* SqlSessionTemplate 的生命周期与 Spring 容器绑定,其创建、销毁和回收都由 Spring 容器管理。
* 当 Spring 容器启动时,会创建一个 SqlSessionTemplate 实例;当 Spring 容器关闭时,会销毁该实例。
* 在 Spring 容器中,SqlSessionTemplate 实例会被注入到需要使用 MyBatis 的组件中,从而实现数据库操作。
*/
// SqlSessionTemplate 与 SqlSessionFactory 的关系
/**
* SqlSessionTemplate 与 SqlSessionFactory 之间存在着密切的关系。
* SqlSessionFactory 负责创建 SqlSessionTemplate 实例,而 SqlSessionTemplate 则负责执行数据库操作。
* 在 MyBatis 中,通常通过 SqlSessionFactoryBuilder 来构建 SqlSessionFactory,然后通过 SqlSessionFactory 创建 SqlSessionTemplate。
*/
// SqlSessionTemplate 的配置与使用
/**
* 在 Spring 容器中,可以通过配置文件或注解的方式配置 SqlSessionTemplate。
* 配置完成后,可以通过注入的方式将 SqlSessionTemplate 实例注入到需要使用 MyBatis 的组件中。
* 以下是一个简单的配置示例:
*
* <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
* <constructor-arg index="0" ref="sqlSessionFactory" />
* </bean>
*/
// SqlSessionTemplate 的线程安全性
/**
* SqlSessionTemplate 是线程安全的,这意味着它可以被多个线程共享使用。
* 这得益于其内部使用 ThreadLocal 来存储 SqlSession 实例,确保每个线程都有自己的 SqlSession 实例。
*/
// SqlSessionTemplate 的扩展与定制
/**
* SqlSessionTemplate 支持扩展和定制,开发者可以根据自己的需求进行修改。
* 例如,可以通过实现 SqlSessionInterceptor 接口来拦截 SQL 执行过程,或者通过实现 SqlSessionExecutor 接口来定制 SQL 执行策略。
*/
// SqlSessionTemplate 与数据库交互原理
/**
* SqlSessionTemplate 与数据库交互的过程如下:
* 1. 创建数据库连接;
* 2. 创建 SqlSession 实例;
* 3. 执行 SQL 语句;
* 4. 处理结果集;
* 5. 提交或回滚事务;
* 6. 关闭数据库连接和 SqlSession 实例。
*/
// SqlSessionTemplate 的性能优化
/**
* 为了提高 SqlSessionTemplate 的性能,可以采取以下措施:
* 1. 使用连接池来管理数据库连接;
* 2. 优化 SQL 语句,减少数据库访问次数;
* 3. 使用缓存来提高数据查询效率;
* 4. 适当调整事务隔离级别。
*/
| 特征/概念 | 描述 |
|---|---|
| SqlSessionTemplate 概念介绍 | MyBatis 提供的线程安全的 SqlSession 实现类,封装数据库操作,简化 MyBatis 使用 |
| 作用与意义 | 简化 MyBatis 使用,提高开发效率,封装数据库连接、事务和 SQL 执行 |
| 生命周期管理 | 与 Spring 容器绑定,由 Spring 容器管理创建、销毁和回收 |
| 与 SqlSessionFactory 的关系 | SqlSessionFactory 负责创建 SqlSessionTemplate 实例,SqlSessionTemplate 负责执行数据库操作 |
| 配置与使用 | 通过配置文件或注解配置,注入到需要使用 MyBatis 的组件中 |
| 线程安全性 | 线程安全,使用 ThreadLocal 存储 SqlSession 实例,确保每个线程都有自己的 SqlSession 实例 |
| 扩展与定制 | 支持扩展和定制,如实现 SqlSessionInterceptor 或 SqlSessionExecutor |
| 与数据库交互原理 | 创建数据库连接、SqlSession 实例,执行 SQL 语句,处理结果集,提交或回滚事务,关闭连接和 SqlSession 实例 |
| 性能优化 | 使用连接池,优化 SQL 语句,使用缓存,调整事务隔离级别 |
SqlSessionTemplate 作为 MyBatis 的核心组件之一,其设计理念在于简化数据库操作流程,降低开发难度。通过封装数据库连接、事务管理和 SQL 执行,SqlSessionTemplate 使得开发者能够更加专注于业务逻辑的实现,而无需过多关注底层细节。这种设计不仅提高了开发效率,也降低了出错概率,为构建稳定可靠的系统提供了有力保障。在实际应用中,SqlSessionTemplate 的线程安全性通过 ThreadLocal 实现了对每个线程独立 SqlSession 实例的保障,有效避免了并发访问时可能出现的资源冲突问题。此外,其扩展性和定制性也为开发者提供了更多灵活的配置选项,以满足不同场景下的需求。
// SqlSessionTemplate工作原理
/**
* SqlSessionTemplate是MyBatis中用于管理SqlSession的一个模板类,它封装了SqlSession的创建、使用和关闭过程。
* 当调用SqlSessionTemplate的方法时,它会根据需要创建一个新的SqlSession实例,执行数据库操作,并在操作完成后关闭SqlSession。
* 这种封装简化了SqlSession的使用,使得开发者无需手动管理SqlSession的生命周期。
*/
public class SqlSessionTemplate implements SqlSessionFactory {
private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType;
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
}
@Override
public SqlSession openSession() {
return openSessionFromDataSource(this.sqlSessionFactory, this.executorType, false);
}
@Override
public SqlSession openSession(ExecutorType execType) {
return openSessionFromDataSource(this.sqlSessionFactory, execType, false);
}
@Override
public SqlSession openSession(boolean autoCommit) {
return openSessionFromDataSource(this.sqlSessionFactory, this.executorType, autoCommit);
}
@Override
public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
return openSessionFromDataSource(this.sqlSessionFactory, execType, autoCommit);
}
private SqlSession openSessionFromDataSource(SqlSessionFactory sqlSessionFactory, ExecutorType execType, boolean autoCommit) {
// 创建SqlSession实例
SqlSession sqlSession = sqlSessionFactory.openSession(execType, autoCommit);
// 执行数据库操作
// ...
// 关闭SqlSession
sqlSession.close();
return sqlSession;
}
}
// SqlSessionTemplate与SqlSession的关系
/**
* SqlSessionTemplate是SqlSession的一个实现,它继承自SqlSessionFactory接口。
* SqlSessionTemplate通过封装SqlSessionFactory的方法,实现了对SqlSession的管理。
* SqlSessionTemplate与SqlSession的关系是:SqlSessionTemplate是SqlSession的实现,它封装了SqlSession的创建、使用和关闭过程。
*/
public class SqlSessionTemplate extends BaseSqlSession implements SqlSession {
// ...
}
// SqlSessionTemplate在MyBatis中的使用场景
/**
* SqlSessionTemplate在MyBatis中主要用于简化SqlSession的使用,以下是一些使用场景:
* 1. 在Spring框架中,通过SqlSessionTemplate可以方便地获取SqlSession实例,进行数据库操作。
* 2. 在非Spring框架中,也可以使用SqlSessionTemplate来管理SqlSession的生命周期。
* 3. 在进行批量操作时,可以使用SqlSessionTemplate来提高性能。
*/
public class MyBatisExample {
public void executeBatch() {
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
try {
// 执行批量操作
// ...
} finally {
sqlSessionTemplate.close();
}
}
}
// SqlSessionTemplate的生命周期管理
/**
* SqlSessionTemplate的生命周期由其所属的Spring容器管理。
* 当Spring容器启动时,会创建SqlSessionTemplate的实例,并在容器关闭时销毁实例。
* 在使用SqlSessionTemplate时,无需手动管理其生命周期,只需在操作完成后关闭SqlSession即可。
*/
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() {
// 创建SqlSessionFactory
// ...
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
// SqlSessionTemplate与数据库交互过程
/**
* 当使用SqlSessionTemplate进行数据库交互时,它会根据需要创建一个新的SqlSession实例,执行数据库操作,并在操作完成后关闭SqlSession。
* 以下是SqlSessionTemplate与数据库交互的过程:
* 1. 调用SqlSessionTemplate的方法,如selectOne、selectList等,传入相应的参数。
* 2. SqlSessionTemplate根据参数创建一个新的SqlSession实例。
* 3. 执行数据库操作,如查询、更新等。
* 4. 关闭SqlSession实例。
*/
public class MyBatisExample {
public void query() {
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
try {
// 查询数据
// ...
} finally {
sqlSessionTemplate.close();
}
}
}
// SqlSessionTemplate的配置与优化
/**
* 在使用SqlSessionTemplate时,可以对以下方面进行配置和优化:
* 1. 设置ExecutorType,如SIMPLE、BATCH等,以适应不同的数据库操作需求。
* 2. 设置事务管理器,如JDBC、MANAGED等,以实现事务管理。
* 3. 设置数据库连接池,如HikariCP、Druid等,以提高数据库连接性能。
*/
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() {
// 创建SqlSessionFactory,设置ExecutorType、事务管理器、数据库连接池等
// ...
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
// SqlSessionTemplate在事务管理中的应用
/**
* 在使用SqlSessionTemplate进行事务管理时,可以通过以下方式实现:
* 1. 使用SqlSessionTemplate的openSession方法创建SqlSession实例,并设置autoCommit为false。
* 2. 在SqlSession实例中执行数据库操作。
* 3. 使用SqlSessionTemplate的commit方法提交事务。
* 4. 使用SqlSessionTemplate的rollback方法回滚事务。
*/
public class MyBatisExample {
public void transaction() {
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
try {
SqlSession sqlSession = sqlSessionTemplate.openSession(false);
try {
// 执行数据库操作
// ...
sqlSession.commit();
} catch (Exception e) {
sqlSession.rollback();
throw e;
} finally {
sqlSession.close();
}
} finally {
sqlSessionTemplate.close();
}
}
}
// SqlSessionTemplate与MyBatis插件集成
/**
* 在使用SqlSessionTemplate时,可以将其与MyBatis插件集成,以实现自定义功能。
* 例如,可以创建一个MyBatis插件,用于拦截数据库操作,实现日志记录、性能监控等功能。
*/
public class MyBatisPlugin implements Plugin {
// ...
}
// SqlSessionTemplate与Spring框架的整合
/**
* 在Spring框架中,可以通过以下方式整合SqlSessionTemplate:
* 1. 创建SqlSessionFactory和SqlSessionTemplate的Bean。
* 2. 在Service层注入SqlSessionTemplate,进行数据库操作。
*/
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() {
// 创建SqlSessionFactory
// ...
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public SomeService someService(SqlSessionTemplate sqlSessionTemplate) {
return new SomeService(sqlSessionTemplate);
}
}
| 特征 | SqlSessionTemplate | SqlSession | 关系 |
|---|---|---|---|
| 实现接口 | SqlSessionFactory | SqlSession | SqlSessionTemplate实现了SqlSessionFactory接口,封装了SqlSession的创建、使用和关闭过程 |
| 创建方式 | 通过构造函数传入SqlSessionFactory | 通过SqlSessionFactory.openSession()方法创建 | SqlSessionTemplate通过传入的SqlSessionFactory创建SqlSession实例 |
| 使用方式 | 提供多种openSession方法 | 提供多种方法进行数据库操作,如selectOne、selectList等 | SqlSessionTemplate封装了SqlSession的方法,简化了数据库操作 |
| 生命周期管理 | 由Spring容器管理 | 由调用者管理 | SqlSessionTemplate的生命周期由Spring容器管理,无需手动关闭 |
| 事务管理 | 通过SqlSession进行 | 通过SqlSession进行 | SqlSessionTemplate使用SqlSession进行事务管理 |
| 与数据库交互过程 | 创建SqlSession实例,执行操作,关闭SqlSession | 创建SqlSession实例,执行操作,关闭SqlSession | SqlSessionTemplate与数据库交互过程与SqlSession相同 |
| 配置与优化 | 设置ExecutorType、事务管理器、数据库连接池等 | 无需配置,由SqlSessionTemplate管理 | SqlSessionTemplate可以配置和优化数据库操作 |
| 事务管理应用 | 使用commit、rollback方法 | 使用commit、rollback方法 | SqlSessionTemplate与SqlSession在事务管理中的应用相同 |
| 与MyBatis插件集成 | 通过实现Plugin接口 | 无需集成插件 | SqlSessionTemplate可以与MyBatis插件集成,实现自定义功能 |
| 与Spring框架整合 | 通过创建Bean进行整合 | 无需与Spring整合 | SqlSessionTemplate可以与Spring框架整合,简化数据库操作 |
SqlSessionTemplate在实现数据库操作时,不仅简化了数据库操作流程,还提供了强大的事务管理功能。通过封装SqlSession的创建、使用和关闭过程,SqlSessionTemplate使得开发者无需关注底层的数据库连接细节,从而提高了开发效率。同时,SqlSessionTemplate的生命周期由Spring容器管理,进一步降低了代码的复杂性。在事务管理方面,SqlSessionTemplate与SqlSession一样,通过commit和rollback方法进行事务控制,确保了数据的一致性和完整性。此外,SqlSessionTemplate还可以与MyBatis插件集成,为开发者提供更多定制化的功能。总的来说,SqlSessionTemplate是Spring框架中处理数据库操作的一个强大工具,它不仅简化了数据库操作流程,还提高了代码的可维护性和扩展性。
// SqlSessionTemplate工作原理
// SqlSessionTemplate是MyBatis框架中用于管理数据库会话的一个类,它封装了SqlSession的创建、关闭和事务管理等功能。
// 当调用SqlSessionTemplate的方法时,它会根据需要创建或获取一个SqlSession实例,执行SQL操作,并在操作完成后关闭SqlSession。
// 与SqlSession的区别
// SqlSessionTemplate与SqlSession的主要区别在于,SqlSessionTemplate是线程安全的,而SqlSession是非线程安全的。
// SqlSessionTemplate内部维护了一个ThreadLocal变量,用于存储当前线程的SqlSession实例,从而实现线程安全。
// 生命周期管理
// SqlSessionTemplate的生命周期由Spring容器管理,当Spring容器启动时,会创建SqlSessionTemplate实例;
// 当Spring容器关闭时,会关闭所有活跃的SqlSessionTemplate实例。
// 缓存管理
// SqlSessionTemplate支持MyBatis的二级缓存,可以通过配置文件或注解来开启和配置缓存。
// 执行SQL操作
// 通过SqlSessionTemplate的getMapper方法,可以获取到Mapper接口的代理实现,并通过代理实现来执行SQL操作。
// 事务管理
// SqlSessionTemplate支持声明式事务管理,可以通过Spring的声明式事务管理器来管理事务。
// 与Spring框架的集成
// SqlSessionTemplate与Spring框架集成,可以通过Spring的声明式事务管理器来管理事务,也可以通过Spring的AOP功能来拦截SqlSessionTemplate的方法调用。
// 性能优化
// SqlSessionTemplate支持懒加载,即只有在需要时才创建SqlSession实例,从而提高性能。
// 应用场景
// SqlSessionTemplate适用于需要线程安全、支持缓存、支持事务管理的场景,如Spring MVC的Controller层。
// 代码示例
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() throws IOException {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(new ClassPathResource("mybatis-config.xml"));
return sqlSessionFactory;
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
| 特性/概念 | 说明 |
|---|---|
| SqlSessionTemplate工作原理 | 封装了SqlSession的创建、关闭和事务管理等功能,根据需要创建或获取SqlSession实例,执行SQL操作,并在操作完成后关闭SqlSession。 |
| 与SqlSession的区别 | SqlSessionTemplate是线程安全的,内部维护ThreadLocal变量存储当前线程的SqlSession实例;SqlSession是非线程安全的。 |
| 生命周期管理 | 由Spring容器管理,启动时创建实例,关闭时关闭所有活跃实例。 |
| 缓存管理 | 支持MyBatis的二级缓存,可通过配置文件或注解开启和配置缓存。 |
| 执行SQL操作 | 通过getMapper方法获取Mapper接口的代理实现,执行SQL操作。 |
| 事务管理 | 支持声明式事务管理,通过Spring的声明式事务管理器管理事务。 |
| 与Spring框架的集成 | 与Spring框架集成,通过声明式事务管理器或AOP功能管理事务。 |
| 性能优化 | 支持懒加载,即需要时才创建SqlSession实例,提高性能。 |
| 应用场景 | 适用于需要线程安全、支持缓存、支持事务管理的场景,如Spring MVC的Controller层。 |
| 代码示例 | 示例代码展示了如何通过Spring配置类创建SqlSessionFactory和SqlSessionTemplate实例。 |
SqlSessionTemplate的设计理念在于简化MyBatis的使用过程,它通过封装底层的SqlSession操作,使得开发者无需关心SqlSession的创建和销毁,从而降低代码复杂度。这种设计使得SqlSessionTemplate在保证线程安全的同时,也提高了代码的可维护性和可读性。在实际应用中,SqlSessionTemplate能够与Spring框架无缝集成,通过声明式事务管理,简化了事务处理的复杂性,使得开发者可以更加专注于业务逻辑的实现。
🍊 MyBatis核心知识点之SqlSessionTemplate:创建与使用
在当今的软件开发领域,MyBatis 作为一款优秀的持久层框架,以其简洁的配置和强大的功能,被广泛应用于各种项目中。然而,在实际开发过程中,如何高效地创建和使用 SqlSessionTemplate 是一个关键问题。SqlSessionTemplate 作为 MyBatis 的核心组件之一,负责管理数据库的会话,是执行 SQL 语句和获取数据库对象的主要途径。下面,我们将深入探讨 MyBatis 核心知识点之 SqlSessionTemplate 的创建与使用。
在传统的 MyBatis 应用中,每次执行数据库操作都需要手动创建和关闭 SqlSession,这不仅增加了代码的复杂性,而且容易导致资源泄漏。为了解决这个问题,MyBatis 提供了 SqlSessionTemplate,它是一个线程安全的单例类,可以简化 SqlSession 的创建和使用过程。
首先,介绍 SqlSessionTemplate 的创建方式。SqlSessionTemplate 通常在 Spring 容器中创建,通过注入 SqlSessionFactory 来实现。SqlSessionFactory 是 MyBatis 的核心接口,负责创建 SqlSession。在 Spring 配置文件中,我们可以通过配置 SqlSessionFactoryBean 来创建 SqlSessionFactory,然后将其注入到 SqlSessionTemplate 中。
接下来,我们将详细讲解 SqlSessionTemplate 的使用步骤。首先,在 Spring 容器中注入 SqlSessionTemplate 实例。然后,通过调用其提供的各种方法来执行 SQL 语句,如 selectOne、selectList、update 和 delete 等。使用完毕后,SqlSessionTemplate 会自动关闭 SqlSession,从而避免资源泄漏。
在使用 SqlSessionTemplate 时,需要注意以下几点。首先,由于 SqlSessionTemplate 是线程安全的,因此在一个线程中只能有一个 SqlSessionTemplate 实例。其次,在使用 SqlSessionTemplate 时,应避免在多线程环境中直接操作数据库,以免造成数据不一致。最后,合理配置事务管理,确保数据的一致性和完整性。
总之,SqlSessionTemplate 作为 MyBatis 的核心组件,在简化数据库操作、提高开发效率方面具有重要意义。通过本文的介绍,读者可以了解到 SqlSessionTemplate 的创建与使用方法,以及在使用过程中需要注意的事项。在后续内容中,我们将进一步探讨 SqlSessionTemplate 的创建方式、使用步骤和注意事项,帮助读者全面掌握 MyBatis 的核心知识点。
// SqlSessionTemplate类概述
/**
* SqlSessionTemplate是MyBatis框架中用于管理SqlSession的一个类,它封装了SqlSession的创建、使用和关闭过程。
* SqlSession是MyBatis中用于执行SQL语句和获取数据库对象的一个接口,它代表了与数据库的会话。
* SqlSessionTemplate通过模板方法模式,简化了SqlSession的使用,使得开发者可以更加专注于业务逻辑的实现。
*/
// SqlSessionTemplate创建方式
/**
* SqlSessionTemplate可以通过以下几种方式创建:
* 1. 通过SqlSessionFactory直接创建
* 2. 通过Spring容器自动创建
* 3. 通过自定义工厂类创建
*/
// 构造函数参数解析
/**
* SqlSessionTemplate的构造函数接受一个SqlSessionFactory对象作为参数,该对象用于创建SqlSession。
* SqlSessionFactory是MyBatis中用于创建SqlSession的一个接口,它封装了SqlSessionFactoryBuilder的创建过程。
*/
// SqlSessionFactory获取方式
/**
* SqlSessionFactory可以通过以下方式获取:
* 1. 通过MyBatis的配置文件(mybatis-config.xml)创建
* 2. 通过XML配置文件和扫描包的方式创建
* 3. 通过注解的方式创建
*/
// Spring容器中配置与使用
/**
* 在Spring容器中,可以通过以下方式配置和使用SqlSessionTemplate:
* 1. 通过XML配置文件配置SqlSessionFactory,然后通过SqlSessionFactory创建SqlSessionTemplate
* 2. 通过注解的方式配置SqlSessionFactory,然后通过SqlSessionFactory创建SqlSessionTemplate
*/
// 与MyBatis配置文件的关系
/**
* SqlSessionTemplate与MyBatis配置文件的关系是,SqlSessionTemplate的创建依赖于MyBatis配置文件中的配置信息。
* MyBatis配置文件中包含了数据库连接信息、事务管理器、映射文件等信息,这些信息被用于创建SqlSessionFactory,
* 而SqlSessionFactory又用于创建SqlSessionTemplate。
*/
// 与数据库连接池的结合
/**
* SqlSessionTemplate可以与数据库连接池结合使用,以实现数据库连接的复用和优化。
* 通过配置数据库连接池,可以减少数据库连接的创建和销毁次数,提高应用程序的性能。
*/
// 与事务管理的关联
/**
* SqlSessionTemplate与事务管理紧密相关,它提供了事务管理的方法,如提交事务、回滚事务等。
* 通过SqlSessionTemplate,可以方便地管理事务,确保数据的一致性和完整性。
*/
// 与Spring AOP的结合
/**
* SqlSessionTemplate可以与Spring AOP结合使用,以实现事务的声明式管理。
* 通过Spring AOP,可以在方法执行前后自动进行事务的提交和回滚,简化了事务管理的代码。
*/
// 与自定义数据库操作的结合
/**
* SqlSessionTemplate可以与自定义数据库操作结合使用,以实现更灵活的数据库操作。
* 通过自定义数据库操作,可以扩展SqlSessionTemplate的功能,满足特定的业务需求。
*/
| 特性/概念 | 描述 |
|---|---|
| SqlSessionTemplate概述 | MyBatis框架中用于管理SqlSession的类,简化SqlSession的使用,专注于业务逻辑实现 |
| 创建方式 | 1. 通过SqlSessionFactory直接创建<br>2. 通过Spring容器自动创建<br>3. 通过自定义工厂类创建 |
| 构造函数参数 | 接受一个SqlSessionFactory对象作为参数,用于创建SqlSession |
| SqlSessionFactory获取 | 1. 通过MyBatis配置文件创建<br>2. 通过XML配置文件和扫描包的方式创建<br>3. 通过注解的方式创建 |
| Spring容器配置 | 1. 通过XML配置文件配置SqlSessionFactory,然后创建SqlSessionTemplate<br>2. 通过注解配置SqlSessionFactory,然后创建SqlSessionTemplate |
| 与MyBatis配置文件 | SqlSessionTemplate的创建依赖于MyBatis配置文件中的配置信息,如数据库连接、事务管理、映射文件等 |
| 与数据库连接池 | 结合数据库连接池,实现数据库连接的复用和优化,提高应用程序性能 |
| 与事务管理 | 提供事务管理方法,如提交、回滚,确保数据一致性和完整性 |
| 与Spring AOP | 与Spring AOP结合,实现事务的声明式管理,简化事务管理代码 |
| 与自定义数据库操作 | 与自定义数据库操作结合,扩展SqlSessionTemplate功能,满足特定业务需求 |
SqlSessionTemplate在MyBatis框架中扮演着至关重要的角色,它不仅简化了SqlSession的使用,还使得业务逻辑的实现更加专注。通过多种创建方式,如直接创建、Spring容器自动创建或自定义工厂类创建,SqlSessionTemplate的灵活性和可配置性得到了充分体现。在Spring容器配置中,无论是通过XML配置文件还是注解配置,SqlSessionTemplate都能与MyBatis配置文件紧密协作,确保数据库连接、事务管理、映射文件等配置信息的正确应用。此外,结合数据库连接池和事务管理,SqlSessionTemplate在提高应用程序性能和确保数据一致性方面发挥着重要作用。与Spring AOP的结合,更是实现了事务的声明式管理,极大地简化了事务管理代码。而对于特定业务需求,通过自定义数据库操作,SqlSessionTemplate的功能得到了进一步扩展。
// 创建SqlSessionTemplate实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
// 使用SqlSessionTemplate执行查询
List<User> users = sqlSessionTemplate.selectList("com.example.mapper.UserMapper.selectUsers");
for (User user : users) {
System.out.println("User ID: " + user.getId() + ", Name: " + user.getName());
}
// 使用SqlSessionTemplate执行更新
int updateCount = sqlSessionTemplate.update("com.example.mapper.UserMapper.updateUser", new User(1, "Alice"));
System.out.println("Updated rows: " + updateCount);
// 使用SqlSessionTemplate管理事务
try {
sqlSessionTemplate.beginTransaction();
sqlSessionTemplate.update("com.example.mapper.UserMapper.insertUser", new User(2, "Bob"));
sqlSessionTemplate.commit();
} catch (Exception e) {
sqlSessionTemplate.rollback();
e.printStackTrace();
}
// SqlSessionTemplate与数据库连接管理
Connection connection = sqlSessionTemplate.getConnection();
try {
// 使用数据库连接执行其他操作
} finally {
connection.close();
}
// SqlSessionTemplate与MyBatis配置
Properties properties = new Properties();
properties.setProperty("mybatis.configuration.cacheEnabled", "false");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"), properties);
sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
// SqlSessionTemplate与Mapper接口绑定
UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
List<User> users2 = userMapper.selectUsers();
for (User user : users2) {
System.out.println("User ID: " + user.getId() + ", Name: " + user.getName());
}
// SqlSessionTemplate的最佳实践与注意事项
// 1. 使用try-with-resources语句确保SqlSessionTemplate关闭
// 2. 避免在SqlSessionTemplate中直接操作数据库连接,而是通过Mapper接口进行操作
// 3. 在多线程环境下,确保每个线程使用自己的SqlSessionTemplate实例
// 4. 在配置文件中设置合理的缓存策略,提高查询效率
// 5. 在执行更新操作时,确保事务的正确性,避免数据不一致
| 功能/操作 | 代码示例 | 说明 |
|---|---|---|
| 创建SqlSessionTemplate实例 | SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));<br>SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory); |
使用SqlSessionFactoryBuilder构建SqlSessionFactory,然后创建SqlSessionTemplate实例。 |
| 使用SqlSessionTemplate执行查询 | List<User> users = sqlSessionTemplate.selectList("com.example.mapper.UserMapper.selectUsers"); |
通过SqlSessionTemplate的selectList方法执行查询,返回查询结果列表。 |
| 使用SqlSessionTemplate执行更新 | int updateCount = sqlSessionTemplate.update("com.example.mapper.UserMapper.updateUser", new User(1, "Alice")); |
通过SqlSessionTemplate的update方法执行更新操作,返回受影响的行数。 |
| 使用SqlSessionTemplate管理事务 | try { sqlSessionTemplate.beginTransaction(); sqlSessionTemplate.update("com.example.mapper.UserMapper.insertUser", new User(2, "Bob")); sqlSessionTemplate.commit(); } catch (Exception e) { sqlSessionTemplate.rollback(); e.printStackTrace(); } |
使用try-catch块管理事务,成功则提交,失败则回滚。 |
| SqlSessionTemplate与数据库连接管理 | Connection connection = sqlSessionTemplate.getConnection();<br>try { // 使用数据库连接执行其他操作 } finally { connection.close(); } |
通过SqlSessionTemplate获取数据库连接,并在finally块中关闭连接。 |
| SqlSessionTemplate与MyBatis配置 | Properties properties = new Properties(); properties.setProperty("mybatis.configuration.cacheEnabled", "false");<br>sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"), properties);<br>sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory); |
设置MyBatis配置属性,并重新构建SqlSessionFactory和SqlSessionTemplate实例。 |
| SqlSessionTemplate与Mapper接口绑定 | UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class); List<User> users2 = userMapper.selectUsers(); |
通过SqlSessionTemplate获取Mapper接口的代理实现,并执行查询操作。 |
| SqlSessionTemplate的最佳实践与注意事项 | - 使用try-with-resources语句确保SqlSessionTemplate关闭<br>- 避免在SqlSessionTemplate中直接操作数据库连接,而是通过Mapper接口进行操作<br>- 在多线程环境下,确保每个线程使用自己的SqlSessionTemplate实例<br>- 在配置文件中设置合理的缓存策略,提高查询效率<br>- 在执行更新操作时,确保事务的正确性,避免数据不一致 | 列出了使用SqlSessionTemplate时的一些最佳实践和注意事项。 |
在实际应用中,SqlSessionTemplate的创建和配置是一个细致的过程。例如,在配置文件中设置合理的缓存策略,如关闭缓存以提高查询效率,或者在多线程环境下确保每个线程使用自己的SqlSessionTemplate实例以避免线程安全问题。此外,通过Mapper接口进行数据库操作,而非直接操作数据库连接,可以更好地封装业务逻辑,提高代码的可读性和可维护性。在执行更新操作时,正确的事务管理至关重要,以避免数据不一致和潜在的数据丢失风险。
// SqlSessionTemplate工作原理
// SqlSessionTemplate是MyBatis中用于管理数据库会话的模板类,它封装了SqlSession的创建、使用和关闭过程。
// 当调用SqlSessionTemplate的方法时,它会根据当前线程的ThreadLocal变量获取或创建一个新的SqlSession实例。
// 这个过程保证了每个线程都有自己的SqlSession实例,避免了线程安全问题。
// SqlSessionTemplate生命周期管理
// SqlSessionTemplate的生命周期与Spring容器绑定,当Spring容器启动时,它会创建SqlSessionTemplate实例。
// 当Spring容器关闭时,它会关闭所有活跃的SqlSession实例,释放数据库连接资源。
// SqlSessionTemplate与数据库连接管理
// SqlSessionTemplate内部使用SqlSessionFactory来管理数据库连接。
// SqlSessionFactory负责创建SqlSession实例,并管理数据库连接的生命周期。
// SqlSessionTemplate事务管理
// SqlSessionTemplate支持声明式事务管理,通过Spring的声明式事务管理器来控制事务的提交和回滚。
// 当调用SqlSessionTemplate的方法时,它会自动将事务提交或回滚。
// SqlSessionTemplate与MyBatis配置
// SqlSessionTemplate的配置信息来自于MyBatis的配置文件或注解。
// 配置信息包括数据库连接信息、事务管理器、映射文件等。
// SqlSessionTemplate与Mapper接口绑定
// SqlSessionTemplate通过Mapper接口与MyBatis的映射文件进行绑定。
// 当调用Mapper接口的方法时,MyBatis会根据映射文件生成对应的SQL语句,并执行数据库操作。
// SqlSessionTemplate与数据库操作注意事项
// 使用SqlSessionTemplate进行数据库操作时,需要注意以下几点:
// 1. 避免在SqlSessionTemplate的方法中直接操作数据库连接,应由SqlSessionFactory负责管理。
// 2. 避免在SqlSessionTemplate的方法中直接提交或回滚事务,应由Spring的事务管理器负责。
// 3. 避免在SqlSessionTemplate的方法中直接关闭SqlSession,应由SqlSessionFactory负责。
// SqlSessionTemplate与线程安全问题
// SqlSessionTemplate内部使用ThreadLocal变量来存储当前线程的SqlSession实例,保证了线程安全。
// 但是,当多个线程同时访问同一个SqlSessionTemplate实例时,需要注意线程安全问题。
// SqlSessionTemplate与性能优化
// 为了提高SqlSessionTemplate的性能,可以采取以下措施:
// 1. 使用连接池来管理数据库连接,减少连接创建和销毁的开销。
// 2. 使用缓存来存储常用的SQL语句和结果集,减少数据库访问次数。
// 3. 使用批处理来执行多个SQL语句,减少网络传输和数据库操作的开销。
// SqlSessionTemplate与异常处理
// 当使用SqlSessionTemplate进行数据库操作时,可能会抛出各种异常。
// 需要正确处理这些异常,例如记录异常信息、回滚事务等。
// 示例代码:使用SqlSessionTemplate进行数据库操作
public class MyBatisExample {
// 获取SqlSessionTemplate实例
private SqlSessionTemplate sqlSessionTemplate;
// 构造函数
public MyBatisExample(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
// 查询数据
public List<User> findUsers() {
// 获取Mapper接口
UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
// 查询数据
return userMapper.findUsers();
}
// 插入数据
public void insertUser(User user) {
// 获取Mapper接口
UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
// 插入数据
userMapper.insertUser(user);
}
// 更新数据
public void updateUser(User user) {
// 获取Mapper接口
UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
// 更新数据
userMapper.updateUser(user);
}
// 删除数据
public void deleteUser(Integer id) {
// 获取Mapper接口
UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
// 删除数据
userMapper.deleteUser(id);
}
}
| 特性/概念 | 描述 |
|---|---|
| SqlSessionTemplate工作原理 | 封装SqlSession的创建、使用和关闭过程,确保每个线程都有自己的SqlSession实例,避免线程安全问题 |
| SqlSessionTemplate生命周期管理 | 与Spring容器绑定,Spring容器启动时创建实例,关闭时关闭所有活跃的SqlSession实例,释放数据库连接资源 |
| SqlSessionTemplate与数据库连接管理 | 使用SqlSessionFactory管理数据库连接,创建SqlSession实例,并管理数据库连接的生命周期 |
| SqlSessionTemplate事务管理 | 支持声明式事务管理,通过Spring的事务管理器控制事务的提交和回滚 |
| SqlSessionTemplate与MyBatis配置 | 配置信息来自MyBatis配置文件或注解,包括数据库连接信息、事务管理器、映射文件等 |
| SqlSessionTemplate与Mapper接口绑定 | 通过Mapper接口与MyBatis映射文件绑定,执行数据库操作 |
| SqlSessionTemplate与数据库操作注意事项 | 避免直接操作数据库连接、提交或回滚事务、关闭SqlSession,由相应的管理器负责 |
| SqlSessionTemplate与线程安全问题 | 使用ThreadLocal变量存储当前线程的SqlSession实例,保证线程安全,但需注意多线程访问同一实例时的线程安全问题 |
| SqlSessionTemplate与性能优化 | 使用连接池、缓存、批处理等措施提高性能 |
| SqlSessionTemplate与异常处理 | 正确处理数据库操作中可能抛出的异常,如记录异常信息、回滚事务等 |
| 示例代码使用 | 通过SqlSessionTemplate实例获取Mapper接口,执行数据库查询、插入、更新、删除操作 |
SqlSessionTemplate作为MyBatis与Spring框架结合的关键组件,其设计理念在于简化数据库操作流程,提高开发效率。通过封装SqlSession的生命周期,SqlSessionTemplate确保了数据库连接的安全和高效使用。在实际应用中,它不仅简化了事务管理,还通过ThreadLocal机制保证了线程安全。然而,在使用过程中,开发者应避免直接操作数据库连接,而是依赖SqlSessionTemplate提供的接口进行操作,以充分利用其性能优化特性,如连接池、缓存和批处理等。此外,合理处理异常也是确保应用稳定性的关键。
🍊 MyBatis核心知识点之SqlSessionTemplate:生命周期管理
在当今的Java应用开发中,MyBatis框架因其简洁的CRUD操作和灵活的映射配置而受到广泛的应用。然而,在实际开发过程中,我们常常会遇到关于MyBatis核心组件SqlSessionTemplate的生命周期管理问题。例如,在一个大型项目中,若未能妥善管理SqlSessionTemplate的生命周期,可能会导致资源泄漏、性能下降甚至系统崩溃。
SqlSessionTemplate是MyBatis框架中用于管理数据库会话的核心类,它封装了SqlSession的创建、使用和关闭过程。在MyBatis中,SqlSession负责执行SQL语句、管理事务以及获取数据库映射器等操作。因此,正确地管理SqlSessionTemplate的生命周期对于确保应用程序的稳定性和性能至关重要。
首先,我们需要了解SqlSessionTemplate的生命周期。SqlSessionTemplate在创建时,会初始化一个SqlSessionFactory,该工厂负责创建SqlSession。在应用程序运行期间,SqlSessionTemplate会根据需要创建和关闭SqlSession,以执行数据库操作。然而,如果SqlSessionTemplate未被正确关闭,那么它所管理的数据库连接和资源将无法被释放,从而可能导致资源泄漏。
接下来,我们将探讨如何关闭和回收SqlSessionTemplate。关闭SqlSessionTemplate意味着释放其管理的所有资源,包括数据库连接、事务管理等。在应用程序关闭或不再需要SqlSessionTemplate时,应当显式地关闭它,以避免资源泄漏。此外,异常处理也是管理SqlSessionTemplate生命周期的一个重要环节。在执行数据库操作时,可能会遇到各种异常,如SQL异常、连接异常等。合理地处理这些异常,可以确保应用程序的健壮性和稳定性。
在本文的后续部分,我们将详细讨论SqlSessionTemplate的生命周期管理,包括其创建、使用、关闭和异常处理等方面。通过深入理解这些知识点,读者将能够更好地掌握MyBatis框架,并在实际项目中避免因生命周期管理不当而引发的问题。这不仅有助于提高应用程序的性能,还能确保系统的稳定运行。
// SqlSessionTemplate创建与销毁过程
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
this(sqlSessionFactory, false);
}
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, boolean openSessionFromPool) {
this(sqlSessionFactory, openSessionFromPool, false);
}
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, boolean openSessionFromPool, boolean executeBatch) {
this.sqlSessionFactory = sqlSessionFactory;
this.openSessionFromPool = openSessionFromPool;
this.executeBatch = executeBatch;
this.executorType = sqlSessionFactory.getExecutorType();
this.config = sqlSessionFactory.getConfiguration().clone();
this.interceptorChain = sqlSessionFactory.getConfiguration().getInterceptorChain().clone();
this.localCacheScope = sqlSessionFactory.getConfiguration().getLocalCacheScope();
this.localCacheEnabled = sqlSessionFactory.getConfiguration().isLocalCacheEnabled();
this.lazyLoadEnabled = sqlSessionFactory.getConfiguration().isLazyLoadEnabled();
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;
this.defaultExecutorType = executorType;

最低0.47元/天 解锁文章
201

被折叠的 条评论
为什么被折叠?



