MyBatis SqlSessionTemplate 深度解析

📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)(进阶篇)、(架构篇)、《解密程序员的思维密码——沟通、演讲、思考的实践》作者、清华大学出版社签约作家、Java领域优质创作者、优快云博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。

📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。

📙不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

Java程序员廖志伟

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

优快云

🍊 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;
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值