MyBatis核心组件以及其作用域、生命周期

一、核心组件

  • SqlSessionFactoryBuilder(构造器):它会根据配置或者代码来生成 SqlSessionFactory,采用的是分步构建的 Builder 模式。
  • SqlSessionFactory(工厂接口):依靠它来生成 SqlSession,使用的是工厂模式。
  • SqlSession(会话):一个既可以发送 SQL 执行返回结果,也可以获取 Mapper 的接口。在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是 MyBatis 提供的 SQL Mapper 接口编程技术,它能提高代码的可读性和可维护性。
  • SQL Mapper(映射器):MyBatis 新设计存在的组件,它由一个 Java 接口和 XML 文件(或注解)构成,需要给出对应的 SQL 和映射规则。它负责发送 SQL 去执行,并返回结果。

请添加图片描述

1.1 SqlSessionFactory

SqlSessionFactory 是一个接口,在 MyBatis 中它存在两个实现类:SqlSessionManager 和 DefaultSqlSessionFactory。 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的,而 SqlSessionFactory 唯一的作用就是生产 MyBatis 的核心接口对象 SqlSession,所以它的责任是唯一的,所以我们往往会采用单例模式处理它。

使用 MyBatis 首先是使用配置或者代码去生产SqlSessionFactory,而 MyBatis 提供了构造器 SqlSessionFactoryBuilder,通过其build()方法创建SqlSessionFactory。通过代码生成SqlSessionFactory和通过XML配置文件生成SqlSessionFactory这两种方式,都是调用了bulid()方法,但是build()利用了Java的重载技术,两者调用的build()不是同一个;虽然调用的build()方法不是同一个,但是内部逻辑都是一样的:加载基础配置文件的信息,解析后的配置信息会形成相应的对象并保存到 Configuration 对象通过 Configuration 类对象构建整个 MyBatis 的上下文,最后返回SqlSessionFactory对象。

推荐采用 XML 的形式,因为代码的方式在需要修改的时候会比较麻烦。

1.1.1 使用XML构建SqlSessionFactory(重点)

在 MyBatis 中的 XML 分为两类,一类是基础配置文件,通常只有一个,主要是配置一些最基本的上下文参数和运行环境;另一类是映射文件,它可以配置映射关系、SQL、参数等信息。此处讲解的是基础配置文件,该文件一般放在项目的资源根目录下。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases><!--别名-->
        <typeAliases alias="user" type="com.mybatis.po.User"/>
    </typeAliases>
    <!-- 数据库环境 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用JDBC的事务管理 -->
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <!-- MySQL数据库驱动 -->
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <!-- 连接数据库的URL -->
                <property name="url"
                    value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="1128" />
            </dataSource>
        </environment>
    </environments>
    <!-- 将mapper文件加入到配置文件中 -->
    <mappers>
        <mapper resource="com/mybatis/mapper/UserMapper.xml" />
    </mappers>
</configuration>
1. <typeAlias> 元素定义了一个别名 user,它代表着 com.mybatis.po.User 这个类。这样定义后,在 MyBatis 上下文中就可以使用别名去代替全限定名了。
2. <environments></environments>标签内可以定义多个<environment>标签,然后通过default属性选定默认环境
3. <environment> 元素的定义,这里描述的是数据库。它里面的 <transactionManager> 元素是配置事务管理器,这里采用的是 MyBatisJDBC 管理器方式。
4. <dataSource> 元素配置数据库,其中属性 type="POOLED" 代表采用 MyBatis 内部提供的连接池方式,最后定义一些关于 JDBC 的属性信息。
5. <mapper> 元素代表引入的那些映射器,在谈到映射器时会详细讨论它。

有了基础配置文件,就可以创建SqlSessionFactory对象:

SqlSessionFactory factory = null;
String resource = "mybatis-config.xml";
InputStream is;
try {
    InputStream is = Resources.getResourceAsStream(resource);
    factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
    e.printStackTrace();
}
1.1.2 使用代码创建 SqlSessionFactory

虽然不推荐使用这种方式,但是我们还是谈谈如何使用它

