【JDBC&Dbutils】JDBC&JDBC连接池&DBUtils使用方法(重要)

-----------------------JDBC----------

0.      db.properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=utf8
username=root
password=root

 

1.原始的获取connection的方法:(配置信息写在程序里面,不读取db.properties文件)

package cn.itheima.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 提供获取连接和释放资源的 方法
 * 
 * @version V1.0
 */
public class JDBCUtils_V1 {

    /**
     * 获取连接方法
     * 
     * @return
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web08", "root", "root");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

 

2.通过ResourceBundle  读取properties文件获取配置信息(使用方法参考:http://www.cnblogs.com/qlqwjy/p/7530715.html)

package cn.itheima.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;

/**
 * 提供获取连接和释放资源的 方法
 * 
 * @version V1.0
 */
public class JDBCUtils_V2 {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    
    /**
     * 静态代码块加载配置文件信息
     */
    static{
        ResourceBundle bundle = ResourceBundle.getBundle("db");
        driver = bundle.getString("driver");
        url = bundle.getString("url");
        username = bundle.getString("username");
        password = bundle.getString("password");
    }

    /**
     * 获取连接方法
     * 
     * @return
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

 

3.通过ClassLoader读取properties文件获取连接

package cn.itheima.jdbc;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import java.util.ResourceBundle;

/**
 * 提供获取连接和释放资源的 方法
 * @version V1.0
 */
public class JDBCUtils_V3 {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    /**
     * 静态代码块加载配置文件信息
     */
    static {
        try {
            // 1.通过当前类获取类加载器
            ClassLoader classLoader = JDBCUtils_V3.class.getClassLoader();
            // 2.通过类加载器的方法获得一个输入流
            InputStream is = classLoader.getResourceAsStream("db.properties");
            // 3.创建一个properties对象
            Properties props = new Properties();
            // 4.加载输入流
            props.load(is);
            // 5.获取相关参数的值
            driver = props.getProperty("driver");
            url = props.getProperty("url");
            username = props.getProperty("username");
            password = props.getProperty("password");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取连接方法
     * 
     * @return
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

 

 

 

上面三个工具的使用及测试方法:

package cn.itheima.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import cn.itheima.jdbc.JDBCUtils_V1;
import cn.itheima.jdbc.JDBCUtils_V2;
import cn.itheima.jdbc.JDBCUtils_V3;

/**
 * 测试工具类
 * 
 * @version V1.0
 */
public class TestUtils {
    /**
     * 根据id更新用户信息方法
     */
    @Test
    public void testUpdateById() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            // 1.获取连接
            conn = JDBCUtils_V3.getConnection();
            // 2.编写sql语句
            String sql = "update tbl_user set upassword=? where uid=?";
            // 3.获取执行sql语句对象
            pstmt = conn.prepareStatement(sql);
            // 4.设置参数
            pstmt.setString(1, "999");
            pstmt.setInt(2, 3);
            // 5.执行更新操作
            int row = pstmt.executeUpdate();
            if (row > 0) {
                System.out.println("更新成功!");
            } else {
                System.out.println("更新失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 6.释放资源
            JDBCUtils_V3.release(conn, pstmt, null);
        }
    }

    /**
     * 根据id删除信息方法
     */
    @Test
    public void testDeleteById() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            // 1.获取连接
            conn = JDBCUtils_V3.getConnection();
            // 2.编写sql语句
            String sql = "delete from tbl_user where uid=?";
            // 3.获取执行sql语句对象
            pstmt = conn.prepareStatement(sql);
            // 4.设置参数
            pstmt.setInt(1, 4);
            // 5.执行删除操作
            int row = pstmt.executeUpdate();
            if (row > 0) {
                System.out.println("删除成功!");
            } else {
                System.out.println("删除失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 6.释放资源
            JDBCUtils_V3.release(conn, pstmt, null);
        }
    }

    /**
     * 添加用户信息方法
     */
    @Test
    public void testAdd() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            // 1.获取连接
            conn = JDBCUtils_V2.getConnection();
            // 2.编写sql语句
            String sql = "insert into tbl_user values(null,?,?)";
            // 3.获取执行sql语句对象
            pstmt = conn.prepareStatement(sql);
            // 4.设置参数
            pstmt.setString(1, "lisi");
            pstmt.setString(2, "hehe");
            // 5.执行插入操作
            int row = pstmt.executeUpdate();
            if (row > 0) {
                System.out.println("添加成功!");
            } else {
                System.out.println("添加失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 6.释放资源
            JDBCUtils_V2.release(conn, pstmt, null);
        }
    }

    /**
     * 根据id查询用户信息
     */
    @Test
    public void testFindUserById() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            // 1.获取连接
            conn = JDBCUtils_V1.getConnection();
            // 2.编写sql语句
            String sql = "select * from tbl_user where uid=?";
            // 3.获取执行sql语句对象
            pstmt = conn.prepareStatement(sql);
            // 4.设置参数
            pstmt.setInt(1, 2);
            // 5.执行查询操作
            rs = pstmt.executeQuery();
            // 6.处理结果集
            while (rs.next()) {
                System.out.println(rs.getString(2) + "----" + rs.getString("upassword"));
            }
            // 释放资源放在此处行么?【不行滴!】
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 7.释放资源
            JDBCUtils_V1.release(conn, pstmt, rs);
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

--------------------自定义连接池--------------------------

1.连接池介绍

 

1.1.1          原理:

传统JDBC的操作,对连接的对象销毁不是特别好.每次创建和销毁连接都是需要花费时间.可以使用连接池优化的程序.(解决性能问题)

* 在程序开始的时候,可以创建几个连接,将连接放入到连接池中.用户使用连接的时候,可以从连接池中进行获取.用完之后,可以将连接归还连接池.

  使用数据源:就是不让连接关闭才使用的,这样就能节省创建链接浪费的时间(调用close()是还到池子里--LinkedList)

 

1.2.2 规范:

SUN公司提供了一个连接池的公共接口.(javax.sql.DataSource)。各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的 切换不同厂商的连接池!

常见的连接池:DBCP   C3P0  

 

2.自定义连接池:

 

2.1     技术分析:

 

【自定义连接池的代码】

  静态代码块中初始化五个Connection对象

package cn.itheima.jdbc.DataSource;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;

import javax.sql.DataSource;

import cn.itheima.jdbc.utils.JDBCUtils_V3;

public class MyDataSource implements DataSource{
    //1.创建1个容器用于存储Connection对象
    private static LinkedList<Connection> pool = new LinkedList<Connection>();
    
    //2.创建5个连接放到容器中去
    static{
        for (int i = 0; i < 5; i++) {
            Connection conn = JDBCUtils_V3.getConnection();
            pool.add(conn);
        }
    }
    
    /**
     * 重写获取连接的方法
     */
    @Override
    public Connection getConnection() throws SQLException {
        Connection conn = null;
        //3.使用前先判断
        if(pool.size()==0){
            //4.池子里面没有,我们再创建一些
            for (int i = 0; i < 5; i++) {
                conn = JDBCUtils_V3.getConnection();
                pool.add(conn);
            }
        }
        //5.从池子里面获取一个连接对象Connection
        conn = pool.remove(0);
        return conn;
    }

    /**
     * 归还连接对象到连接池中去
     */
    public void backConnection(Connection conn){
        pool.add(conn);
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

}

 

 测试自定义连接池添加用户:

    /**
     * 添加用户
     * 使用未改造过的connection
     */
    @Test
    public void testAddUser() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        // 1.创建自定义连接池对象
        MyDataSource dataSource = new MyDataSource();
        try {
            // 2.从池子中获取连接
            conn = dataSource.getConnection();
            String sql = "insert into tbl_user values(null,?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "吕布");
            pstmt.setString(2, "貂蝉");
            int rows = pstmt.executeUpdate();
            if (rows > 0) {
                System.out.println("添加成功!");
            } else {
                System.out.println("添加失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            dataSource.backConnection(conn);
        }
    }

 

 

【自定义连接池中问题及如何解决】

  • 问题?
用户调用getConnection获得连接后,必须调用dataSource.backConnection(conn);归还连接,如果调用conn.close()还是释放连接,连接将不存在,连接池中也将无连接可用。
此时我们希望用户调用close()方法后,连接归还给连接池。对close()方法进行增,调用close方法的时候归还连接而不释放连接,需要对方法进行增强。
  • 解决:

不额外提供API方法,就可以解决上述两个问题!!!

  能不能还调用Connection的close方法.能不能增强Connection的close方法,原有的销毁变为归还!!!

  • 如何增强Connectionclose方法:

* 增强一个Java类中的某个方法有几种方式???

【继承和装饰者的案例】

/**

 * 继承的方式增强一个类中某个方法:

 */

class Man{

    public void run(){

        System.out.println("跑....");

    }

}

 

class SuperMan extends Man{

    public void run(){

        // super.run();

        System.out.println("飞....");

    }

}

 

 

/**

 * 使用装饰者的方式完成类的方法的增强

 */

interface Waiter{

    public void server();

}

 

class Waiteress implements Waiter{

 

    @Override

    public void server() {

        System.out.println("服务...");

    }

   

}

 

class WaiteressWrapper implements Waiter{

    private Waiter waiter;

 

    public WaiteressWrapper(Waiter waiter) {

    this.waiter = waiter;

    }

   

    @Override

    public void server() {

        System.out.println("微笑...");

        // this.waiter.server();

       

    }

   

}

 

【使用装饰者模式增强Connection的close方法】

package cn.itheima.jdbc.DataSource;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

//1.实现同一个接口Connection
public class MyConnection implements Connection {
    //3.定义一个变量
    private Connection conn;
    
    private LinkedList<Connection> pool;
    
    // 2.编写一个构造方法(参数使用了面相对象的多态特性)
    public MyConnection(Connection conn,LinkedList<Connection> pool) {
        this.conn=conn;
        this.pool=pool;
    }
    
    //4.书写需要增强的方法
    @Override
    public void close() throws SQLException {
        pool.add(conn);
    }

    /**
     * 此方法必须覆盖!否则会出现空指针异常!!!
     */
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return conn.prepareStatement(sql);
    }
    
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }
    ...

}

改造后的连接池:(池子中放的是增强close方法后的Conection)

package cn.itheima.jdbc.DataSource;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;

import javax.sql.DataSource;

import cn.itheima.jdbc.utils.JDBCUtils_V3;

public class MyDataSource1 implements DataSource{
    //1.创建1个容器用于存储Connection对象
    private static LinkedList<Connection> pool = new LinkedList<Connection>();
    
    //2.创建5个连接放到容器中去
    static{
        for (int i = 0; i < 5; i++) {
            Connection conn = JDBCUtils_V3.getConnection();
            //放入池子中connection对象已经经过改造了
            MyConnection myconn = new MyConnection(conn, pool);
            pool.add(myconn);
        }
    }
    
    /**
     * 重写获取连接的方法
     */
    @Override
    public Connection getConnection() throws SQLException {
        Connection conn = null;
        //3.使用前先判断
        if(pool.size()==0){
            //4.池子里面没有,我们再创建一些
            for (int i = 0; i < 5; i++) {
                conn = JDBCUtils_V3.getConnection();
                //放入池子中connection对象已经经过改造了
                MyConnection myconn = new MyConnection(conn, pool);
                pool.add(myconn);
            }
        }
        //5.从池子里面获取一个连接对象Connection
        conn = pool.remove(0);
        return conn;
    }

    /**
     * 归还连接对象到连接池中去
     */
    public void backConnection(Connection conn){
        pool.add(conn);
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

}

 

 测试:

    /**
     * 添加用户
     * 使用改造过的connection
     */
    @Test
    public void testAddUser1() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        // 1.创建自定义连接池对象
        DataSource dataSource = new MyDataSource1();
        try {
            // 2.从池子中获取连接
            conn = dataSource.getConnection();
            String sql = "insert into tbl_user values(null,?,?)";
            //3.必须在自定义的connection类中重写prepareStatement(sql)方法
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "吕布1");
            pstmt.setString(2, "貂蝉1");
            int rows = pstmt.executeUpdate();
            if (rows > 0) {
                System.out.println("添加成功!");
            } else {
                System.out.println("添加失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtils_V3.release(conn, pstmt, null);
        }
    }

 

   JDBCUtils_V3.release(conn, pstmt, null)中调用的close()方法是自定义的MyConnection 的close()方法。

 

--------------------------C3P0与DBCP-----------------------------

【常见的开源的数据库连接池】:

  • DBCP:

DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。

  • C3P0:

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

  • Tomcat内置连接池:

【DBCP连接池的使用】

第一步:引入DBCP连接池的jar包.

第二步:编写DBCP代码:

    * 手动设置参数:

    * 配置文件设置参数:

 

 

配置文件:

 

  @Test

    /**

     * 手动方式:

     */

    public void demo1(){

        Connection conn = null;

        PreparedStatement stmt = null;

        ResultSet rs = null;

        BasicDataSource dataSource = new BasicDataSource();

        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        dataSource.setUrl("jdbc:mysql:///web_07");

        dataSource.setUsername("root");

        dataSource.setPassword("123");

        try{

            // 获得连接:

            conn = dataSource.getConnection();

            // 编写SQL:

            String sql = "select * from category";

            // 预编译SQL:

            stmt = conn.prepareStatement(sql);

            // 执行SQL:

            rs = stmt.executeQuery();

            while(rs.next()){

                System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));

            }

        }catch(Exception e){

            e.printStackTrace();

        }finally{

            JDBCUtils.release(rs,stmt, conn);

        }

    }

   

    @Test

    /**

     * 配置文件方式:

     */

    public void demo2(){

        Connection conn = null;

        PreparedStatement stmt = null;

        ResultSet rs = null;

        Properties properties = new Properties();

       

        try{

            properties.load(new FileInputStream("src/db.properties"));

            DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);

            // 获得连接:

            conn = dataSource.getConnection();

            // 编写SQL:

            String sql = "select * from category";

            // 预编译SQL:

            stmt = conn.prepareStatement(sql);

            // 执行SQL:

            rs = stmt.executeQuery();

            while(rs.next()){

                System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));

            }

        }catch(Exception e){

            e.printStackTrace();

        }finally{

            JDBCUtils.release(rs,stmt, conn);

        }

    }

抽取工具类:

package cn.itheima.jdbc.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPUtils {
    private static DataSource dataSource;
    static{
        try {
            //1.加载找properties文件输入流
            InputStream is = DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties");
            //2.加载输入流
            Properties props = new Properties();
            props.load(is);
            //3.创建数据源
            dataSource = BasicDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static DataSource getDataSource(){
        return dataSource;
    }
    
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

 

测试:

package cn.itheima.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import cn.itheima.jdbc.utils.DBCPUtils;

public class TestDBCP {

    @Test
    public void testUpdateUserById(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = DBCPUtils.getConnection();
            String sql ="update tbl_user set upassword=? where uid=?";
            pstmt= conn.prepareStatement(sql);
            pstmt.setString(1, "柳岩");
            pstmt.setInt(2, 20);
            int rows = pstmt.executeUpdate();
            if(rows>0){
                System.out.println("更新成功!");
            }else{
                System.out.println("更新失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

 

 

 

 

【C3P0连接池的使用】

第一步:引入C3P0连接池的jar包.

第二步:编写代码:

  * 手动设置参数:(不需要c3p0-config.xml)

  

 import com.mchange.v2.c3p0.*; ... ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" ); cpds.setUser("dbuser"); cpds.setPassword("dbpassword"); 

 

  * 配置文件设置参数:    c3p0-config.xml

配置文件:

 

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql:///web_07</property>
    <property name="user">root</property>
    <property name="password">123</property>
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">20</property>
  </default-config>
  
  <named-config name="oracle"> 
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql:///web_07</property>
    <property name="user">root</property>
    <property name="password">123</property>
  </named-config>
  

</c3p0-config>

 

  配置一个是默认的,一个是带名字的

测试:

    @Test
    public void testAddUser() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        // 1.创建自定义连接池对象
        ComboPooledDataSource dataSource = new ComboPooledDataSource();// 自动加载默认的配置
        // ComboPooledDataSource dataSource = new
        // ComboPooledDataSource("oracle");//加载有名称的配置
        try {
            // 2.从池子中获取连接
            conn = dataSource.getConnection();
            String sql = "insert into tbl_user values(null,?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "吕布2");
            pstmt.setString(2, "貂蝉2");
            int rows = pstmt.executeUpdate();
            if (rows > 0) {
                System.out.println("添加成功!");
            } else {
                System.out.println("添加失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtils_V3.release(conn, pstmt, null);
        }
    }

 

 

【C3P0改造工具类】

  1.提供数据源

  2.返回连接

package cn.itheima.jdbc.utils;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

    public static DataSource getDataSource() {
        return dataSource;
    }

    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

 

 测试:

    @Test
    public void testAddUser1() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            // 2.从池子中获取连接
            conn = C3P0Utils.getConnection();
            String sql = "insert into tbl_user values(null,?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "吕布3");
            pstmt.setString(2, "貂蝉3");
            int rows = pstmt.executeUpdate();
            if (rows > 0) {
                System.out.println("添加成功!");
            } else {
                System.out.println("添加失败!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtils_V3.release(conn, pstmt, null);
        }
    }

 

 

 

----------------------------DButils-------------------------------

 

基本使用:(增,删,改)

package cn.itheima.jdbc.test;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;

import cn.itheima.jdbc.utils.C3P0Utils;

/**
 * 测试DBUtils工具类的增删改操作
 * 
 * @version V1.0
 */
public class TestDBUtils1 {

    /**
     * 添加所有用户方法
     */
    @Test
    public void testAddUser() {
        try {
            // 1.创建核心类QueryRunner
            QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
            // 2.编写SQL语句
            String sql = "insert into tbl_user values(null,?,?)";
            // 3.为站位符设置值
            Object[] params = { "余淮", "耿耿" };
            // 4.执行添加操作
            int rows = qr.update(sql, params);
            if (rows > 0) {
                System.out.println("添加成功!");
            } else {
                System.out.println("添加失败!");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    /**
     * 根据id修改用户方法
     * 
     */
    @Test
    public void testUpdateUserById() {
        try {
            // 1.创建核心类QueryRunner
            QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
            // 2.编写SQL语句
            String sql = "update tbl_user set upassword=? where uid=?";
            // 3.为站位符设置值
            Object[] params = { "xxx", 21 };
            // 4.执行添加操作
            int rows = qr.update(sql, params);
            if (rows > 0) {
                System.out.println("修改成功!");
            } else {
                System.out.println("修改失败!");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    /**
     * 根据id删除用户方法
     */
    @Test
    public void testDeleteUserById() {
        try {
            // 1.创建核心类QueryRunner
            QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
            // 2.编写SQL语句
            String sql = "delete from tbl_user where uid=?";
            // 3.为站位符设置值
            Object[] params = {19};
            // 4.执行添加操作
            int rows = qr.update(sql, params);
            if (rows > 0) {
                System.out.println("删除成功!");
            } else {
                System.out.println("删除失败!");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

 

ResultSetHandler

我们知道在执行select语句之后得到的是ResultSet,然后我们还需要对ResultSet进行转换,得到最终我们想要的数据。你可以希望把ResultSet的数据放到一个List中,也可能想把数据放到一个Map中,或是一个Bean中。

DBUtils提供了一个接口ResultSetHandler,它就是用来ResultSet转换成目标类型的工具。你可以自己去实现这个接口,把ResultSet转换成你想要的类型。

DBUtils提供了很多个ResultSetHandler接口的实现,这些实现已经基本够用了,我们通常不用自己去实现ResultSet接口了。

l  MapHandler:单行处理器!把结果集转换成Map<String,Object>,其中列名为键!

l  MapListHandler:多行处理器!把结果集转换成List<Map<String,Object>>;

l  BeanHandler:单行处理器!把结果集转换成Bean,该处理器需要Class参数,即Bean的类型;

l  BeanListHandler:多行处理器!把结果集转换成List<Bean>;

l  ColumnListHandler:多行单列处理器!把结果集转换成List<Object>,使用ColumnListHandler时需要指定某一列的名称或编号,例如:new ColumListHandler(“name”)表示把name列的数据放到List中。

l  ScalarHandler:单行单列处理器!把结果集转换成Object。一般用于聚集查询,例如select count(*) from tab_student。

 

Map处理器

 

 

Bean处理器

 

 

Column处理器

 

Scalar处理器

 

 

QueryRunner之查询

QueryRunner的查询方法是:

public <T> T query(String sql, ResultSetHandler<T> rh, Object… params)

public <T> T query(Connection con, String sql, ResultSetHandler<T> rh, Object… params)

query()方法会通过sql语句和params查询出ResultSet,然后通过rh把ResultSet转换成对应的类型再返回。

 DButils查询方法:

@Test
    public void fun1() throws SQLException {
        DataSource ds = JdbcUtils.getDataSource();
        QueryRunner qr = new QueryRunner(ds);
        String sql = "select * from tab_student where number=?";
        Map<String,Object> map = qr.query(sql, new MapHandler(), "S_2000");
        System.out.println(map);
    }
    
    @Test
    public void fun2() throws SQLException {
        DataSource ds = JdbcUtils.getDataSource();
        QueryRunner qr = new QueryRunner(ds);
        String sql = "select * from tab_student";
        List<Map<String,Object>> list = qr.query(sql, new MapListHandler());
        for(Map<String,Object> map : list) {
            System.out.println(map);
        }
    }
    
    @Test
    public void fun3() throws SQLException {
        DataSource ds = JdbcUtils.getDataSource();
        QueryRunner qr = new QueryRunner(ds);
        String sql = "select * from tab_student where number=?";
        Student stu = qr.query(sql, new BeanHandler<Student>(Student.class), "S_2000");
        System.out.println(stu);
    }
    
    @Test
    public void fun4() throws SQLException {
        DataSource ds = JdbcUtils.getDataSource();
        QueryRunner qr = new QueryRunner(ds);
        String sql = "select * from tab_student";
        List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));
        for(Student stu : list) {
            System.out.println(stu);
        }
    }
    
    @Test
    public void fun5() throws SQLException {
        DataSource ds = JdbcUtils.getDataSource();
        QueryRunner qr = new QueryRunner(ds);
        String sql = "select * from tab_student";
        List<Object> list = qr.query(sql, new ColumnListHandler("name"));
        for(Object s : list) {
            System.out.println(s);
        }
    }
    
    @Test
    public void fun6() throws SQLException {
        DataSource ds = JdbcUtils.getDataSource();
        QueryRunner qr = new QueryRunner(ds);
        String sql = "select count(*) from tab_student";
        Number number = (Number)qr.query(sql, new ScalarHandler());
        int cnt = number.intValue();
        System.out.println(cnt);
    }

 

 


 [ThinkPad1]把一行记录转换成一个Map,其中键为列名称,值为列值

 [ThinkPad2]把转换集转换成List<Map>,其中每个Map对应一行记录

 [ThinkPad3]把结果集转换成一个Bean对象,在使用BeanHandler时需要指定Class,即Bean的类型

 [ThinkPad4]把结果集转换成List<Bean>,其中每个Bean对应一行记录

 [ThinkPad5]多行单例处理器,即获取name列数据

 [ThinkPad6]单行单列处理器,一般用于聚合查询,在使用ScalarHandler时可以指定列名,如果不指定,默认为第1列。

 [ThinkPad7]对聚合函数的查询结果,有的驱动返回的是Long,有的返回的是BigInteger,所以这里我们把它转换成Number,Number是Long和BigInteger的父类!然后我们再调用Number的intValue()或longValue()方法就OK了。

posted @ 2017-10-19 17:58  QiaoZhi  阅读(804)  评论(0编辑  收藏  举报