Mybatis连接池与事务深入

简介: Mybatis连接池与事务深入

Mybatis的连接池技术


在 Mybatis 中有连接池技术,它采用的是自己的连接池技术。配置位置是在 Mybatis 的 SqlMapConfig.xml 配置文件中,通过<dataSource type=”pooled”>来实现 Mybatis 中连接池的配置。


很多时候我们所说的数据源就是为了更好的管理数据库连接,也就是我们所说的连接池技术。连接池的使用是因为它可以减少我们获取连接所消耗的时间。

1.png



Mybatis连接池的分类


Mybatis 将它自己的数据源分为下面三类:

image.png


MyBatis 内部分别定义了实现了 java.sql.DataSource 接口的 UnpooledDataSource,

PooledDataSource 类来表示 UNPOOLED、POOLED 类型的数据源。


Mybatis中数据源的配置


我们的数据源配置就是在 SqlMapConfig.xml 文件中,具体配置如下:


<!-- 配置数据源(连接池)信息 --> 
<dataSource type="POOLED"> 
  <property name="driver" value="${jdbc.driver}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username" value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</dataSource>

MyBatis 在初始化时,根据的 type 属性来创建相应类型的的数据源 DataSource,即:

type=“POOLED”:MyBatis 会创建 PooledDataSource 实例

type=“UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例

type=“JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用


Mybatis中DataSource的存取


MyBatis 是 通 过 工 厂 模 式 来 创 建 数 据 源 DataSource 对 象 的 , MyBatis 定 义 了 抽 象 的 工 厂 接口:org.apache.ibatis.datasource.DataSourceFactory,通过其getDataSource()方法返回数据源DataSource。


Mybatis中连接的获取过程分析


当我们需要创建 SqlSession 对象并需要执行 SQL 语句时,这时候 MyBatis 才会去调用 dataSource 对象来创建java.sql.Connection对象。也就是说,java.sql.Connection对象的创建一直延迟到执行SQL语句的时候。


真正连接打开的时间点,只是在我们执行SQL语句时,才会进行。其实这样做我们也可以进一步发现,数据库连接是我们最为宝贵的资源,只有在要用到的时候,才去获取并打开连接,当我们用完了就再立即将数据库连接归还到连接池中。


Mybatis的事务控制


JDBC中事务的回顾


在 JDBC 中我们可以通过手动方式将事务的提交改为手动方式,通过 setAutoCommit()方法就可以调整。

Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的setAutoCommit()方法来设置事务提交方式的。

它是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚。


Mybatis中事务提交方式


Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制。


运行测试代码:


package com.keafmd.test;
import com.keafmd.dao.IUserDao;
import com.keafmd.domain.QueryVo;
import com.keafmd.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
 * Keafmd
 *
 * @ClassName: MybatisTest
 * @Description: 测试类,测试crud操作
 * @author: 牛哄哄的柯南
 * @date: 2021-02-08 15:24
 */
public class MybatisTest {
    private InputStream in;
    private SqlSession sqlsession;
    private IUserDao userDao;
    @Before // 用于在测试方法执行前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        sqlsession = factory.openSession(); //里面写个true,下面每次就不用了写 sqlsession.commit(); 了
        //4.使用SqlSession创建Dao接口的代理对象
        userDao = sqlsession.getMapper(IUserDao.class);
    }
    @After // 用于在测试方法执行后执行
    public void destory() throws Exception{
        //提交事务
        sqlsession.commit();
        //6.释放资源
        sqlsession.close();
        in.close();
    }
    /**
     * 测试保存操作
     */
    @Test
    public void testSave() throws Exception {
        User user = new User();
        user.setUsername("Keafmd laset insertid");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setAddress("XXXXXXX");
        System.out.println("保存操作前:"+user);
        //5.执行保存方法
        userDao.saveUser(user);
        System.out.println("保存操作后:"+user);
    }
}

控制台信息:

1.png


这是我们的 Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进行事务的提交,原因是 setAutoCommit()方法,在执行时它的默认值被设置为 false 了,所以我们在 CUD 操作中,必须通过 sqlSession.commit()方法来执行提交操作。


Mybatis自动提交事务的设置


在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。

我们设置session = factory.openSession(true);,同时去掉destory()中的session.commit();提交语句,这样就成了自动提交事务了。


