zoukankan      html  css  js  c++  java
  • 常见的数据库连接池

    数据库连接池

    1、概述

    • 概念:其实就是一个容器(集合),存放数据库连接的容器。
    • 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户访问数据库时,会从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
    • 好处:
      • 节约资源
      • 用户访问高效

    2.、实现逻辑

    1. 标准接口:DataSource javax.sql包下的

      • 方法:
        • 获取连接:getConnection()
        • 归还连接:Connection.close()。如果连接对象 Connection 是从连接池中获取的,那么调用Connection.close()方法,则不会关闭连接了。而是归还连接。
    2. 一般我们不去实现它,由数据库厂商来实现

      1. C3P0:数据库连接池技术
      2. Druid:数据库连接池实现技术,由阿里巴巴提供的

    3、数据库连接池:C3P0

    • 使用步骤:

      1. 导入 jar包(两个):c3p0-0.9.5.2.jar、mchange-commons-java-0.2.12.jar,不要忘记导入数据库驱动 jar 包
      2. 定义配置文件
        • 名称:叫 c3p0.properties 或者 c3p0-config.xml 将会自动加载
        • 路径:直接将文件放到 src 目录下即可,右键 --> Add as Library
      3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
      4. 获取连接:getConnection()
    • c3p0目录结构

    c3p0目录结构

    • 代码演示:
    package com.my.datasource.c3p0;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    
    /**
     * c3p0的演示
     */
    public class C3P0Demo1 {
        public static void main(String[] args) throws SQLException {
            // 1.创建数据库连接池对象 DataSource,使用默认配置
            DataSource ds = new ComboPooledDataSource();
    
            // 1.1 获取DataSource,使用指定名称配置
    //        DataSource ds = new ComboPooledDataSource("otherc3o0");
    
            // 2.获取连接对象
    //        Connection conn = ds.getConnection();
    
            // 3.打印
    //        System.out.println(conn);
    
            // 获取10个连接对象
            for (int i = 1; i <= 9; i++) {
                Connection conn = ds.getConnection();
                System.out.println(i + ":" + conn);
                if (i == 4) {
                    conn.close(); // 归还Connection对象
                }
            }
        }
    }
    
    • c3p0-config.xml 配置文件
    <c3p0-config>
        <!-- 使用默认的配置读取连接对象 -->
        <default-config>
            <!-- 连接参数 -->
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/db4</property>
            <property name="user">root</property>
            <property name="password">root</property>
    
            <!-- 连接池参数 -->
            <!-- 初始化申请的连接数量 -->
            <property name="initialPoolSize">5</property>
            <!-- 最大的连接数量 -->
            <property name="maxPoolSize">10</property>
            <!-- 超时时间 -->
            <property name="checkoutTimeout">3000</property>
        </default-config>
    
        <!-- 使用指定名称的配置读取连接对象 -->
        <named-config name="otherc3p0">
            <!-- 连接参数 -->
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/db4</property>
            <property name="user">root</property>
            <property name="password">root</property>
    
            <!-- 连接池参数 -->
            <!-- 初始化申请的连接数量 -->
            <property name="initialPoolSize">5</property>
            <!-- 最大的连接数量 -->
            <property name="maxPoolSize">8</property>
            <!-- 超时时间 -->
            <property name="checkoutTimeout">1000</property>
        </named-config>
    
    
    </c3p0-config>
    

    4、数据库连接池:Druid

    • 使用步骤:

      1. 导入 jar包 druid-1.0.9.jar
      2. 定义配置文件:
        • 是 properties 形式的
        • 可以叫任意名称,可以放在任意目录下,不能自动加载
      3. 加载配置文件:Properties
      4. 获取数据库连接池对象:通过工厂来获取 DruidDataSourceFactory
      5. 获取连接:getConnection()
    • druid.properties

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql:///db4
    username=root
    password=root
    # 初始化连接数量
    initialSize=5
    # 最大连接数
    maxActive=10
    # 最大等待时间
    maxWait=3000
    maxIdle=8
    minIdle=3
    
    • DruidDemo.java
    package com.my.datasource.ddruid;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.util.Properties;
    
    /**
     * Druid演示
     */
    public class DruidDemo {
        public static void main(String[] args) throws Exception {
            // 1.导入jar包
            // 2.定义配置文件
            // 3.加载配置文件
            InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties pro = new Properties();
            pro.load(is);
            // 4.获取数据库连接池对象
            DataSource ds = DruidDataSourceFactory.createDataSource(pro);
            // 5.获取数据库连接对象
            Connection conn = ds.getConnection();
            System.out.println(conn);
            conn.close();
        }
    }
    
    • 定义工具类

      1. 定义一个类:JDBCUtils
      2. 提供静态代码块加载配置文件,初始化连接池对象
      3. 提供方法:
        1. 获取数据库连接对象的方法:通过数据库连接池获取连接
        2. 释放资源
        3. 获取数据库连接池对象的方法
    • 代码实现:

    package com.my.datasource.utils;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Properties;
    
    /**
     * Druid连接池的工具类
     */
    public class JDBCUtils {
        // 1.定义成员变量 DataSource
    private static DataSource ds;
    
        static {
            try {
                // 2.加载配置文件
                Properties pro = new Properties();
                pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
                // 3.获取DataSource
                ds = DruidDataSourceFactory.createDataSource(pro);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
    
        /**
         * 获取数据库连接对象
         *
         * @return
         * @throws SQLException
         */
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
    }
    
        /**
         * 获取连接池对象的方法
         *
         * @return
         */
        public static DataSource getDataSource() {
            return ds;
    }
    
        /**
         * 释放执行DML语句后资源的方法
         *
         * @param pstmt
         * @param conn
         */
        public static void close(PreparedStatement pstmt, Connection conn) {
            close(null, pstmt, conn);
    }
    
        /**
         * 释放执行DQL语句后资源的方法
         *
         * @param rs
         * @param pstmt
         * @param conn
         */
        public static void close(ResultSet rs, PreparedStatement pstmt, Connection conn) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    5、Spring JDBC

    • Spring 框架对 JDBC 的简单封装。
    • 提供了一个 JDBCTemplate 对象简化 JDBC 的开发
    • 使用步骤:
      1. 导入 jar
      2. 创建 JDBCTemplate 对象。依赖于数据源 DataSource
        • JdbcTemplate template = new JdbcTemplate(ds);
      3. 调用 JDBCTemplat 的方法来完成 CRUD 操作
        • update():执行 DML 语句。增、删、改语句。
        • queryForMap():查询结果,将结果集封装为 map 集合,将列名作为 key,值作为 value,将这条记录封装成为一个 map 集合
          • 注意:这个方法查询的结果集长度只能是1
        • queryForList():查询结果,将结果集封装为 list 集合
          • 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中。
        • query():查询结果,将结果集封装为 JavaBean 对象
          • query的参数:RowMapper<类型>
            • 一般我们使用**BeanPropertyRowMapper<类型>实现类**,可以完成数据到 JavaBean的自动封装
            • new BeanPropertyRowMapper<类型>(类型.class)
        • queryForObject()查询结果,将结果封装为对象
    • JdbcTemplate 目录结构,需要导入的 5个 jar 包

    5个jar包

    JdbcTemplate目录结构.PNG

    • 示例
    package com.my.JdbcTemplate;
    
    import com.my.datasource.utils.JDBCUtils;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    /**
     * JdbcTemplate 入门
     */
    public class JdbcTemplateDemo {
        public static void main(String[] args) {
            // 1.导入 jar 包
            // 2.创建 JdbcTemplate对象
            JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
            // 3.定义sql
            String sql = "update account set banlance = ? where id = ?";
            // 4.调用方法
            int count = template.update(sql, 5000, 3);
            System.out.println(count);
        }
    }
    
    • 练习:
    package com.my.JdbcTemplate;
    
    import com.my.datasource.utils.JDBCUtils;
    import com.my.domain.Emp;
    import org.junit.Assert;
    import org.junit.Test;
    import org.springframework.jdbc.core.BeanPropertyRowMapper;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import java.util.List;
    import java.util.Map;
    
    public class JdbcTemplateDemo2 {
        // 获取 JdbcTemplate 对象
        private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
        private String sql;
        private int count;
    
        /*
            修改id为1001的 salary = 10000
         */
        @Test
        public void test1() {
            sql = "update emp set salary = ? where id = ?";
            count = template.update(sql, 10000, 1001);
            Assert.assertEquals(1, count);
        }
    
        /*
            添加一条记录
         */
        @Test
        public void test2() {
            sql = "insert into emp(id, ename, dept_id) values (?, ?, ?)";
            count = template.update(sql, 1015, "郭靖", 10);
            Assert.assertEquals(1, count);
        }
    
        /*
            删除 id 为 1015 的记录
         */
        @Test
        public void test3() {
            sql = "delete from emp where id = ?";
            count = template.update(sql, 1015);
            Assert.assertEquals(1, count);
        }
    
        /*
            查询 id = 1001的记录,将其封装成 Map集合
         */
        @Test
        public void test4() {
            sql = "select * from emp where id = ? ";
            Map<String, Object> map = template.queryForMap(sql, 1001);
            // {id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
            System.out.println(map);
        }
    
        /*
            查询所有的记录,将其封装成 List集合
         */
        @Test
        public void test5() {
            sql = "select * from emp";
            List<Map<String, Object>> list = template.queryForList(sql);
            for (Map<String, Object> stringObjectMap : list) {
                System.out.println(stringObjectMap);
            }
        }
    
        /*
            查询所有记录,将其封装成Emp(Java Bean)对象的List集合
            query():将其封装成指定的对象
         */
        @Test
        public void test6() {
            sql = "select * from emp";
            List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
            list.stream().forEach(System.out::println);
        }
    
        /*
            查询总的记录数
            queryForObject():一般用于聚合函数的计算
         */
        @Test
        public void test7() {
            sql = "select count(id) from emp";
            Long count = template.queryForObject(sql, Long.class);
            System.out.println(count);
        }
    
    }
    
  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/rainszj/p/12219505.html
Copyright © 2011-2022 走看看