dbcp c3p0(内含工具类)及dbutils总结

一 配置文件

1 常见的配置文件格式:
  • properties 里面内容的格式 key=value(并且不用写“”)

  • xml

若我们的配置文件为properties,并且放在src目录下.
我们可以通过 ResourceBundle类快速获取里面的配置信息
使用步骤:
1.获取ResourceBundle 对象:
static ResourceBundle getBundle("文件名称不带后缀名")
2.通过ResourceBundle 对象获取配置信息
String getString(String key) :通过执行key获取指定的value

Demo:
jdbc.properties(我们在src目录下创建此文件 内容如下)

# 配置文件 里面是key value的形式
# java 的使用  通过ResourceBoundle对象快速获得 骚的一批
driverclass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day07
user=root
password=123456

写个测试类读取信息:

package jdbc;

import java.util.ResourceBundle;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args){
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");
        System.out.println(rb.getString("driverclass"));
        System.out.println(rb.getString("url"));
        System.out.println(rb.getString("user"));
        System.out.println(rb.getString("password"));
    }
}

输出:
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/day07
root
123456

Process finished with exit code 0

2 配置文件方式优点

操作方便,方便修改防止硬编码,(xml的方式就不再举例子了,后面会有)

二 常用的连接池(理解即可)

  • DBCP
  • C3P0
1 dbcp连接池:

所属:apache组织的
使用步骤:

  • 导入jar包(commons-dbcp-1.4.jar和commons-pool-1.5.6.jar)
  • 使用api
    使用api分为硬编码方式和非硬编码方式
    (硬编码方式就是通过类设置属性,非硬编码就是属性存配置文件,我们读取)

1.1举个栗子

硬编码方式:
package jdbc;

import org.apache.commons.dbcp.BasicDataSource;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ResourceBundle;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args){
        //创建连接池
        BasicDataSource ds = new BasicDataSource();
        //手动设置配置信息
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql:///day07");
        ds.setUsername("root");
        ds.setPassword("1234");
        // 获得连接
        try {
            Connection connection = ds.getConnection();
            // 执行 sql 获得结果等等。。。。。。
            // 略
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}

-----------------------------------------------------------------
非硬编码方式:
package jdbc;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import java.util.ResourceBundle;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args) throws Exception {

        //存放配置文件
        Properties prop = new Properties();
        // 直接加载 就行
        prop.load(new FileInputStream("src/dbcp.properties"));
       // prop.setProperty("driverClassName", "com.mysql.jdbc.Driver");// 也是硬编码方式 不使用

        //创建连接池
        DataSource ds = BasicDataSourceFactory.createDataSource(prop);
        
        // 获得连接
        ds.getConnection();
        // 下面相同  略。。。。。

    }
}


2 c3p0连接池

所属:c3p0 组织开发
使用:hibernate和spring使用
相对来说优点:有自动回收空闲连接的功能.(dbcp没有此功能)
使用步骤:

  • 导入jar包(c3p0-0.9.1.2.jar)
  • 使用api

举个栗子

配置文件 c3p0.properties(名字固定)

#固定的键一定不能错
#文件的命名也是固定的不能改变   (文件名)
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/day07
c3p0.user=root
c3p0.password=123456
package jdbc;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class C3p0Demo {
    public static void main(String[] args) throws Exception {
        ComboPooledDataSource pool = new ComboPooledDataSource();
        // 硬编码方式 不推荐使用 推荐使用 配置文件(配置好直接new 对象就能使用 底层帮我们做了设置功能)
//        pool.setDriverClass("com.mysql.jdbc.Driver");
//        pool.setJdbcUrl("jdbc:mysql://localhost:3306/day07");
//        pool.setUser("root");
//        pool.setPassword("123456");
        Connection connection = pool.getConnection();
        String sql = "SELECT * FROM CATEGORY";
        PreparedStatement prst = connection.prepareStatement(sql);
        ResultSet rs = prst.executeQuery();
        while (rs.next()) {
            System.out.println(rs.getString("cid") + "::" + rs.getString("cname"));
        }
        // 调用工具类
        JdbcUtil.releaseResource(connection, prst, rs);

    }
}

