JDBC连接池&DBUtils
JDBC连接池&DBUtils
勤劳的开发者px 发表于3个月前
JDBC连接池&DBUtils
  • 发表于 3个月前
  • 阅读 1
  • 收藏 0
  • 点赞 0
  • 评论 0

一,使用连接池重写工具类 


 1.为什么使用连接池重写工具类

- Connection对象在JDBC使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了.每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.程序初始化的时候,初始化多个连接,将多个连接放入到池(集合)中.每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中.

2.连接池原理 

![img](img/tu_1.png)

- 目的:解决建立数据库连接耗费资源和时间很多的问题,提高性能。

3.编写连接池 

3.1步骤

- 创建一个类,定义LInkedList集合作为连接池,在静态代码块中,向集合里面添加5个连接对象
- 添加addBack()方法,用作归还连接
 


public class MyDataSource {
    //连接池
    static LinkedList<Connection> pool = new LinkedList<>();
    //初始化连接
    static{
        try {
            for(int i = 0;i < 5;i++){
                pool.add(JdbcUtils.getConnection());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
    }
    
    //提供连接
    public Connection getConnection(){
        
        Connection connection = pool.removeFirst();
        return connection;
        
    }
    
    //归还连接的方法
    public  void addBack(Connection connection){
        //添加到最后
        pool.addLast(connection);
        
    }
    
    //返回pool里面连接的个数
    public int getCount(){
        return pool.size();
    }
    

}

3.2datasource接口概述

- Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商(用户)需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!
- 常见的连接池:DBCP、C3P0。

3.3编写连接池遇到的问题

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

3.4解决办法

- 继承
      条件:可以控制父类的构造


- 装饰者模式

  目的:改写已存在的类的某个方法或某些方法,装饰设计模式(包装模式)    

      条件:1.增强类和被增强类实现的是同一个接口
              2.增强类里面要拿到被增强类的引用


  步骤:

1. 编写一个类实现一个接口,为被增强类
2. 编写一个类,实现与被增强类相同的接口。(具备相同的行为)
3. 定义一个被增强类类型的变量。
4. 定义构造方法,把被增强类类的对象注入,给被增强类变量赋值。
5. 对于不需要改写的方法,调用被增强类类原有的方法。
6. 对于需要改写的方法,写自己的代码。

- 动态代理


3.5采用装饰者模式进行改造


4.常用连接池 

4.1 dbcp

4.1.1 dbcp概念

![img](img/tu_2.jpg)

+ DBCP:Apache推出的Database Connection Pool

核心API:

- basicDatasource
- basicDatasourceFactory

4.1.2使用步骤

- 添加jar包  commons-dbcp-1.4.jar  commons-pool-1.5.6.jar
- 添加配置文件到src目录
- 编写数据源工具类


1. 通过配置文件来编写

 

public class DBCPUtils {
    static DataSource ds;
    static {
        //只需要初始化一次
        try {
            Properties p = new Properties();
            InputStream is =JdbcUtils.class.getClassLoader()
.getResourceAsStream("dbcpconfig .properties");
            // InputStream is = new
            // FileInputStream("src/dbcpconfig.properties");
            p.load(is);
            ds = BasicDataSourceFactory.createDataSource(p);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    // 创建连接
        public static Connection getConnection() throws SQLException {
            // DriverManager.getConnection(url, user, password);  Connection
            Connection connection = ds.getConnection();
            return 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();
                }
            }
        }
}

2. 通过硬编码来表写(不需要配置文件)

   ```
   DataSource basicDataSource = new BasicDataSource();
   basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
   basicDataSource.setUrl("jdbc:mysql://localhost:3306/day01_1");
   basicDataSource.setUsername("root");
   basicDataSource.setPassword("123456");
   ```

   ​

4.2 c3p0

4.2.1 c3p0概念

![img](img/tu_3.jpg)

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

4.2.2使用步骤

- 添加jar包 
- 编写配置文件c3p0-config.xml,放在src中(注:文件名一定不要写错)
1. 通过配置文件来编写

public class C3P0Utils {
    //创建一个连接池对象
    static DataSource ds = new ComboPooledDataSource();
    //从池中获得一个连接
    public static Connection getConnection() throws SQLException{
        return ds.getConnection();
    }
    //释放资源
    public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            rs = null;
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            stmt = null;
        }
        if(conn!=null){
            try {
                conn.close();//放心的关。是否关闭取决连接是怎么来的
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            conn = null;
        }
    }
}

2. 通过硬编码来编写(不需要配置文件)

```
    DataSource cpds = new ComboPooledDataSource();
    cpds.setDriverClass("com.mysql.jdbc.Driver"); // loads the jdbc driver
    cpds.setJdbcUrl("jdbc:mysql://localhost:3306/day01_1");
    cpds.setUser("root");
    cpds.setPassword("ai1996");
```

二,使用DBUtils 增删改查的操作


- DBUtils就是JDBC的简化开发工具包。需要使用技术:连接池(获得连接)、SQL语句都没有少

DBUtils完成CRUD 

2.1概述

1. DBUtils是java编程中的数据库操作实用工具,小巧简单实用。 第一个操作数据库框架(jar),
2. DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。
3. Dbutils三个核心功能介绍

> QueryRunner中提供对sql语句操作的API.  update(), query()
> ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
> DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法

2.2QueryRunner核心类

- QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection 
- update(String sql, Object... params) ,执行更新数据 insert update delete  参数就是一个数组,参数个       数取决于语句中?的个数
- query(String sql, ResultSetHandler<T> rsh, Object... params) ,执行查询 select

2.3ResultSetHandler结果集处理类

Handler类型     说明      
ArrayHandler

将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值 

ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
BeanHandler 将结果集中第一条记录封装到一个指定的javaBean中
BeanListHandler 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
ColumnListHandler  将结果集中指定的列的字段值,封装到一个List集合中
KeyedHandler 将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。
MapHandler 将结果集中第一条记录封装到Map<String,Object>集合中,key就是字段名称,value就是字段值
MapListHandler 将结果集中每一条记录封装到Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。
ScalarHandler 它是用于单个数据。例如select  count(*) from 表操作。


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.4练习

开发步骤:


1. 创建项目,并导入jar包
2. 创建连接池
3. 编写测试类
增加

//向user表添加一条数据
    
