java学习记录三十三:连接池

一、连接池

一、解释

Connection对象在JDBC使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了(close).每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.

​ 程序初始化的时候,初始化多个连接,将多个连接放入到池(集合)中.每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中.
生活里面的连接池例子

  • 老方式:

    ​ 下了地铁需要骑车, 跑去生产一个, 然后骑完之后,直接把车销毁了.

  • 连接池方式 摩拜单车:

    ​ 骑之前, 有一个公司生产了很多的自行车, 下了地铁需要骑车, 直接扫码使用就好了, 然后骑完之后, 还回去

二、连接池原理

在这里插入图片描述

  1. 程序一开始就创建一定数量的连接,放在一个容器(集合)中,这个容器称为连接池。
  2. 使用的时候直接从连接池中取一个已经创建好的连接对象, 使用完成之后 归还到池子
  3. 如果池子里面的连接使用完了, 还有程序需要使用连接, 先等待一段时间(eg: 3s), 如果在这段时间之内有连接归还, 就拿去使用; 如果还没有连接归还, 新创建一个, 但是新创建的这一个不会归还了(销毁)
  4. 集合选择LinkedList
    • 增删比较快
    • LinkedList里面的removeFirst()和addLast()方法和连接池的原理吻合

使用连接池的目的: 可以让连接得到复用, 避免浪费

三、自定义连接池

  1. 创建一个类MyDataSource, 定义一个集合LinkedList
  2. 程序初始化的时候, 创建5个连接 存到LinkedList
  3. 定义getConnection() 从LinkedList取出Connection返回
  4. 定义addBack()方法归还Connection到LinkedList
public class MyDataSource1 {
    // 1.定义一个LinkedList集合,用来存储初始化的连接
    private static LinkedList<Connection> list = new LinkedList<>();

