MyBatis 连接池和事务控制

文章源码

MyBaits 连接池

实际开发中都会使用连接池,因为它可以减少获取连接所消耗的时间。具体可查看

MyBatis 数据源配置在 SqlMapConfig.xml 中的 dataSource 标签,type 属性就是表示采用何种方式,它提供了三种方式的配置:

  • POOLED 采用传统的 javax.sql.DataSource 接口中的连接池,MyBatis中有针对此接口的实现
  • UNPOOLED 采用传统的获取连接的方式,虽然也实现 javax.sql.DataSource 接口,但是并没有使用池的思想
  • JNDI 采用服务器提供的 JNDI 技术实现,来获取 DataSource 对象,不同的服务器所能拿到 DataSource 是不一样的。值得注意的是,如果不是 web 或者 maven 的 war 工程,是不能使用的。例如 Tomcat 服务器采用连接池就是DBCP。

POOLED 分析

连接池就是用于存储连接的一个容器,即一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一个连接。而且,该集合还必须实现队列先进先出的特性。

运行测试程序,得到:

可以看到,先得到了一个连接,然后使用完成后,又将连接放回了连接池中。

源码分析

由上图可以看到,一共有两个连接池,即 idleConnections 空闲池 和 activeConnections 活动池。

  • 第一步:如果空闲池还有连接的话,直接从中取出一个拿出来使用,否则
  • 第二步:查看活动池是否达到了最大数量,如果没有,则创建一个连接放入活动池,否则
  • 第三步:从活动池取出一个最老的连接出来

UNPOOLED 分析

运行测试程序,得到:

可以看到,并没有连接池的概念。

JNDI 分析

JNDI(Java Nameing and Directory),即 Java 命名和目录接口,它提供了一个接口让用户在不知道资源所在位置的情形下,取得该资源服务。

使用步骤:

  • 建立 Maven 工程,选择 archetype-webapp

  • 手动添加 java resources test 等文件夹

  • 在 webapp 目录下添加 META-INF.context.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <Context>
    3. <!--
    4. <Resource
    5. name="jdbc/mybatisT" 数据源的名称
    6. type="javax.sql.DataSource" 数据源类型
    7. auth="Container" 数据源提供者
    8. maxActive="20" 最大活动数
    9. maxWait="10000" 最大等待时间
    10. maxIdle="5" 最大空闲数
    11. username="root" 用户名
    12. password="root" 密码
    13. driverClassName="com.mysql.jdbc.Driver" 驱动类
    14. url="jdbc:mysql://localhost:3306/mybatisT?useSSL=false" 连接url字符串
    15. />
    16. -->
    17. <Resource
    18. name="jdbc/mybatisT"
    19. type="javax.sql.DataSource"
    20. auth="Container"
    21. maxActive="20"
    22. maxWait="10000"
    23. maxIdle="5"
    24. username="root"
    25. password="root"
    26. driverClassName="com.mysql.jdbc.Driver"
    27. url="jdbc:mysql://localhost:3306/mybatisT?useSSL=false"
    28. />
    29. </Context>
  • 配置 SqlMapConfig.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE configuration
    3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6. <typeAliases>
    7. <package name="cn.parzulpan.domain"/>
    8. </typeAliases>
    9. <environments default="mysql">
    10. <environment id="mysql">
    11. <!-- 配置事务控制的方式 -->
    12. <transactionManager type="JDBC"/>
    13. <!-- 配置连接数据库的必备信息 type属性表示是否使用数据源(连接池)-->
    14. <dataSource type="JNDI">
    15. <property name="data_source" value="java:comp/env/jdbc/mybatisT"/>
    16. </dataSource>
    17. </environment>
    18. </environments>
    19. <!-- 指定mapper配置文件的位置 -->
    20. <mappers>
    21. <package name="cn.parzulpan.dao"/>
    22. </mappers>
    23. </configuration>
  • 编辑 index.jsp,部署 Tomcat

    1. <%@ page import="java.io.InputStream" %>
    2. <%@ page import="org.apache.ibatis.io.Resources" %>
    3. <%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %>
    4. <%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>
    5. <%@ page import="org.apache.ibatis.session.SqlSession" %>
    6. <%@ page import="cn.parzulpan.dao.UserDAO" %>
    7. <%@ page import="cn.parzulpan.domain.User" %>
    8. <%@ page import="java.util.List" %>
    9. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    10. <html>
    11. <body>
    12. <h2>Hello World!</h2>
    13. <%
    14. // 1. 读取配置文件
    15. InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
    16. // 2. 创建 SqlSessionFactory 的构建者对象
    17. SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    18. // 3. 使用构建者创建工厂对象 SqlSessionFactory
    19. SqlSessionFactory factory = builder.build(is);
    20. // 4. 使用 SqlSessionFactory 生产 SqlSession 对象
    21. SqlSession sqlSession = factory.openSession();
    22. // 5. 使用 SqlSession 对象 创建 DAO 接口的的代理对象
    23. UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    24. // 6. 使用代理对象执行方法
    25. List<User> users = userDAO.findAll();
    26. for (User user : users) {
    27. System.out.println(user);
    28. }
    29. // 7. 释放资源
    30. sqlSession.close();
    31. is.close();
    32. %>
    33. </body>
    34. </html>

MyBatis 事务控制

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

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

  1. public class Test {
  2. private InputStream is;
  3. SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  4. private SqlSessionFactory factory;
  5. private SqlSession session;
  6. private UserDAO userDAO;
  7. @Before
  8. public void init() throws IOException {
  9. is = Resources.getResourceAsStream("SqlMapConfig.xml");
  10. factory = builder.build(is);
  11. session = factory.openSession();
  12. userDAO = session.getMapper(UserDAO.class);
  13. }
  14. @After
  15. public void destroy() throws IOException {
  16. session.commit(); // 事务提交
  17. session.close();
  18. is.close();
  19. }
  20. }