    @Test
    public void  insert() throws SQLException{
        //创建queryRunner对象
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        
        //String sql = "insert into user values(null,'aaa','111','露西')";
        String sql = "insert into user values(?,?,?,?)";
        
        Object[] params ={null,"aaa","111","露西"};
        queryRunner.update(sql, params);
        
    }

更新

  //把用户名是aaa的user密码改成222
    
    @Test
    public  void update() throws SQLException{
        //创建queryRunner对象
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        
        String sql = "update user set password = ? where username = ?";
        Object[] params={"222","aaa"};
        queryRunner.update(sql, params);
        
    }

删除

    //把用户名是aaa的user给删除
    
    @Test
    public  void delete() throws SQLException{
        //创建queryRunner对象
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        
        String sql = "delete from user where username = ?";
        Object[] params={"aaa"};
        queryRunner.update(sql, params);
        
    }

通过id查询
 

 //查询id为1的用户信息
    
    @Test
    public  void selectById() throws SQLException{
        //创建queryRunner对象
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "select *from user where id = ?";
        Object[] params = {1};
        
        User user = queryRunner.query(sql, new BeanHandler<>(User.class), params);
        
        System.out.println(user.toString());
        
    }

查询所有列
 

    //查询所有的用户信息
    @Test
    public  void selectAll() throws SQLException{
        //创建queryRunner对象
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        
        String sql = "select *from user";
        Object[] params = {};
        
        List<User> list = queryRunner.query(sql, new BeanListHandler<>(User.class), params);
        
        System.out.println(list.toString());
        
    }

 总记录数


    //统计用户的个数
    
    @Test
    public  void getCount() throws SQLException{
        //创建queryRunner对象
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        
        String sql = "select count(*) from user";
        
        Long n = (Long) queryRunner.query(sql, new ScalarHandler());
        
        System.out.println(n.intValue());
    }


 

共有 人打赏支持
粉丝 2
博文 47
码字总数 96234
评论 (0)
×
勤劳的开发者px
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: