数据库连接池

数据库连接池

一、直接获取数据库链接的缺点

用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。

数据库连接池

二、使用数据库连接池优化程序性能

数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个

如下图所示:

数据库连接池

三、开源数据库连接池

通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。

也有一些开源组织提供的数据源:

  • DBCP连接池
  • C3P0连接池

3.1 DBCP连接池

使用DBCP连接池,需要导入两个jar包

  • commons-dbcp-1.2.2.jar :连接池的实现
  • Commons-pool.jar:连接池实现的依赖库

数据库连接池

3.2 在应用程序中加入DBCP连接池(两种方式:BasicDataSource、BasicDataSourceFactory)

BasicDataSource方式(硬编码):BasicDataSource对象设置各种数据

  1. 导入相关jar包

    commons-dbcp-1.2.2.jar、commons-pool.jar

  2. 硬编码获取connection连接

 
 
 
 
 
 
public static DataSource getDataSource(){
    BasicDataSource bds = new BasicDataSource();
    bds.setDriverClassName("com.mysql.jdbc.Driver");
    bds.setUrl("jdbc:mysql://localhost:3306/student");
    bds.setUsername("root");
    bds.setPassword("123456");
    bds.setInitialSize(20);
    bds.setMaxActive(10);
?
    return bds;
}
?
public static void main(String[] args) throws Exception{
        System.out.println(getDataSource().getConnection());
    }
 

BasicDataSourceFactory方式: 配置方式(.properties文件)

  1. 导入相关jar包

    commons-dbcp-1.2.2.jar、commons-pool.jar

  2. 在类目录下加入dbcp的配置文件:dbcpconfig.properties(此处遇到一个错误将在文后写)

    数据库连接池

     

     
     
     
     
     
     
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/student
    username=root
    password=123456
    ?
    #<!-- 初始化连接 -->
    initialSize=10
    ?
     #最大连接数量
    maxActive=50
    ?
    #<!-- 最大空闲连接 -->
    maxIdle=20
    ?
    #<!-- 最小空闲连接 -->
    minIdle=5
    ?
    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000
     
  1. 通过读取配置文件获取connection连接

     
     
     
     
     
     
    public static DataSource getDataSourceByProfile() throws Exception{
    ?
        DataSource dbcp = null;
        Properties properties = new Properties();
        
        //读取配置文件转化为输入流的形式
        InputStream inputStream = DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
    ?
        //加载配置文件的输入流
        properties.load(inputStream);
    ?
        //获取数据库连接
        dbcp = BasicDataSourceFactory.createDataSource(properties);
    ?
        return dbcp;
    ?
    }
     

 

3.3 c3p0连接池

c3p0与dbcp区别

  1. dbcp没有自动回收空闲连接的功能
  2. c3p0有自动回收空闲连接功能

3.4 在应用程序中加入c3p0连接池(两种方式:硬编码和配置文件)

数据库连接池

硬编码方式

  1. 导入相关jar包

    c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,如果操作的是mysql数据库需另加入mysql-connector-java-5.1.49-bin.jar

  2. 应用程序获取数据库连接

     
     
     
     
     
     
    public static DataSource getDataSourceByC3P0() throws Exception{
        ComboPooledDataSource c3p0 = new ComboPooledDataSource();
        c3p0.setDriverClass("com.mysql.jdbc.Driver");
        c3p0.setJdbcUrl("jdbc:mysql://localhost:3306/student");
        c3p0.setUser("root");
        c3p0.setPassword("123456");
        c3p0.setInitialPoolSize(5);
        c3p0.setMaxPoolSize(15);
    ?
        return c3p0;
    }
    ?
        public static void main(String[] args) throws Exception{
            System.out.println(getDataSourceByC3P0().getConnection());
        }
     

     

配置文件方式

  1. 导入相关jar包

    c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,如果操作的是mysql数据库需另加入mysql-connector-java-5.1.49-bin.jar

  2. 编写配置文件c3p0-config.xml

     
     
     
     
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <default-config>
            <!-- 如果要研究某个xml中可以设置哪些属性。找相关类的 属性 或者setXxx()-->
            <property name="user">root</property>
            <property name="password">123456</property>
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/student</property>
            <property name="checkoutTimeout">30000</property>
        </default-config>
    ?
    ?
        <named-config name="admin">
            <property name="user">root</property>
            <property name="password">123456</property>
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/student</property>
            <property name="checkoutTimeout">20000</property>
    ?
        </named-config>
    ?
    </c3p0-config>
     
  3. 程序中获取数据库连接

     

     
     
     
     
     
     
        public static DataSource getDataSourceByC3P0XML(){
    ?
            ComboPooledDataSource c3p0 = new ComboPooledDataSource("admin");
    ?
            return c3p0;
        }
    ?
        public static void main(String[] args) throws Exception{
            System.out.println(getDataSourceByC3P0XML().getConnection());
        }
    }
     

四、配置Tomcat数据源

4.1 JNDI技术简介

JNDI(Java Naming and Directory Interface),Java命名和目录接口它对应于javax.naming包这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需 通过名称检索即可。其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

我们可以通过配置context.xml和web.xml文件实现JNDI获取Tomcat数据库连接池

数据库连接池

 
 
 
 
 
 
context.xml
?
<Context>
?
    <Resource name = "student" auth = "Container" type = "javax.sql.DataSource" maxActive = "400"
              maxIdle = "20" maxWait = "5000" username = "root" password="123456" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/student">
?
    </Resource>
?
</Context>
 
 
 
 
 
web.xml
?
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
?
?
    <resource-ref>
        <res-ref-name>student</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
 
 
    </resource-ref>
?
</web-app>
 

服务器创建好数据源之后,我们的应用程序又该怎么样得到这个数据源呢,Tomcat服务器创建好数据源之后是以JNDI的形式绑定到一个JNDI容器中的,我们可以把JNDI想象成一个大大的容器,我们可以往这个容器中存放一些对象,一些资源,JNDI容器中存放的对象和资源都会有一个独一无二的名称,应用程序想从JNDI容器中获取资源时,只需要告诉JNDI容器要获取的资源的名称,JNDI根据名称去找到对应的资源后返回给应用程序。

java程序如何获取数据库连接

 
 
 
 
 
 
try {
    Class.forName("com.mysql.jdbc.Driver") ;
    Context cxt = new InitialContext();
    DataSource ds = (DataSource)cxt.lookup("java:comp/env/student");
    connection = ds.getConnection();
} catch (NamingException e) {
    e.printStackTrace();
}
 

 

学习过程中遇到的错误

无论使用哪一种数据库连接池时,都可能会遇到访问配置文件的情况

在使用配置文件获取DBCP和C3P0的数据库连接时出现以下错误:

数据库连接池

数据库连接池

 

可我明明配置了c3p0-config.xml 配置文件 ,却并未加载,发现是文件位置问题,将c3p0-config.xml移至resources目录下解决。

 

数据库连接池

上一篇:SDBCI-WRCF2020-MI赛题成绩回顾


下一篇:MySQL-DML(1):简单查询