其实也可以采取非手动方式,openSession() 有一个可以设置是否自动提交的方法 SqlSession openSession(boolean autoCommit);

  1. public class MyBatisCRUDTest {
  2. private InputStream is;
  3. SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  4. private SqlSessionFactory factory;
  5. private SqlSession session;
  6. private UserDAO userDAO;
  7. @Before
  8. public void init() throws IOException {
  9. is = Resources.getResourceAsStream("SqlMapConfig.xml");
  10. factory = builder.build(is);
  11. session = factory.openSession(true);
  12. userDAO = session.getMapper(UserDAO.class);
  13. }
  14. @After
  15. public void destroy() throws IOException {
  16. // session.commit(); // 事务提交
  17. session.close();
  18. is.close();
  19. }
  20. }

但就编程而言,设置为自动提交方式为 false 再根据情况决定是否进行提交,这种方式更常用。因为可以根据业务情况来决定提交是否进行提交。

练习和总结


什么是事务?

事务的四大特性?

不考虑隔离性会产生的问题?

四种隔离级别?

参考数据库事务


【MyBatis】MyBatis 连接池和事务控制的更多相关文章

  1. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_6 mybatis中的事务原理和自动提交设置

    在实际的开发中,建议使用连接池的形式. JNDI的资料 H:\BaiDu\黑马传智JavaEE57期 2019最新基础+就业+在职加薪\讲义+笔记+资料\主流框架\31.会员版(2.0)-就业课(2. ...

  2. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_3 mybatis连接池的分类

    2.mybatis中的连接池     mybatis连接池提供了3种方式的配置:         配置的位置:             主配置文件SqlMapConfig.xml中的dataSourc ...

  3. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_5 mybatis中使用poolead配置连接的原理分析

    idelConnection是空闲的链接 idelConnection就是ArrayList的数组 如果没有空闲的就new一个 新的connection 一个空闲池,一个活动的池,一个链接过来.空闲池 ...

  4. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_4 mybatis中使用unpooled配置连接池的原理分析

    把之前的CRUD的代码src下的代码都复制过来 依赖项也都复制过来, 配置文件 整理一番 执行findAll方法的测试 查看日志的输出部分 修改程序池 再来执行findAll方法 Plooled从连接 ...

  5. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_2 连接池介绍

  6. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_1 今日课程内容介绍

  7. MyBatis基础_连接池与事务、动态SQL、注解开发

    一.MyBatis连接池及事务控制 1.连接池 在实际开发中,都会使用连接池,因为它可以减少获取连接缩消耗的时间.所谓连接池,就是存储数据库连接的容器.连接池中存储一定数量的数据库连接,当线程需要使用 ...

  8. Mybatis 的连接池技术

    我们在前面的 WEB 课程中也学习过类似的连接池技术,而在 Mybatis 中也有连接池技术,但是它采用的是自 己的连接池技术.在 Mybatis 的 SqlMapConfig.xml 配置文件中,通 ...

  9. Spring Boot1.5.4 连接池 和 事务

    原文:https://github.com/x113773/testall/issues/10 默认连接池---spring Boot中默认支持的连接池有Tomcat.HikariCP .DBCP . ...

随机推荐

  1. golang omitempty 总结

    golang omitempty 总结 在使用Golang的时候,不免会使用Json和结构体的相互转换,这时候常用的就是 json.Marshal和json.Unmarshal两个函数. 这时候在定义 ...

  2. 题解-CF348E Pilgrims

    题面 CF348E Pilgrims 有一棵 \(n\) 个点的 带权 树和 \(m\) 个关键点,要求杀了一个不关键的点,满足最多的关键点到离它最远的所有关键点的路径都被打断.求可以满足的最多关键点 ...

  3. 最简 Spring IOC 容器源码分析

    前言 BeanDefinition BeanFactory 简介 Web 容器启动过程 bean 的加载 FactoryBean 循环依赖 bean 生命周期 公众号 前言 许多文章都是分析的 xml ...

  4. 使用纯js 不导包实现 table 导出 Excel

    1.将js粘贴到项目 2.设置table标签 id3.定义按钮,调用方法即可 1 <!DOCTYPE html> 2 <html lang="zh_CN"> ...

  5. php_memcache扩展

    今天在一家招聘信息看到需要熟悉memcache,以前没接触过,用的都是redis,今天稍微看了下,在这里记述下一些基础点. memcache是什么? 首先我们需要了解memcache是做什么的,他有什 ...

  6. django DRF理解

    django restframework(DRF) 最近的开发过程当中,发现restframework的功能很强大,所以尝试解读了一下源码,写篇博客分享给大家,有错误的地方还请各位多多指出 视图部分 ...

  7. 什么是babel

    什么是babel babel是一款基于node开发的工具,其功能是对es6的新语法和新特性进行转码.

  8. OS第六章

    OS第七次实验 多进程 添加一个进程体 添加进程B,首先设置i的初值为0x1000,这样来方便程序运行时的时候能区分.其余地方与A一致. 相关变量和宏 Minix中定义了一个数组,叫做tasktab的 ...

  9. Flink连接器-批处理-读写Hbase

    Flink批处理与hbase的读写 source-hbase 父类 是模仿官方写的. import org.apache.flink.api.common.io.LocatableInputSplit ...

  10. JavaScript之作用域-作用域链

    作用域 ==> 作用域链   作用域:变量可以其作用的区域(声明定义好一个变量,变量可以在哪些范围内使用) 分类:全局作用域和局部作用域(函数作用域):在js中,目前全局有作用域以及函数可以形成 ...