对于数据库连接池的一些思考和MyBatis的集成与使用

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:   Java应用要连接数据库需要先通过jdbc与数据库之间产生connection,然后通过sql语句产生statment,再执行这个statment查询的到ResultSet返回给应用,应用解析ResultSet获得Java支持类型的结果。

  Java应用要连接数据库需要先通过jdbc与数据库之间产生connection,然后通过sql语句产生statment,再执行这个statment查询的到ResultSet返回给应用,应用解析ResultSet获得Java支持类型的结果。

这里存在以下几个问题:

  1. 产生连接本身需要,而且这个延时比起常规的查询操作来说是较高的,对于有响应时限的操作来说这是一个致命问题。
  2. 建立连接需要消耗数据库资源,数据库本身开放的连接数量是有限的,即使不断的建立与关闭连接保证总数的稳定,也会极大消耗数据库资源影响性能。而数据库资源比起应用服务器来说又是非常宝贵的,数据库的分流比应用要困难很多。

  所以要避免这种情况就有了连接池。连接池有几个基本属性:初始连接数、最大连接数、最小空闲数、最大空闲数、最大等待毫秒数,分别假设为5 10 1 5 60。连接池可以想象为一个池子,先建立5个连接放入池子中。应用的一个线程需要与数据库交互时,向连接池要一个连接,然后去执行,执行完后会将连接还给连接池。当并发量很高时,连接池内的连接会被取完,此时又有线程要连接,就会检查是否达到了最大连接数,如果没达到就会继续新建连接,将连接交给线程。如果达到上限,则让线程进行等待,知道有线程把连接还回来。

  当连接池内的连接数超过了最大空闲数时,当这个连接被归还连接池,它就会被强制关闭。而当连接池内的连接数小于最小空闲数时,连接池会自动去新建连接来补充到这个数量。为什么连接数量自己会变化呢?因为数据库存在一个连接的等待时间,超过这个时间始终没有活动的话,连接会被数据库关闭,连接池会周期性的去探知所有连接是否存活,以管理连接的数量。

  所谓持久层,是指将数据长期存储到硬盘当中。因为在webapp开发中数据通过数据库存储到硬盘中,所以持久层可以简单的认为就是负责对数据库的增删改查。用过Java原始jdbc的查询的话都知道ResultSet要转换成Java Bean中间的重复操作还是挺多的;要把一个List<T>转换成SQL语句也挺麻烦的,持久层框架的好处之一就是省略掉这中间的重复操作,根据写好的映射关系,直接完成数据库与Java代码之间交互。

  常用的持久层框架有两个:MyBatis和Hibernate。MyBatis最大的特点是SQL语句基本就是没有任何封装的原生SQL。缺点当然是开发起来工作量较大,同时不同数据库之间的迁移性收到影响。优点是学习简单,SQL自由性大,也就有更大的优化空间。毕竟正常情况下你能够控制的东西越多,开发就会越复杂,但是性能极限会更高,当然这里的前提是开发者足够资深,毕竟一般人写的代码不如编译器优化出来的。

  下面开始SSM框架下的这个M的搭建。首先,pom.xml里面引入相关的依赖,包括mybatis本身、Spring的支持插件、mysql驱动,以及连接池创建工具这里采用dbcp

        <!--mysql数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!-- 连接池创建 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

然后配置数据源的话有两种方式,一种是直接配置数据源,还有一种是基于容器的数据源比如tomcat下的jndi连接。

直接配置的话,在applicationContext.xml,即通过ContextLoaderListener监听的配置文件里面添加如下:

<!-- 配置jdbc文件 -->
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations" value="classpath:jdbc.properties" />
    </bean>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${initialSize}" />
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${maxActive}" />
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${maxIdle}" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${minIdle}" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${maxWait}" />
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
        <property name="mapperLocations" value="classpath:com/web/**/*.xml" />
    </bean>

    <!-- DAO接口所在包名,Spring会自动查找其下的类 ,包下的类需要使用@MapperScan注解,否则容器注入会失败 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.web" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

这里采用外部读入参数的方式加载用户名信息,便于统一管理。resources目录下添加jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
username=root
password=123456
initialSize=5
maxActive=10
maxIdle=5
minIdle=1
maxWait=60

然后添加dao层Bean层与对应的xml映射文件

<?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.web.dao.TestMapper">
    <select id="getTest" resultType="com.web.bean.HelloBean">
        select id,txt from test
    </select>
</mapper>
package com.web.dao;

import java.util.List;