    // 2.初始化5个连接,并存储到集合中
    static {
        for (int i = 0; i < 5; i++) {
            try {
                // 获得连接
                Connection connection = JDBCUtils.getConnection();
                // 添加到集合中
                list.add(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 3.定义getAbc方法,用来获得连接
    public Connection getAbc(){
        Connection connection = list.removeFirst();
        return connection;
    }

    // 4.定义addBack方法,用来归还连接
    public void addBack(Connection connection){
        list.addLast(connection);
    }

    // 5.定义getCount方法,返回连接池中连接数量
    public static int getCount(){
        return list.size();
    }
}

// 测试
public class CRUDTest1 {
    // 查询记录
    @Test
    public void select() throws Exception {
        // 1.创建连接池对象
        MyDataSource1 dataSource = new MyDataSource1();
        System.out.println("获得连接之前,连接池中连接的数量:"+MyDataSource1.getCount());// 5

        // 2.获得连接
        Connection connection = dataSource.getAbc();

        // 2.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);
        // 3.设置参数
        ps.setInt(1,3);
        // 4.执行sql语句
        ResultSet resultSet = ps.executeQuery();
        // 封装,处理数据
        User user = null;
        while (resultSet.next()){
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println("获得连接之后,连接池中连接的数量:"+MyDataSource1.getCount());// 4
        System.out.println(user);

        // 5.释放资源
        // 归还连接
        dataSource.addBack(connection);
        JDBCUtils.release(resultSet,ps,null);

        System.out.println("归还连接之后,连接池中连接的数量:"+MyDataSource1.getCount());// 5

    }
}
  1. 创建一个类MyDataSource, 定义一个集合LinkedList
  2. 程序初始化(静态代码块)里面 创建5个连接存到LinkedList
  3. 定义提供Connection的方法
  4. 定义归还Connection的方法

四、优化自定义连接池

实现datasource完成自定义连接池,在上面的自定义连接池中, 我们定义的方法是getAbc(). 因为是自定义的.如果改用李四的自定义的连接池,李四定义的方法是getCon(), 那么我们的源码就需要修改, 这样不方便维护. 所以sun公司定义了一个接口DataSource,让自定义连接池有了规范

4.1datasource接口

Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商(用户)需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!
在这里插入图片描述

public class MyDataSource2 implements DataSource {
    // 1.定义一个LinkedList集合,用来存储初始化的连接
    private static LinkedList<Connection> list = new LinkedList<>();

    // 2.初始化5个连接,并存储到集合中
    static {
        for (int i = 0; i < 5; i++) {
            try {
                // 获得连接
                Connection connection = JDBCUtils.getConnection();
                // 添加到集合中
                list.add(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /*// 3.定义getAbc方法,用来获得连接
    public Connection getAbc(){
        Connection connection = list.removeFirst();
        return connection;
    }*/

    // 4.定义addBack方法,用来归还连接
    public void addBack(Connection connection){
        list.addLast(connection);
    }

    // 5.定义getCount方法,返回连接池中连接数量
    public static int getCount(){
        return list.size();
    }

    @Override
    public Connection getConnection() throws SQLException {
        Connection connection = list.removeFirst();
        return connection;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}


// 测试
public class CRUDTest2 {

    // 查询记录
    @Test
    public void select() throws Exception {
        // 1.创建连接池对象
        DataSource dataSource = new MyDataSource2();
        System.out.println("获得连接之前,连接池中连接的数量:"+MyDataSource2.getCount());// 5

        // 2.获得连接
        Connection connection = dataSource.getConnection();

        // 2.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);
        // 3.设置参数
        ps.setInt(1,3);
        // 4.执行sql语句
        ResultSet resultSet = ps.executeQuery();
        // 封装,处理数据
        User user = null;
        while (resultSet.next()){
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println("获得连接之后,连接池中连接的数量:"+MyDataSource2.getCount());// 4
        System.out.println(user);

        // 5.释放资源
        // 归还连接
        // 解决办法: 1.向下转型  2.增强Connection的close方法(默认是销毁连接,增强后变成归还连接)
        ((MyDataSource2)dataSource).addBack(connection);
        JDBCUtils.release(resultSet,ps,null);

        System.out.println("归还连接之后,连接池中连接的数量:"+MyDataSource2.getCount());// 5

    }
}

4.2总结

编写连接池遇到的问题

  • 实现DataSource接口后,addBack()不能调用了.
  • 能不能不引入新的api,直接调用之前的connection.close(),但是这个close不是关闭,是归还

解决办法

  • 继承

    • 条件:可以控制父类, 最起码知道父类的名字
  • 装饰者模式

    • 作用:改写已存在的类的某个方法或某些方法
    • 条件:
      • 增强类和被增强类实现的是同一个接口
      • 增强类里面要拿到被增强类的引用
  • 动态代理

五、最终版本连接池

使用装饰者模式改写connection的close()方法, 让connection归还

  • 什么是装饰者模式

    ​ 装饰者模式,是 23种常用的面向对象软件的设计模式之一. 动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。

    ​ 装饰者的作用:改写已存在的类的某个方法或某些方法, 增强方法的逻辑

  • 使用装饰者模式需要满足的条件

    • 增强类和被增强类实现的是同一个接口
    • 增强类里面要拿到被增强类的引用

实现步骤:

  1. 增强类和被增强类需要实现同一个接口
  2. 增强类里面需要得到被增强类的引用,
  3. 对于不需要改写的方法,调用被增强类原有的方法。
  4. 对于需要改写的方法写自己的代码
    接口:
public interface Star {
    public void sing();
    public void dance();
}
被增强的类: 
public class LiuDeHua implements Star {
    @Override
    public void sing() {
        System.out.println("刘德华唱忘情水...");
    }

    @Override
    public void dance() {
        System.out.println("刘德华跳霹雳舞...");
    }
}

增强的类:

public class LiuDeHuaWrapper implements Star {

    // 增强类中获得被增强类的引用
    LiuDeHua ldh;

    public LiuDeHuaWrapper(LiuDeHua ldh) {
        this.ldh = ldh;
    }

    @Override
    public void sing() {
        System.out.println("刘德华唱冰雨...");
        ldh.sing();
        System.out.println("刘德华唱练习...");
    }

    @Override
    public void dance() {
        // 不增强
        ldh.dance();
    }
}

测试

public class Test {
    public static void main(String[] args) {
        // 没有使用装饰者
        LiuDeHua ldh = new LiuDeHua();
        //ldh.sing();
        //ldh.dance();

        // 使用装饰者
        LiuDeHuaWrapper ldhw = new LiuDeHuaWrapper(ldh);
        ldhw.sing();
        ldhw.dance();
    }
}

自定义连接池终极版本
增强connection的close()方法, 其它的方法逻辑不改

  1. 创建MyConnection实现Connection
  2. 在MyConnection里面需要得到被增强的connection对象(通过构造方法传进去)
  3. 改写close()的逻辑, 变成归还
  4. 其它方法的逻辑, 还是调用被增强connection对象之前的逻辑。
    实现
    MyConnection
public class MyConnection implements Connection {

    // 获得被增强的连接对象的引用
    Connection con;

    // 获得连接池
    LinkedList<Connection> list;

    public MyConnection(Connection con, LinkedList<Connection> list) {
        this.con = con;
        this.list = list;
    }

    @Override
    public void close() throws SQLException {
        // 归还连接
        list.addLast(con);
    }

    @Override
    public Statement createStatement() throws SQLException {
        return con.createStatement();
    }
	// 必须写
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return con.prepareStatement(sql);
    }
	// 剩余的重写方法,使用被增强的连接对象调用原有方法...
    // ...
}

MyDataSource03

public class MyDataSource3 implements DataSource {
    // 1.定义一个LinkedList集合,用来存储初始化的连接
    private static LinkedList<Connection> list = new LinkedList<>();

    // 2.初始化5个连接,并存储到集合中
    static {
        for (int i = 0; i < 5; i++) {
            try {
                // 获得连接
                Connection connection = JDBCUtils.getConnection();
                // 添加到集合中
                list.add(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /*// 3.定义getAbc方法,用来获得连接
    public Connection getAbc(){
        Connection connection = list.removeFirst();
        return connection;
    }*/

    /*// 4.定义addBack方法,用来归还连接
    public void addBack(Connection connection){
        list.addLast(connection);
    }*/

    // 5.定义getCount方法,返回连接池中连接数量
    public static int getCount(){
        return list.size();
    }

    @Override
    public Connection getConnection() throws SQLException {
        Connection connection = list.removeFirst();// 返回的是被增强的连接对象
        // 增强
        MyConnection myConnection = new MyConnection(connection,list);
        return myConnection;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}

测试类

public class CRUDTest3 {

    // 查询记录
    @Test
    public void select() throws Exception {
        // 1.创建连接池对象
        DataSource dataSource = new MyDataSource3();
        System.out.println("获得连接之前,连接池中连接的数量:"+MyDataSource3.getCount());// 5

        // 2.获得连接
        Connection connection = dataSource.getConnection();// 返回的是增强的连接对象 MyConnection

        // 2.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);
        // 3.设置参数
        ps.setInt(1,3);
        // 4.执行sql语句
        ResultSet resultSet = ps.executeQuery();
        // 封装,处理数据
        User user = null;
        while (resultSet.next()){
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println("获得连接之后,连接池中连接的数量:"+MyDataSource3.getCount());// 4
        System.out.println(user);

        // 5.释放资源
        // 归还连接
        //connection.close();// 归还连接
        JDBCUtils.release(resultSet,ps,connection);

        System.out.println("归还连接之后,连接池中连接的数量:"+MyDataSource3.getCount());// 5

    }
}
  1. 创建一个MyConnection实现Connection
  2. 在MyConnection得到被增强的connection对象
  3. 改写MyConnection里面的close()方法的逻辑为归还
  4. MyConnection里面的其它方法 调用被增强的connection对象之前的逻辑
  5. 在MyDataSource03的getConnection()方法里面 返回了myConnection(增强的连接对象)

二、第三方连接池

常见的第三方连接池如下:

  • C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0是异步操作的,所以一些操作时间过长的JDBC通过其它的辅助线程完成。目前使用它的开源项目有Hibernate,Spring等。C3P0有自动回收空闲连接功能
  • 阿里巴巴-德鲁伊druid连接池:Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求。
  • DBCP(DataBase Connection Pool)数据库连接池,是Apache上的一个Java连接池项目,也是Tomcat使用的连接池组件。dbcp没有自动回收空闲连接的功能。

一、C3P0 连接池

  • C3P0开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用第三方工具需要导入jar包,c3p0使用时还需要添加配置文件c3p0-config.xml.
  • 使用C3P0需要添加c3p0-0.9.1.2.jar

1.通过硬编码来编写【了解】

  • 步骤
  1. 拷贝jar
  2. 创建C3P0连接池对象
  3. 从C3P0连接池对象里面获得connection
public class Test1_通过硬编码来编写 {
    public static void main(String[] args) throws Exception {
        // 1.拷贝c3p0jar包到模块下,并添加到classpath路径中
        // 2.创建连接池对象
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        // 连接池设置参数
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/day21_1");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        // 设置初始化连接数量
        dataSource.setInitialPoolSize(5);

        // 3.获得连接
        Connection connection = dataSource.getConnection();

        // 4.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);

        // 5.设置参数
        ps.setInt(1, 3);

        // 6.执行sql语句
        ResultSet resultSet = ps.executeQuery();

        // 封装,处理数据
        User user = null;
        while (resultSet.next()) {
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println(user);

        // 7.释放资源---连接归还
        JDBCUtils.release(resultSet,ps,connection);
    }
}

2 通过配置文件来编写【重点】

步骤:

  1. 拷贝jar
  2. 拷贝配置文件(c3p0-config.xml)到src目录【名字不要改
  3. 创建C3P0连接池对象【自动的读取】
  4. 从池子里面获得连接
  5. 实现:
  • 编写配置文件c3p0-config.xml,放在src目录下(注:文件名一定不要改)
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/day21_1</property>
		<property name="user">root</property>
		<property name="password">root</property>
		<property name="initialPoolSize">5</property>
	</default-config>
</c3p0-config>

编写Java代码 (会自动读取src目录下的c3p0-config.xml,所以不需要我们解析配置文件)

public class Test2_通过配置文件来编写 {
    public static void main(String[] args) throws Exception{
        // 1.拷贝c3p0jar包到模块下,并添加到classpath路径中
        // 2.创建连接池对象
        ComboPooledDataSource dataSource = new ComboPooledDataSource();

        // 3.获得连接
        Connection connection = dataSource.getConnection();

        // 4.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);

        // 5.设置参数
        ps.setInt(1, 3);

        // 6.执行sql语句
        ResultSet resultSet = ps.executeQuery();

        // 封装,处理数据
        User user = null;
        while (resultSet.next()) {
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println(user);

        // 7.释放资源---连接归还
        JDBCUtils.release(resultSet,ps,connection);
    }
}

3使用c3p0改写工具类【重点】

​ 我们之前写的工具类(JdbcUtils)每次都会创建一个新的连接, 使用完成之后, 都给销毁了; 所以现在我们要使用c3p0来改写工具类. 也就意味着,我们从此告别了JdbcUtils. 后面会使用c3p0写的工具类

思路:

  1. 创建C3P0Utils这个类
  2. 定义DataSource, 保证DataSource全局只有一个
  3. 定义getConnection()方法从DataSource获得连接
  4. 定义closeAll()方法 释放资源
import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @Author:pengzhilin
 * @Date: 2020/10/8 11:33
 */
public class C3P0Utils {
    // 创建c3p0连接池对象
    private static final ComboPooledDataSource DATA_SOURCE = new ComboPooledDataSource();

    /**
     * 获得连接的方法
     * @return  连接
     * @throws Exception
     */
    public static Connection getConnection() throws Exception{
        Connection connection = DATA_SOURCE.getConnection();
        return connection;
    }

    /**
     * 获得连接池的方法
     * @return
     */
    public static DataSource getDataSource(){
        return DATA_SOURCE;
    }

    /**
     * 释放资源
     *
     * @param resultSet
     * @param statement
     * @param connection
     */
    public static void release(ResultSet resultSet, Statement statement, Connection connection) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

4.小结

  1. C3P0 配置文件方式使用
    • 拷贝jar
    • 拷贝配置文件到src【配置文件的名字不要改】
    • 创建C3P0连接池对象
  2. C3P0工具类
    • 保证DataSource连接池只有一个【static】
    • 提供connection
    • 释放资源

二、DRUID

Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是国内目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。如:一年一度的双十一活动,每年春运的抢火车票。
Druid的下载地址:https://github.com/alibaba/druid

DRUID连接池使用的jar包:druid-1.0.9.jar
在这里插入图片描述

1.通过硬编码方式【了解】

步骤:

  1. 导入DRUID jar 包
  2. 创建Druid连接池对象, 配置4个基本参数
  3. 从Druid连接池对象获得Connection

实现:

public class Test1_硬编码方式使用 {
    @Test
    public void select() throws Exception{
        // 1.拷贝jar包,添加classpath路径
        // 2.创建Druid连接池对象
        DruidDataSource dataSource = new DruidDataSource();
        // 设置参数
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/day21_1");
        dataSource.setUsername("root");
        dataSource.setPassword("root");

        dataSource.setInitialSize(5);

        // 3.获得连接
        DruidPooledConnection connection = dataSource.getConnection();
78s
        // 4.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);

        // 5.设置参数
        ps.setInt(1, 3);

        // 6.执行sql语句
        ResultSet resultSet = ps.executeQuery();

        // 封装,处理数据
        User user = null;
        while (resultSet.next()) {
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println(user);

        // 7.释放资源---连接归还
        JDBCUtils.release(resultSet,ps,connection);
    }
}

2.通过配置文件方式【重点】

步骤:

  1. 导入DRUID jar 包
  2. 拷贝配置文件到src目录
  3. 根据配置文件创建Druid连接池对象
  4. 从Druid连接池对象获得Connection

实现:

  • 创建druid.properties, 放在src目录下
url=jdbc:mysql://localhost:3306/day21_1
username=root
password=root
driverClassName=com.mysql.jdbc.Drive

java代码

public class Test2_配置文件方式使用 {
    @Test
    public void select() throws Exception{
        // 1.拷贝jar包,添加classpath路径
        // 2.创建Druid连接池对象
        Properties prop = new Properties();
        // 加载配置文件
        InputStream is = Test2_通过配置文件来编写.class.getClassLoader().getResourceAsStream("druid.properties");
        prop.load(is);
        // 创建Druid连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        // 3.获得连接
        Connection connection = dataSource.getConnection();

        // 4.书写sql语句,预编译sql语句,得到预编译对象
        String sql = "select * from user where id = ?";
        PreparedStatement ps = connection.prepareStatement(sql);

        // 5.设置参数
        ps.setInt(1, 3);

        // 6.执行sql语句
        ResultSet resultSet = ps.executeQuery();

        // 封装,处理数据
        User user = null;
        while (resultSet.next()) {
            user = new User();
            user.setId(resultSet.getInt("id"));
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            user.setNickname(resultSet.getString("nickname"));
        }
        System.out.println(user);

        // 7.释放资源---连接归还
        JDBCUtils.release(resultSet,ps,connection);
    }
}

3.小结

  1. Druid配置文件使用
    • 拷贝jar
    • 拷贝配置文件到src
    • 读取配置文件成properties对象
    • 使用工厂根据properties创建DataSource
    • 从DataSource获得Connection
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值