• Java操作数据库——使用连接池连接数据库


    Java操作数据库——使用连接池连接数据库

    摘要:本文主要学习了如何使用JDBC连接池连接数据库。

    传统方式和连接池方式

    传统方式的步骤

    使用传统方式在Java中使用JDBC连接数据库,完成一次数据库的操作,一般有以下几个步骤:

    加载驱动。

    建立连接。

    执行SQL语句。

    释放连接。

    传统方式的弊端

    每一次对数据库的操作都要建立一次连接,并且会将得到的Connection对象加载到内存中,导致消耗了大量的内存和时间。如果短时间有很多需要进行建立连接的操作,会导致占用很多系统资源,甚至会导致服务器崩溃。

    同建立连接相对应,每次使用都需要手动释放连接,如果忘记释放连接或者程序出现异常未能成功释放,会导致内存泄露。

    此外,传统方式并不能控制连接的数量,如果连接的人数过多,会导致无限制的创建连接对象,导致内存开销过大,服务器崩溃。

    连接池的步骤

    创建连接池并配置连接属性。

    使用连接池获取连接。

    连接池的优势

    每次需要连接数据库时,不需要建立连接,而是通过连接池获取,由连接池提供连接。

    在使用完连接后,不需要手动释放连接,而是交由连接池释放连接。

    可以通过连接池控制连接的数量,在连接池里的连接可多次重复使用,避免了无限制创建连接的问题。

    使用连接池

    使用C3P0连接池

    C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

    导入jar包:

    1 c3p0-0.9.5.2.jar

    在当前项目的代码根目录 src 下新建名为 c3p0-config.xml 的配置文件,注意文件名称不可改变,内容如下:

     1 <c3p0-config>
     2     <!-- 连接名称 -->
     3     <named-config name="mysql">
     4         <!-- 接数据库的驱动类名 -->
     5         <property name="driverClass">com.mysql.jdbc.Driver</property>
     6         <!-- 连接属性 -->
     7         <property name="jdbcUrl">jdbc:mysql://192.168.35.128:3306/demo</property>
     8         <property name="user">root</property>
     9         <property name="password">123456</property>
    10         <!-- 当连接池用完时等待获取新连接的时间,超时后将抛出SQLException,单位毫秒,如设为0则无限期等待。默认为0。 -->
    11         <property name="checkoutTimeout">5000</property>
    12         <!-- 当连接用尽后,一次获取的连接个数 -->
    13         <property name="acquireIncrement">2</property>
    14         <!-- 初始连接数 -->
    15         <property name="initialPoolSize">1</property>
    16         <!-- 最小连接数 -->
    17         <property name="minPoolSize">3</property>
    18         <!-- 最大连接数 -->
    19         <property name="maxPoolSize">5</property>
    20     </named-config>
    21 </c3p0-config>

    程序代码:

     1 public class TestDataPool {
     2     // 根据配置文件里的名称创建连接池
     3     public static ComboPooledDataSource cpds = new ComboPooledDataSource("mysql");
     4     
     5     /**
     6      * 主程序
     7      */
     8     public static void main(String[] args) {
     9         // 模拟多次对数据库的查询操作
    10         for (int i = 0; i < 6; i++) {
    11             new Thread(new Runnable() {
    12                 @Override
    13                 public void run() {
    14                     select();
    15                 }
    16             }, "线程" + i).start();
    17         }
    18     }
    19     
    20     /**
    21      * 查询程序
    22      */
    23     public static void select() {
    24         Connection conn = null;
    25         PreparedStatement pstmt = null;
    26         ResultSet rs = null;
    27         // 获取连接并执行SQL
    28         try {
    29             conn = cpds.getConnection();
    30             pstmt = conn.prepareStatement("select * from student where id = 906");
    31             rs = pstmt.executeQuery();
    32             while (rs.next()) {
    33                 System.out.println(Thread.currentThread().getName() + "	" + rs.getString(1) + "	" + rs.getString(2) + "	" + rs.getString("address"));
    34             }
    35         } catch (Exception e) {
    36             e.printStackTrace();
    37         } finally {
    38             // 释放资源
    39             try {
    40                 rs.close();
    41             } catch (SQLException e) {
    42                 e.printStackTrace();
    43             }
    44             try {
    45                 pstmt.close();
    46             } catch (SQLException e) {
    47                 e.printStackTrace();
    48             }
    49             try {
    50                 conn.close();
    51             } catch (SQLException e) {
    52                 e.printStackTrace();
    53             }
    54         }
    55     }
    56 }

    使用DBCP连接池

    DBCP是Apache上的一个Java连接池项目,是一个依赖Jakarta项目commons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用,Tomcat的数据源使用的就是DBCP。

    导入jar包:

    1 commons-dbcp-1.4.jar2 commons-pool-1.5.5.jar

    在当前项目的代码根目录 src 下新建名为 dbcp.properties 的配置文件,文件名需要同代码中引用的文件名一致,内容如下:

     1 # 接数据库的驱动类名
     2 driverClassName=com.mysql.jdbc.Driver
     3 # 连接属性
     4 url=jdbc:mysql://192.168.35.128:3306/demo
     5 username=root
     6 password=123456
     7 # 初始化连接数
     8 initialSize=10
     9 # 最大连接数
    10 maxActive=15

    程序代码:

     1 public class TestDBCP {
     2     // 根据配置文件里的名称创建连接池
     3     private static DataSource source = null;
     4     static {
     5         Properties pros = new Properties();
     6         InputStream is = TestDBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
     7         try {
     8             pros.load(is);
     9             source = BasicDataSourceFactory.createDataSource(pros);
    10         } catch (Exception e) {
    11             e.printStackTrace();
    12         }
    13     }
    14 
    15     /**
    16      * 主程序
    17      */
    18     public static void main(String[] args) {
    19         // 模拟多次对数据库的查询操作
    20         for (int i = 0; i < 6; i++) {
    21             new Thread(new Runnable() {
    22                 @Override
    23                 public void run() {
    24                     select();
    25                 }
    26             }, "线程" + i).start();
    27         }
    28     }
    29 
    30     /**
    31      * 查询程序
    32      */
    33     public static void select() {
    34         Connection conn = null;
    35         PreparedStatement pstmt = null;
    36         ResultSet rs = null;
    37         // 获取连接并执行SQL
    38         try {
    39             conn = source.getConnection();
    40             pstmt = conn.prepareStatement("select * from student where id = 906");
    41             rs = pstmt.executeQuery();
    42             while (rs.next()) {
    43                 System.out.println(Thread.currentThread().getName() + "	" + rs.getString(1) + "	" + rs.getString(2) + "	" + rs.getString("address"));
    44             }
    45         } catch (Exception e) {
    46             e.printStackTrace();
    47         } finally {
    48             // 释放资源
    49             try {
    50                 rs.close();
    51             } catch (SQLException e) {
    52                 e.printStackTrace();
    53             }
    54             try {
    55                 pstmt.close();
    56             } catch (SQLException e) {
    57                 e.printStackTrace();
    58             }
    59             try {
    60                 conn.close();
    61             } catch (SQLException e) {
    62                 e.printStackTrace();
    63             }
    64         }
    65     }
    66 }

    使用Druid连接池

    Druid是阿里巴巴出品的数据源,而且是淘宝和支付宝专用数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。

    导入jar包:

    1 druid-1.0.9.jar

    在当前项目的代码根目录 src 下新建名为 druid.properties 的配置文件,文件名需要同代码中引用的文件名一致,内容如下:

     1 # 接数据库的驱动类名
     2 driverClassName=com.mysql.jdbc.Driver
     3 # 连接属性
     4 url=jdbc:mysql://192.168.35.128:3306/demo
     5 username=root
     6 password=123456
     7 # 最大连接数
     8 maxActive=15
     9 # 最长等待时间
    10 maxWait=3000
    11 # 配置初始化连接数
    12 initialSize=1
    13 # 配置最大活动连接数
    14 maxActive=10

    程序代码:

     1 public class TestDruid {
     2     // 根据配置文件里的名称创建连接池
     3     private static DataSource source = null;
     4     static {
     5         Properties pros = new Properties();
     6         InputStream is = TestDruid.class.getClassLoader().getResourceAsStream("druid.properties");
     7         try {
     8             pros.load(is);
     9             source = DruidDataSourceFactory.createDataSource(pros);
    10         } catch (Exception e) {
    11             e.printStackTrace();
    12         }
    13     }
    14 
    15     /**
    16      * 主程序
    17      */
    18     public static void main(String[] args) {
    19         // 模拟多次对数据库的查询操作
    20         for (int i = 0; i < 6; i++) {
    21             new Thread(new Runnable() {
    22                 @Override
    23                 public void run() {
    24                     select();
    25                 }
    26             }, "线程" + i).start();
    27         }
    28     }
    29 
    30     /**
    31      * 查询程序
    32      */
    33     public static void select() {
    34         Connection conn = null;
    35         PreparedStatement pstmt = null;
    36         ResultSet rs = null;
    37         // 获取连接并执行SQL
    38         try {
    39             conn = source.getConnection();
    40             pstmt = conn.prepareStatement("select * from student where id = 906");
    41             rs = pstmt.executeQuery();
    42             while (rs.next()) {
    43                 System.out.println(Thread.currentThread().getName() + "	" + rs.getString(1) + "	" + rs.getString(2) + "	" + rs.getString("address"));
    44             }
    45         } catch (Exception e) {
    46             e.printStackTrace();
    47         } finally {
    48             // 释放资源
    49             try {
    50                 rs.close();
    51             } catch (SQLException e) {
    52                 e.printStackTrace();
    53             }
    54             try {
    55                 pstmt.close();
    56             } catch (SQLException e) {
    57                 e.printStackTrace();
    58             }
    59             try {
    60                 conn.close();
    61             } catch (SQLException e) {
    62                 e.printStackTrace();
    63             }
    64         }
    65     }
    66 }
  • 相关阅读:
    AI---训练集(train set) 验证集(validation set) 测试集(test set)
    Kubernetes核心概念总结
    GoLang structTag说明
    GOROOT、GOPATH和project目录说明
    在iOS上实现二维码功能
    Page View Controllers
    ios 视图切换翻页效果
    iOS中scrollview自动滚动的实现
    关于Block的copy和循环引用的问题
    Info.plist与Prefix.pch修改文件位置遇到的问题及解决方法
  • 原文地址:https://www.cnblogs.com/shamao/p/11928905.html
Copyright © 2020-2023  润新知