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

    前述:

      对之前JDBC的操作,不管是原始的操作步骤,还是JDBCUtils工具类的写法,都存在一个严重的问题:每次我们都需要去创建一个连接对象,然后再释放掉资源的操作。

      从效率和内存的角度,这种重复创建和释放的操作方式是不可取的。那么该如何优化?

      既然知道了问题是出现在重复创建和释放的操作上,那我们便可以对症下药--让重复不再重复。

      于是,结合线程池的思想,我们也可以创建一个容器来存放一定数量的数据库连接对象,在使用时获取,在关闭时归还。---我们称之为数据库连接池

    一、数据库连接池

     1.1 概述

        存放数据库连接的容器(集合)。

        作用:高效率,节约资源。

     1.2 代码实现

        接口标准:javax.sql.DataSource

      • 获取连接:getConnection()
      • 归还连接:Connection.close()。  // 如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了,而是归还连接。

     小贴士:一般我们不去实现它,由数据库厂商来实现,比如:

    • C3P0:数据库连接池技术
    • Druid:数据库连接池实现技术(由阿里巴巴提供的)

    二、C3P0 数据库连接池技术

     2.1 步骤

        1. 导入jar包 (两个: c3p0-0.9.5.2.jar、mchange-commons-java-0.2.12.jar)
        2. 定义配置文件:
          * 名称:c3p0.properties 或者 c3p0-config.xml
          * 路径:直接将文件放在src目录下即可。
        3. 创建核心对象:数据库连接池对象 ComboPooledDataSource
        4. 获取连接:getConnection

     2.2 代码实现

        1. 创建数据库连接池对象
        DataSource ds  = new ComboPooledDataSource();
        2. 获取连接对象
        Connection conn = ds.getConnection();

    三、Druid 数据库连接池实现技术(由阿里巴巴提供)

     3.1 步骤

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

     3.2 代码实现

        1.加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        2.获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        3.获取连接对象
        Connection conn = ds.getConnection();

    四、重新定义JDBCUtils工具类

     4.1 步骤

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

     4.2 代码实现(使用Druid连接池)

    public class JDBCUtils {
    
    	//1.定义成员变量 DataSource
    	private static DataSource ds ;
    
    	static{
    		try {
    			//1.加载配置文件
    			Properties pro = new Properties();
    			pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
    			//2.获取DataSource
    			ds = DruidDataSourceFactory.createDataSource(pro);
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	/**
    	 * 获取连接
    	 */
    	public static Connection getConnection() throws SQLException {
    		return ds.getConnection();
    	}
    
    	/**
    	 * 释放资源
    	 */
    	public static void close(Statement stmt,Connection conn){
    	   /* if(stmt != null){
    			try {
    				stmt.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		if(conn != null){
    			try {
    				conn.close();	//归还连接
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}*/
    
    	   close(null,stmt,conn);
    	}
    	/**
    	 * 释放资源
    	 */
    	public static void close(ResultSet rs , Statement stmt, Connection conn){
    		if(rs != null){
    			try {
    				rs.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		if(stmt != null){
    			try {
    				stmt.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		if(conn != null){
    			try {
    				conn.close();	//归还连接
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	
    	/**
    	 * 获取连接池方法
    	 */
    	public static DataSource getDataSource(){
    		return ds;
    	}
    			
    }
    

      

    五、Spring JDBC

     5.1 概述

        Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发。

     5.2 步骤

        1. 导入相关的jar包;(如:spring-jdbc-5.0.0.RELEASE.jar等)
        2. 创建JdbcTemplate对象。依赖于数据源DataSource
          * JdbcTemplate template = new JdbcTemplate(ds);
        3. 调用JdbcTemplate的方法来完成CRUD的操作
          * update():执行DML(增、删、改)语句。
          * queryForMap():查询结果将结果集封装为map集合。
            * 注意:查询的结果集长度只能是1,将列名作为key,将值作为value, 将这条记录封装为一个map集合。
          * queryForList():查询结果将结果集封装为list集合。
            * 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中。
          * query():查询结果,将结果封装为JavaBean对象。
          * query的参数:RowMapper
            * 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装。
            * new BeanPropertyRowMapper<类型>(类型.class)
          * queryForObject:查询结果,将结果封装为对象。
            * 一般用于聚合函数的查询


     面试题:数据库连接池的工作机制是什么?

      J2EE服务器启动时会建立一定数量的连接池,并一直维持不少于此数目的池连接。
      客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其标记为忙。
      如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量由配置参数决定。
      当使用的池连接调用完成后,池驱动程序将此连接标记为闲,其他调用就可以使用这个连接。
      实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关闭连接,而是把它代理的Connection对象还回到连接池中。

  • 相关阅读:
    tcp_wrapper过滤
    cobbler无人值守批量安装Linux系统
    PXE+kickstart无人值守安装CentOS 7
    kickstart文件详解
    SHELL脚本--shell数组基础
    SHELL脚本--管道和重定向基础
    第4章 DHCP服务
    第3章 NFS基本应用
    man sm-notify(sm-notify命令中文手册)
    man statd(rpc.statd中文手册)
  • 原文地址:https://www.cnblogs.com/sun9/p/13599394.html
Copyright © 2011-2022 走看看