// 数据库连接池信息
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword ("1128");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
dataSource.setDefeultAutoCommit(false);
// 采用 MyBatis 的 JDBC 事务方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment ("development", transactionFactory, dataSource);
// 创建 Configuration 对象
Configuration configuration = new Configuration(environment);
// 注册一个 MyBatis 上下文别名
configuration.getTypeAliasRegistry().registerAlias("role", Role.class);
// 加入一个映射器
configuration.addMapper(RoleMapper.class);
//使用 SqlSessionFactoryBuilder 构建 SqlSessionFactory
SqlSessionFactory SqlSessionFactory =
new SqlSessionFactoryBuilder().build(configuration);
return SqlSessionFactory;

除非有特殊的需要,比如在配置文件中,需要配置加密过的数据库用户名和密码,需要我们在生成 SqlSessionFactory 前解密为明文的时候,才会考虑使用这样的方式。

1.2 SqlSession

在 MyBatis 中,SqlSession 是其核心接口。在 MyBatis 中有两个实现类,DefaultSqlSessionSqlSessionManager

DefaultSqlSession 是单线程使用的,而 SqlSessionManager 在多线程环境下使用。

SqlSession 的作用类似于一个 JDBC 中的 Connection 对象,代表着一个连接资源的启用。具体而言,它的作用有 3 个:

  • 获取 Mapper 接口。
  • 发送 SQL 给数据库。
  • 控制数据库事务。
SqlSession sqlSession = SqlSessionFactory.openSession();

SqlSession 只是一个门面接口,它有很多方法,可以直接发送 SQL。它就好像一家软件公司的商务人员,是一个门面,而实际干活的是软件工程师。在 MyBatis 中,真正干活的是 Executor,我们会在底层看到它。

SqlSession对象中常用方法有:

<T> T selectOne(String statement)
   - 参数statement是在配置文件中定义的<select>元素的id。
   - 该方法返回执行SQL语句查询结果的一个泛型对象。
  
<T> T selectOne(String statement, Object parameter)
   - 参数statement是在配置文件中定义的<select>元素的id,
   - parameter是查询所需的参数。该方法返回执行SQL语句查询结果的一个泛型对象。
  
<E> List<E> selectList(String statement)
   - 参数statement是在配置文件中定义的<select>元素的id。
   - 该方法返回执行SQL语句查询结果的泛型对象的集合。
  
<E> List<E> selectList(String statement, Object parameter)
   statement: 在配置文件中定义的<select>元素的id,
   parameter: 查询所需的参数,
   rOWBounds: 用于分页的参数对象
     该方法返回执行SQL语句查询结果的泛型对象的集合。
  
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds, Resulthandler handler);
    statement: 在配置文件中定义的<select>元素的id,
    parameter: 查询所需的参数,
    handler: 用于处理查询返回的复杂结果集,通常用于多表查询。

1.3 SQL MApper(映射器)

映射器中的接口不能直接运行。MyBatis 运用了动态代理技术使得接口能运行起来,入门阶段只要懂得 MyBatis 会为这个接口生成一个代理对象,代理对象会去处理相关的逻辑即可。

映射器是一些绑定映射语句的接口。映射器接口的实例是从 SqlSession 中获得的,将 SQL 查询到的结果映射为一个 POJO,或者将 POJO 的数据插入到数据库中,并定义一些关于缓存等的重要内容。

它可以配置以下内容:

  • 描述映射规则。
  • 提供 SQL 语句,并可以配置 SQL 参数类型、返回类型、缓存刷新等信息。
  • 配置缓存。
  • 提供动态 SQL。

阐述两种实现映射器的方式,XML 文件形式和注解形式。不过在此之前,先创建 role 表和定义一个POJO:

CREATE TABLE `role` (
    `id` bigint(20) NOT NULL,
    `role_name` varchar(20) DEFAULT NULL,
    `note` varchar(20) DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
package com.mybatis.po;

public class Role {
    private Long id;
    private String roleName;
    private String note;
/**setter and getter**/
}
1.3.1 XML实现映射器

用 XML 定义映射器分为两个部分:接口和 XML映射文件。

package com.mybatis.mapper;
import com.mybatis.po.Role;
public interface RoleMapper {
    public Role getRole(Long id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.RoleMapper">
    <select id="getRole" parameterType="long" resultType="role">
        SELECT id,role_name as roleName, note FROM role WHERE id =#{id}
    </select>
</mapper>
  1. <mapper> 元素中的属性 namespace 所对应的是一个接口的全限定名,于是 MyBatis 上下文就可以通过它找到对应的接口。
  2. <select> 元素表明这是一条查询语句。
    • 属性 id 标识了这条 SQL
    • 属性parameterType="long" 说明传递给 SQL 的是一个 long 型的参数
    • resultType="role" 表示执行sql语句返回的结果用 role 类型的对象来保存。 role 是之前配置文件 mybatis-config.xml 中配置的别名,指代的是com.mybatis.po.Role类。
  3. 这条 SQL 中的 #{id} 表示传递进去的参数,参数类型为long

我们并没有配置 SQL 执行后和 role 的对应关系,它是如何映射的呢?

当执行SQL 语句返回的列名能和 JavaBean中的属性名完全相同,MyBatis就会执行自动映射机制。

在上述<select>语句中,JavaBean指的是<select>语句中resultType属性值指代的类com.mybatis.po.Role

当sql返回的记录的列名和JavaBean属性名并不相同时,可以在<select><\select>中sql语句中给列名设置别名,让列名的别名和JavaBean属性名相同。

上述mapper文件中的SQL语句:SELECT id,role_name as roleName, note FROM role ... 中,通过给列名设置别名(role_name as roleName ),让sql语句返回的记录的列名从role_name变为role_Name

1.3.2 注解实现映射器

采用注解方式定义映射器,它只需要一个接口就可以通过 MyBatis 的注解来注入 SQL

package com.mybatis.

apache.ibatis.annotations.Select;
import com.mybatis.po.Role;
public interface RoleMapper2 {
    @Select("select id,role_name as roleName,note from t_role where id=#{id}")
    public Role getRole(Long id);
}

如果注解和 XML 方式同时定义时,XML 方式将覆盖掉注解方式,所以 MyBatis 官方推荐使用的是 XML 方式

1.4 执行SQL

执行SQL语句有两种方式:
​ ①SqlSession 发送 SQL
​ ②用 Mapper 接口发送 SQL

无论上述哪种执行方式,都无法使得数据库中的数据发生变动,所以执行完SQL之后需要使用sqlSession.commit()来将改动提交到数据库中

1.4.1 SqlSession 发送 SQL

直接通过“命名空间(namespace)+SQL id”的方式执行 SQL,不需要获取映射器

Role role = (Role)sqlSession.select("com.mybatis.mapper.RoleMapper.getRole",1L);
1.4.2 用 Mapper 接口发送 SQL

SqlSession 获取 Mapper 接口,通过 Mapper 接口发送 SQL

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1L);

使用 Mapper 接口编程可以消除 SqlSession 带来的功能性代码,提高可读性,而 SqlSession 发送 SQL,需要一个 SQL id 去匹配 SQL,比较晦涩难懂

目前使用 Mapper 接口编程已成为主流,尤其在 Spring中运用 MyBatis 时,Mapper 接口的使用就更为简单

二、作用域和生命周期

我们已经掌握了 MyBatis 组件的创建及其基本应用,但这是远远不够的,还需要讨论其生命周期。

所谓生命周期就是每一个对象应该存活的时间,比如一些对象一次用完后就要关闭,使它们被Java虚拟机(JVM)销毁,以避免继续占用资源,所以我们会根据每一个组件的作用去确定其生命周期。

2.1 SqlSessionFactoryBuilder

SqlSessionFactoryBuilder接口的作用在于创建 SqlSessionFactory
创建SqlSessionFactory成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,不能长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)

2.2 SqlSessionFactory

SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口的实现类的对象。
因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。

由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。

因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域。

2.3 SqlSession

如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。

所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try…catch…finally… 语句来保证其正确关闭。

所以 SqlSession 的最佳的作用域是请求或方法作用域。

2.4 Mapper映射器

Mapper 是一个接口,它由 SqlSession 所创建,所以它的最大生命周期至多和 SqlSession 保持一致,尽管它很好用,但是由于 SqlSession 的关闭,它的数据库连接资源也会消失,所以它的生命周期应该小于等于 SqlSession 的生命周期。Mapper 代表的是一个请求中的业务处理,所以它应该在一个请求中,一旦处理完了相关的业务,就应该废弃它

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领,每个领都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值