import org.mybatis.spring.annotation.MapperScan;

import com.web.bean.HelloBean;

@MapperScan
public interface TestMapper {
    public List<HelloBean> getTest();
}
package com.web.bean;

public class HelloBean {
    private String id;
    private String txt;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTxt() {
        return txt;
    }

    public void setTxt(String txt) {
        this.txt = txt;
    }

}

全部添加完后,项目的路径如下:

 

然后通过注入dao层类之后执行testMapper.getTest(),表与插入的测试数据可以参见我上一篇文章。结果下:

 

说明数据已经直接映射到了结果的bean上面。

  第二种方法,就是利用tomcat来创建连接池,然后mybatis直接只用tomcat的数据源。先配置context.xml

<Resource name="jdbc/mybatis-jndi" auth="Container" type="javax.sql.DataSource"
        maxActive="100" maxIdle="30" maxWait="10000" username="root" password="123456"
        driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/demo" />

然后在applicationContext.xml文件上添加jndi数据源,并修改mybatis使用的数据源java:comp/env/这里是固定字段,后面的jdbc/mybatis-jndi对应context里面配置的name属性

    <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName">
            <value>java:comp/env/jdbc/mybatis-jndi</value>
        </property>
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- ref是使用的数据源 -->
        <property name="dataSource" ref="jndiDataSource" />
        <!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
        <property name="mapperLocations" value="classpath:com/web/**/*.xml" />
    </bean>

  MyBatis的集成至此完成。

个人GitHub地址: https://github.com/GrayWind33
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL Java 数据库连接
深入 MyBatis-Plus 插件:解锁高级数据库功能
Mybatis-Plus 提供了丰富的插件机制,这些插件可以帮助开发者更方便地扩展 Mybatis 的功能,提升开发效率、优化性能和实现一些常用的功能。
216 26
深入 MyBatis-Plus 插件:解锁高级数据库功能
|
2月前
|
存储 JSON Ubuntu
时序数据库 TDengine 支持集成开源的物联网平台 ThingsBoard
本文介绍了如何结合 Thingsboard 和 TDengine 实现设备管理和数据存储。Thingsboard 中的“设备配置”与 TDengine 中的超级表相对应,每个设备对应一个子表。通过创建设备配置和设备,实现数据的自动存储和管理。具体操作包括创建设备配置、添加设备、写入数据,并展示了车辆实时定位追踪和车队维护预警两个应用场景。
83 3
|
2月前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
220 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
2月前
|
安全 算法 Java
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
本文提供了在数据库中对密码等敏感信息进行加盐加密的详细教程,包括手写MD5加密算法和使用Spring Security的BCryptPasswordEncoder进行加密,并强调了使用BCryptPasswordEncoder时需要注意的Spring Security配置问题。
202 0
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
|
2月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
77 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
3月前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
|
4月前
|
XML SQL JavaScript
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
这篇文章介绍了如何在Vue页面中结合SpringBoot、MyBatis、ElementUI和ECharts,实现从数据库获取数据并展示为图表的过程,包括前端和后端的代码实现以及遇到的问题和解决方法。
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
|
4月前
|
XML Java 数据库连接
Spring Boot集成MyBatis
主要系统的讲解了 Spring Boot 集成 MyBatis 的过程,分为基于 xml 形式和基于注解的形式来讲解,通过实际配置手把手讲解了 Spring Boot 中 MyBatis 的使用方式,并针对注解方式,讲解了常见的问题已经解决方式,有很强的实战意义。在实际项目中,建议根据实际情况来确定使用哪种方式,一般 xml 和注解都在用。
|
4月前
|
存储 机器学习/深度学习 人工智能
矢量数据库与LLM的集成:实践指南
矢量数据库与LLM的集成:实践指南
71 2
|
4月前
|
存储 C# 关系型数据库
“云端融合:WPF应用无缝对接Azure与AWS——从Blob存储到RDS数据库,全面解析跨平台云服务集成的最佳实践”
【8月更文挑战第31天】本文探讨了如何将Windows Presentation Foundation(WPF)应用与Microsoft Azure和Amazon Web Services(AWS)两大主流云平台无缝集成。通过具体示例代码展示了如何利用Azure Blob Storage存储非结构化数据、Azure Cosmos DB进行分布式数据库操作;同时介绍了如何借助Amazon S3实现大规模数据存储及通过Amazon RDS简化数据库管理。这不仅提升了WPF应用的可扩展性和可用性,还降低了基础设施成本。
96 0