附:c3p0-config.xml(使用xml方式的也行 如下 , 文件名不能错)

<c3p0-config>
    <!-- 默认配置,如果没有指定则使用这个配置 -->
    <!-- 和properties 类似键不能错,是规定好的,值可以自己输入-->
    <default-config>
        <!-- 基本配置 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day07</property>
        <property name="user">root</property>
        <property name="password">123456</property>
    
        <!--扩展配置-->
        <property name="checkoutTimeout">30000</property>
        <property name="idleConnectionTestPeriod">30</property>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>
    </default-config> 
    
    
    <!-- 命名的配置 -->
    <named-config name="itcast">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
        <property name="user">root</property>
        <property name="password">1234</property>
        
        
        <!-- 如果池中数据连接不够时一次增长多少个 -->
        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">20</property>
        <property name="minPoolSize">10</property>
        <property name="maxPoolSize">40</property>
        <property name="maxStatements">20</property>
        <property name="maxStatementsPerConnection">5</property>
    </named-config>
</c3p0-config> 

三 dbutils

1 前文讲了获连接池的几种方式这里可以进行封装下方便使用
DataSourceUtils.java (连接池相关封装工具类)
package jdbc;

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;

/**
 * Create by SunnyDay on 2018/11/12
 *
 * usage: 使用本工具要求:
 * 1首先导包(c3p0)
 * 2其次写配置文件(写好就行 ,工具会自动检测)
 * 3 写sql 获得结果
 */
public class DataSourceUtils {
    private static ComboPooledDataSource pool = new ComboPooledDataSource();
    /**
     * 获取连接池
     * @return 连接池(c3p0 的连接池 使用本工具类 要导包)
     * */
    public static DataSource getDataSource(){
        return  pool;
    }

    /**
     * 获取连接
     * @return 连接
     * */
    public static Connection getConnection() throws SQLException {
        return pool.getConnection();
    }


    /**
     *
     * 释放资源
     * @param  conn 连接
     * @param  statement 预编译
     * @param  resultSet 结果集合
     * */
    public static void releaseResource(Connection conn, Statement statement, ResultSet resultSet) {
        closeResultSet(resultSet);
        closeStatement(statement);
        closeConnnection(conn);
    }

    //关闭连接
    private static void closeConnnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 关闭结果集合
    private static void closeResultSet(ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 关闭预编译状态
    private static void closeStatement(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

2 有了连接池工具类我们就可以结合dbutils快速实现curd了

dbutils简介:是apache组织的一个工具类,jdbc的框架,更方便我们使用
使用步骤:
2.1.导入jar包(commons-dbutils-1.4.jar)
2.2创建一个queryrunner类
queryrunner作用:操作sql语句
构造方法:
new QueryRunner(Datasource ds);
2.3.编写sql
2.4.执行sql
query(..):执行r操作
update(...):执行cud操作
2.5简单的代码实现

package jdbc;

import org.apache.commons.dbutils.QueryRunner;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args) throws Exception {
        // 获得对象 通过构造函数(参数DataSource接口子类)
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        // 写sql
        String sql = "insert into category values(?,?)";
        // 执行sql
        qr.update(sql, "c201", "厨电");
    }
}

查看数据库(插入成功):


image.png

看过我们的测试类感慨万千,以前读取数据库的数据,操作数据库时,写了七八步呢,这里三行代码就插入一条数据这就ojbk了快乐了。
(有了框架工具类就是快乐了 哈哈)

3 dbutils 的api

有了上面的例子我们就接下来详细的总结一下api的使用

核心类或者接口:
1 QueryRunner:类名
        作用:操作sql语句
        构造器:
            new QueryRunner(Datasource ds);
        注意:(使用这个构造时)
            底层帮我们创建连接,创建语句执行者 ,释放资源.
        常用方法:
            query(..):
            update(..):

2 DbUtils:释放资源,控制事务 类
        closeQuietly(conn):内部处理了异常
        commitAndClose(Connection conn):提交事务并释放连接

3 ResultSetHandler:封装结果集 接口
   实现类:
         (了解)ArrayHandler, 将查询结果的第一条记录封装成数组,返回。
         (了解)ArrayListHandler, 将查询结果的每一条记录封装成数组,将每一个数组放入list中返回。
         ★★BeanHandler, 将查询结果的第一条记录封装成指定的bean对象,返回。
         ★★BeanListHandler, 将查询结果的每一条记录封装成指定的bean对象,将每一个bean对象放入list中 返回.
         (了解)ColumnListHandler, 将查询结果的指定一列放入list中返回 。
         (了解)MapHandler, 将查询结果的第一条记录封装成map,字段名作为key,值为value 返回。
         ★MapListHandler, 将查询结果的每一条记录封装map集合,将每一个map集合放入list中返回。
         ★ScalarHandler,针对于聚合函数(一个返回值) 例如:count(*) 返回的是一个Long值。


1ResultSetHandler 实现类的简单栗子


