1、概念:其实就是一个容器(集合),存放数据库连接的容器。

         当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

2、好处:1. 节约资源,2. 用户访问高效。

3、实现:

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

    1. 方法:

      *   获取连接:getConnection()

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

               2. 一般我们不去实现它,有数据库厂商来实现

      1. C3P0:数据库连接池技术
      2. Druid:数据库连接池实现技术,由阿里巴巴提供的
4. C3P0:数据库连接池技术
  * 步骤:
    1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
      * 不要忘记导入数据库驱动jar包

       2. 定义配置文件:

      * 名称: c3p0.properties 或者 c3p0-config.xml
      * 路径:直接将文件放在src目录下即可。

       3. 创建核心对象 数据库连接池对象 ComboPooledDataSource

       4. 获取连接: getConnection

复制代码
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 {
        //新建连接池
        DataSource ds = new ComboPooledDataSource();
        //获取连接
        Connection conn = ds.getConnection();
        //打印连接
        System.out.println(
                conn
        );
    }
}
复制代码

 

 C3P0的配置文件:
复制代码
<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
      <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/test02</property>
    <property name="user">root</property>
    <property name="password">123456</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/day25</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>
复制代码

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

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

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class druidDemo1 {
    public static void main(String[] args) throws Exception {
        //
        Properties pro = new Properties();
        InputStream is =druidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        //
        DataSource ds =DruidDataSourceFactory.createDataSource(pro);
        Connection conn =ds.getConnection();
        System.out.println(conn);
    }
}
复制代码

   5.2、定义工具类

 1. 定义一个类 JDBCUtils

   2. 提供静态代码块加载配置文件,初始化连接池对象

   3. 提供方法
  1. 获取连接方法:通过数据库连接池获取连接
  2. 释放资源
  
复制代码
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtils {
    private static DataSource ds;
    static{
        //自动获取连接
        try {
            Properties pro= new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            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 stat,Connection conn) throws SQLException {
        if(stat != null){
            stat.close();
        }
        if(conn != null){
            conn.close();
        }
    }
    //
    public static void close(ResultSet rs, Statement stat, Connection conn) throws SQLException {
        if(stat != null){
            stat.close();
        }
        if(conn != null){
            conn.close();
        }
        if(rs != null){
            rs.close();
        }
    }
    //获取连接池
    public static DataSource getDataSource(){
        return ds;
    }
}
复制代码

 编写JDBCUtil方法后的写法

复制代码
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class druidDemo2 {
    public static void main(String[] args) throws SQLException {
       // JDBCUtils utils = new JDBCUtils();
        Connection conn=JDBCUtils.getConnection();
        PreparedStatement ps =conn.prepareStatement("insert into app08_publisher values (?,?)");
        ps.setInt(1,5);
        ps.setString(2,"贵州省税务局出版社");
        int rows =ps.executeUpdate();
        System.out.println(rows);
        JDBCUtils.close(ps,conn);
       // ResultSet rs=conn.createStatement().executeQuery("select *  FROM app08_publisher");
//        while (rs.next()){
//            int i= rs.getInt("id");
//            String publish=rs.getString("name");
//            System.out.println("编号:"+i+",出版社名称:"+publish);
//        }
        //System.out.println(conn);
    }
}
复制代码

 6、Spring JDBC

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

   6.2  步骤:

   1. 导入jar包
   2. 创建JdbcTemplate对象。依赖于数据源DataSource
   * JdbcTemplate template = new JdbcTemplate(ds);
   3  调用JdbcTemplate的方法来完成CRUD的操作
    *  update():执行DML语句。增、删、改语句
      *  queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
       * 注意:这个方法查询的结果集长度只能是1
      * queryForList():查询结果将结果集封装为list集合
            * 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
      * query():查询结果,将结果封装为JavaBean对象
      * query的参数:RowMapper
        * 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
          * new BeanPropertyRowMapper<类型>(类型.class)
    * queryForObject:查询结果,将结果封装为对象
      * 一般用于聚合函数的查询
  6.3 示例
     * 需求:
    1. 修改1号数据的 name 
    2. 添加一条记录
    3. 删除刚才添加的记录
    4. 查询id为1的记录,将其封装为Map集合
    5. 查询所有记录,将其封装为List
    6. 查询所有记录,将其封装为Emp对象的List集合
    7. 查询总记录数
    
复制代码
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class JDBCTemplate02 {
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    @Test
    public void test01(){
        String sql="update app08_publisher set name = '贵州省税务局出版社' where id =?";
        int n=template.update(sql,5);
        System.out.println(n);
    }

    @Test
    public void test02(){
        String sql="insert into app08_publisher (id,name) values(?,?)";
        int n = template.update(sql,6,"机械出版社");
        System.out.println(n);
    }

    @Test
    public void test03(){
        String sql="delete from app08_publisher where id = ?";
        int n = template.update(sql,6);
        System.out.println(n);
    }

    @Test
    public void test04(){
        String sql="select *  from app08_publisher where id = ?";
        Map<String, Object> map = template.queryForMap(sql, 1);
        System.out.println(map);
    }

    @Test
    public void test05(){
        String sql="select *  from app08_publisher";
        List<Map<String, Object>> maps = template.queryForList(sql);
        System.out.println(maps);
    }

    @Test
    public void test06(){
        String sql="select *  from app08_publisher";
        List<Map<String, Object>> maps = template.queryForList(sql);
        //System.out.println(maps);
        for(Map<String, Object> map : maps){
            System.out.println(map);
        }
    }

    @Test
    public void test07(){
        String sql="select *  from app08_publisher";
        List<Publish> list = template.query(sql, new RowMapper<Publish>() {
            @Override
            public Publish mapRow(ResultSet resultSet, int i) throws SQLException {
                Publish pu = new Publish();
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                pu.setId(id);
                pu.setName(name);
                return pu;
            }
        });
        for(Publish p:list){
            System.out.println(p);
        }

    }
    @Test
    public void test08(){
        String sql="select *  from app08_publisher";
        List<Publish> list = template.query(sql, new BeanPropertyRowMapper<Publish>(Publish.class));
        for(Publish pu :list){
            System.out.println(pu);
        }

    }
    @Test
    public void test09(){
        String sql="select count(1) from app08_publisher";
        Long l=template.queryForObject(sql,Long.class);
        System.out.println(l);

    }
}
复制代码