运行测试代码:


package com.keafmd.test;
import com.keafmd.dao.IUserDao;
import com.keafmd.domain.QueryVo;
import com.keafmd.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
 * Keafmd
 *
 * @ClassName: MybatisTest
 * @Description: 测试类,测试crud操作
 * @author: 牛哄哄的柯南
 * @date: 2021-02-08 15:24
 */
public class MybatisTest {
    private InputStream in;
    private SqlSession sqlsession;
    private IUserDao userDao;
    @Before // 用于在测试方法执行前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        sqlsession = factory.openSession(true); //里面写个true,下面每次就不用了写 sqlsession.commit(); 了
        //4.使用SqlSession创建Dao接口的代理对象
        userDao = sqlsession.getMapper(IUserDao.class);
    }
    @After // 用于在测试方法执行后执行
    public void destory() throws Exception{
        //提交事务
        //sqlsession.commit();
        //6.释放资源
        sqlsession.close();
        in.close();
    }
    /**
     * 测试保存操作
     */
    @Test
    public void testSave() throws Exception {
        User user = new User();
        user.setUsername("Keafmd laset insertid");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setAddress("XXXXXXX");
        System.out.println("保存操作前:"+user);
        //5.执行保存方法
        userDao.saveUser(user);
        System.out.println("保存操作后:"+user);
    }
}

DefaultSqlSessionFactory 类的源代码:


public SqlSession openSession(boolean autoCommit) {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }

控制台信息:


1.png

我们可以发现,此时事务就设置为自动提交了,同样可以实现CUD操作时记录的保存。虽然这也是一种方式,但就编程而言,设置为自动提交方式为 false 再根据情况决定是否进行提交,这种方式更常用。因为我们可以根据业务情况来决定提交是否进行提交。


以上就是Mybatis连接池与事务深入的全部内容。


相关文章
|
1月前
|
Java 关系型数据库 MySQL
【mybatis-plus】自定义多数据源,动态切换数据源事务失效问题
【mybatis-plus】自定义多数据源,动态切换数据源事务失效问题
【mybatis-plus】自定义多数据源,动态切换数据源事务失效问题
|
4月前
|
Java 数据库连接 mybatis
一文彻底搞懂Mybatis系列(二)之mybatis事务管理机制深度剖析
一文彻底搞懂Mybatis系列(二)之mybatis事务管理机制深度剖析
216 0
|
5月前
|
XML Java 数据库连接
SpringBoot - 整合MyBatis配置版(XML)并开启事务
SpringBoot - 整合MyBatis配置版(XML)并开启事务
117 0
|
7月前
|
Java 测试技术 数据库连接
MyBatis基本用法 && 什么是自动化测试 && Spring事务和事务传播机制 && 性能测试概念和术语 && Loadrunner安装
MyBatis基本用法 && 什么是自动化测试 && Spring事务和事务传播机制 && 性能测试概念和术语 && Loadrunner安装
50 0
|
9月前
|
SQL Java 数据库连接
【MyBatis】框架特点,ORM思想,事务管理机制
【MyBatis】框架特点,ORM思想,事务管理机制
|
9月前
|
XML Java 数据库连接
2021-08-10基于注解配置AOP,银行取款初步后台搭建,spring事务处理,注解方式事务配置,spring+mybatis整合
2021-08-10基于注解配置AOP,银行取款初步后台搭建,spring事务处理,注解方式事务配置,spring+mybatis整合
340 1
|
12月前
|
XML Java 关系型数据库
Spring Boot2.x-10 基于Spring Boot 2.1.2 + Mybatis 2.0.0实现多数据源,支持事务
Spring Boot2.x-10 基于Spring Boot 2.1.2 + Mybatis 2.0.0实现多数据源,支持事务
7610 0
|
Java 关系型数据库 MySQL
详解 MyBatis 事务管理,彻底颠覆你对事务的理解!
详解 MyBatis 事务管理,彻底颠覆你对事务的理解!
456 0
详解 MyBatis 事务管理,彻底颠覆你对事务的理解!
|
Java 大数据 数据库连接
Mybatis整合c3p0连接池
你好看官,里面请!今天笔者讲的是Mybatis整合c3p0连接池。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。
320 2