 (了解)ArrayHandler, 将查询结果的第一条记录封装成数组,返回。



package jdbc;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;

import java.util.Arrays;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args) throws Exception {
        // 获得对象 通过构造函数(参数DataSource接口子类)
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        // 写sql
        String sql = "select * from category";
        // 执行sql
        Object[] query = qr.query(sql, new ArrayHandler());
        System.out.println(Arrays.toString(query));
    }
}

 输出:[c001, 电器]   查询记录中的第一条
(了解)ArrayListHandler, 将查询结果的每一条记录封装成数组,将每一个数组放入list中返回


package jdbc;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;

import java.util.Arrays;
import java.util.List;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args) throws Exception {
        // 获得对象 通过构造函数(参数DataSource接口子类)
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        // 写sql
        String sql = "select * from category";
        // 执行sql
        List<Object[]> query = qr.query(sql, new ArrayListHandler());
        for (Object[] o :query){
            System.out.println(Arrays.toString(o));
        }
    }
}

结果:
[c001, 电器]
[c002, 服饰]
[c003, 化妆品]
[c004, 哈哈]
[c201, 厨电]
重要的栗子 ★★BeanHandler, 将查询结果的第一条记录封装成指定的bean对象,返回

首先搞个bean类如下(Category.java)

package domain;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Category {
    private String cid;
    private String cname;

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Category{" +
                "cid='" + cid + '\'' +
                ", cname='" + cname + '\'' +
                '}';
    }
}

测试类:

package jdbc;

import domain.Category;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.util.Arrays;
import java.util.List;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args) throws Exception {
        // 获得对象 通过构造函数(参数DataSource接口子类)
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        // 写sql
        String sql = "select * from category";
        // 执行sql
       Category category =  qr.query(sql, new BeanHandler<>(Category.class));
        System.out.println(category.toString());
    }
}


结果:
  Category{cid='c001', cname='电器'}
  ★★BeanListHandler, 将查询结果的每一条记录封装成指定的bean对象,将 每一个bean对象
  放入list中返回(不在举例子 )

★ScalarHandler,针对于聚合函数 例如:count(*) 返回的是一个Long值Demo
package jdbc;

import domain.Category;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.util.Arrays;
import java.util.List;

/**
 * Create by SunnyDay on 2018/11/12
 */
public class Test0 {
    public static void main(String[] args) throws Exception {
        // 获得对象 通过构造函数(参数DataSource接口子类)
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        // 写sql
        String sql = "select count(*) from category";
        // 执行sql
       Object obj =  qr.query(sql, new ScalarHandler());
        System.out.println(obj);
    }
}

结果:
5

Process finished with exit code 0

四 完结!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容