複習_數據庫連接池和DBUtils

1.常用開源連接池

  • Apache DBCP
  • C3P0

1.1 DBCP

使用DBCP 數據源,應用程序需要在系統中增加兩個jar文件
在這裏插入圖片描述
1.手動配置

package ConnectionPool;

import JDBC.JDBCUtil;
import org.apache.commons.dbcp.BasicDataSource;

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

public class DBCPPool {

    public static void main(String[] args) {
        BasicDataSource basicDataSource = new BasicDataSource();
        //手動設置連接需要的參數
        basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        basicDataSource.setUrl("jdbc:mysql://localhost:3306/mybd");
        basicDataSource.setUsername("root");
        basicDataSource.setPassword("root");
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        //獲取連接
        try {
            connection = basicDataSource.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery("select * from user");
            while (resultSet.next()) {
                System.out.println(resultSet.getString("username"));
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            JDBCUtil.release(connection, statement, resultSet);
        }
    }
}

2.文件配置

創建 dbcp.properties 文件
Key是固定的,不要隨意改變

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybd
username=root
password=root
package ConnectionPool;

import JDBC.JDBCUtil;
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.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DBCPPool {

    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        //獲取連接
        try {
            //dbcp數據庫連接池配置文件的方式
            //獲取dbcp的配置文件
            Properties properties = new Properties();
            properties.load(new FileInputStream("src/ConnectionPool/dbcp.properties"));
            //創建dbcp數據庫連接池
            DataSource basicDataSource = BasicDataSourceFactory.createDataSource(properties);
            connection = basicDataSource.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery("select * from user");
            while(resultSet.next()){
                System.out.println(resultSet.getString("username"));
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            JDBCUtil.release(connection,statement, resultSet);
        }
    }
}

1.2 C3P0

C3P0 是一個開源的JDBC連接池,目前他的開源項目有spring和hibernate。
spring 和 hibernate對C3P0進行支持。

使用c3p0數據庫連接池之前,首先需要在資料中找到如下的jar包,加載到項目中。
在這裏插入圖片描述

手動配置:

public static void main(String[] args) {

	Connection connection = null;
	Statement statement = null;
	ResultSet resultSet = null;
	//獲取連接
	try {
		//首先創建c3p0數據庫連接池對象
		ComboPooledDataSource basicDataSource = new ComboPooledDataSource();
		//手動設置參數
		basicDataSource.setDriverClass("com.mysql.jdbc.Driver");
		basicDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/12day01");
		basicDataSource.setUser("root");
		basicDataSource.setPassword("123");
		 connection = basicDataSource.getConnection();
		 statement = connection.createStatement();
		 resultSet = statement.executeQuery("select * from dept");
		while(resultSet.next()){
			System.out.println(resultSet.getString(2));
		}
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally{
		JdbcUtils04.release(connection,statement, resultSet);
	}
}

文件方式配置:
當然了,我們提供了c3p0數據庫連接池的配置方式,配置文件如下,注意,這是一個xml配置文件。而我們之前的dbcp數據庫連接池需要獲取配置文件交給dbcp,然後才能去創建數據庫連接池。而我們的c3p0,我們只需要將信息配置好,取好固定的名字:c3p0-config.xml然後將文件放在src目錄下,我們的c3p0數據庫連接池自己去獲取配置文件,自己解析配置文件。非常方便

注意:
1.c3p0的xml配置文件的名稱必須叫做c3p0-config.xml
2. C3p0-config.xml必須放在src目錄下。

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://localhost:3306/mybd</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!-- 如果連接池中連接不夠時一次性增長多少連接 -->
        <property name="acquireIncrement">5</property>
        <!-- 初始化連接池時池子中有多少個連接 -->
        <property name="initialPoolSize">20</property>
        <!-- 池子中最小連接數 -->
        <property name="minPoolSize">10</property>
        <!-- 池子中最大連接數 -->
        <property name="maxPoolSize">40</property>
        <!-- 每次最多可以執行多少個批處理語句 -->
        <property name="maxStatements">50</property>
        <!-- 連接池內單個連接所擁有的最大緩存statements數 -->
        <property name="maxStatementsPerConnection">5</property>
    </default-config>
</c3p0-config>
public static void main(String[] args) {

    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    //獲取連接
    try {
		ComboPooledDataSource basicDataSource = new ComboPooledDataSource();
        connection = basicDataSource.getConnection();
        statement = connection.createStatement();
        resultSet = statement.executeQuery("select * from user");
        while (resultSet.next()) {
            System.out.println(resultSet.getString(2));
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        JDBCUtil.release(connection, statement, resultSet);
    }
}

2.DBUtils

package ConnectionPool;

public class User {
    private String id;
    private String username;
    private int age;
    private String password;

    public User() {
        super();
    }

    public User(String id, String username, int age, String password) {
        this.id = id;
        this.username = username;
        this.age = age;
        this.password = password;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

之前的做法
在這裏插入圖片描述

2.1 使用DBUtils改寫上述代碼

使用DBUtils之前需要導入DBUtils的jar包
在這裏插入圖片描述
在這裏插入圖片描述
DBUtils概述
DBUtils是java編程中的數據庫操作實用工具,小巧簡單實用。
DBUtils封裝了對JDBC的操作,簡化了JDBC操作,可以少寫代碼。
Dbutils三個核心功能介紹

  • QueryRunner中提供對sql語句操作的API.
  • ResultSetHandler接口,用於定義select操作後,怎樣封裝結果集.
  • DbUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法
package ConnectionPool;

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;

public class C3P0Utils {
	//空參,自動到classpath目錄下面加載“c3p0-config.xml”配置文件---配置文件的存儲位置和名稱必須是這樣,且使用“默認配置”
    public static ComboPooledDataSource	 dataSource = new ComboPooledDataSource();

    public static DataSource getDataSource(){
        return dataSource;
    }

    public static Connection getConnection(){
        Connection con = null;
        //con從數據庫連接池去拿
        try {
            con = dataSource.getConnection();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return con;
    }

    public static void release(Connection con, Statement st, ResultSet rs){
        //6.釋放資源:先開後關,後開先關,最好放在finally代碼塊中
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(con!=null){
            try {
                con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

c3p0-config.xml需要放在src目錄下

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mybd</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!-- 如果連接池中連接不夠時一次性增長多少連接 -->
        <property name="acquireIncrement">5</property>
        <!-- 初始化連接池時池子中有多少個連接 -->
        <property name="initialPoolSize">20</property>
        <!-- 池子中最小連接數 -->
        <property name="minPoolSize">10</property>
        <!-- 池子中最大連接數 -->
        <property name="maxPoolSize">40</property>
        <!-- 每次最多可以執行多少個批處理語句 -->
        <property name="maxStatements">50</property>
        <!-- 連接池內單個連接所擁有的最大緩存statements數 -->
        <property name="maxStatementsPerConnection">5</property>
    </default-config>
</c3p0-config>

2.2 QueryRunner核心類介紹

  • QueryRunner(DataSource) 創建核心類,並提供數據源,內部自己維護Connection
  • update(String sql , Object … params) 執行DML語句
  • query(String sql , ResultSetHandler , Object … params) 執行DQL語句,並將查詢結果封裝到對象中。

或者是自己提供Connection

  • QueryRunner() 創建核心類,沒有提供數據源,在進行具體操作時,需要手動提供Connection
  • update(Connection conn, String sql , Object … params) 執行DML語句
  • query(Connection conn, String sql , ResultSetHandler , Object … params) 執行DQL語句,並將查詢結果封裝到對象中。

2.3 QueryRunner實現添加、更新、刪除操作

添加

// 提供con
public void add() throws Exception{
	//首先創建queryRunner對象
	QueryRunner queryRunner = new QueryRunner();
	String sql = "insert into product values(?,?,?,?)";
	//注意,此處必須要傳遞connection對象才能執行。
	Connection con = JdbcUtils.getConnection();
	int update = queryRunner.update(con, sql, 20,"空調",2000,"c001");
	//自己需要關閉連接
	con.close();
}

// 不提供con
public void add() throws SQLException{
	//首先創建queryRunner對象,提供數據庫連接池
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql = "insert into product values(?,?,?,?)";
	//注意,此處必須要傳遞connection對象才能執行。
	int update = queryRunner.update(sql, 21,"立式空調",3000,"c001");
}

更新

public void update(){
	//創建QueryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	//
	try {
		int update = queryRunner.update("update  product set pname=? where pid=? ", "cccc",14);
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

刪除

public void delete(){
	//創建QueryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	try {
		int update = queryRunner.update("delete from product where pid=?", 14);
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

2.4 QueryRunner實現查詢操作(重點)

  • query(String sql, ResultSetHandler rsh, Object… params) ,用來完成表數據的查詢操作

ResultSetHandler結果集處理類
在這裏插入圖片描述
在這裏插入圖片描述

JavaBean

package ConnectionPool;

public class Product {
    private int pid;
    private String pname;
    private double price;
    private String category_id;

    public Product() {
        super();
    }

    public Product(int pid, String pname, double price, String category_id) {
        this.pid = pid;
        this.pname = pname;
        this.price = price;
        this.category_id = category_id;
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getCategory_id() {
        return category_id;
    }

    public void setCategory_id(String category_id) {
        this.category_id = category_id;
    }

    @Override
    public String toString() {
        return "Product{" +
                "pid=" + pid +
                ", pname='" + pname + '\'' +
                ", price=" + price +
                ", category_id='" + category_id + '\'' +
                '}';
    }
}

1.BeanHandler

/**
 * 	BeanHandler:結果集處理的一種方式
 * 		將查詢的結果的第一條數據封裝到javaBean中。
 * 		格式:new BeanHandler<泛型>(javaBean的類型)
 * 
 * @throws SQLException
 */
@Test
public void beanHandlerTest() throws SQLException{
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql = "select * from product";
	//執行sql語句
	Product product = queryRunner.query(sql, new BeanHandler<Product>(Product.class));
	System.out.println(product);
}

2.BeanListHandler

/**
 * BeanListHandler:
 * 		將查詢的所有的結果封裝到javaBean的集合中。
 * 
 * @throws SQLException
 */
@Test
public void beanListHandlerTest() throws SQLException{
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql = "select * from product";
	//執行sql語句
	List<Product> productList = queryRunner.query(sql, new BeanListHandler<Product>(Product.class));
	for (Product product : productList) {
		System.out.println(product);
	}
}

3.ScalarHander

/**
 *	ScalarHandler:
 *		將一行一列的數據封裝起來。一般用於聚集函數 
 *		必須是Long類型
 * @throws SQLException 
 *
 */
@Test
public void scalarHandlerTest() throws SQLException{
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql = "select count(*) from product";
	//執行sql語句
	Long count = queryRunner.query(sql, new ScalarHandler<Long>());
	System.out.println(count);
}

4.MapHandler

/**
 * mapHandler:
 * 		將第一條數據封裝成map集合。
 * 		key就是列名,value就是列對應的值。
 * @throws SQLException
 */
@Test
public void mapHandlerTest() throws SQLException{
	//首先創建一個queryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql ="select * from product";
	 Map<String, Object> query = queryRunner.query(sql, new MapHandler());
	 System.out.println(query);
}

5.MapListHandler

/**
 * mapListHandlerTest:
 * 		將所有的商品封裝成list集合,list集合中每一個都是map集合。
 * 		map集合的key就是列名,值就是列對應的值。
 * @throws SQLException
 */
@Test
public void mapListHandlerTest() throws SQLException{
	//首先創建一個queryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql ="select * from product";
	List<Map<String,Object>> query = queryRunner.query(sql, new MapListHandler());
	 for (Map<String, Object> map : query) {
		System.out.println(map);
	}
}

6.ArrayHandler

/**
 * arrayHandler:
 * 		將第一條數據封裝成數組,數組中的每個值都是列中的值。
 * @throws SQLException
 */
@Test
public void arrayHandlerTest() throws SQLException{
	//首先創建一個queryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql ="select * from product";
	Object[] query = queryRunner.query(sql, new ArrayHandler());
	System.out.println(Arrays.toString(query));
	 
}

7.ArrayListHandler

/**
 * arrayListHandler:
 * 			將所有的數據封裝成一個list集合,集合中的每一個對象都是數組。每一個數組對應了一條數據。
 * @throws SQLException
 */
@Test
public void arrayListHandlerTest() throws SQLException{
	//首先創建一個queryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql ="select * from product";
	List<Object[]> query = queryRunner.query(sql, new ArrayListHandler());
	for (Object[] objects : query) {
		System.out.println(Arrays.toString(objects));
	}
	 
}

8.KeyedHandler

/**
 * keyedHandler:
 * 		將所有的結果封裝成一個map集合,
 * 		key就是制定的列的值,
 * 		value就是每一條數據被封裝成的map集合,key是列名,值就是列 對應的值。
 * new KeyedHandler<T>(columName)
 * 	T:指的就是列對應的數據類型
 * 	columName:制定的列的名稱,如果不指定列,那麼就默認的取第一列。
 * @throws SQLException
 */
@Test
public void keyedHandlerTest() throws SQLException{
	//首先創建一個queryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql ="select * from product";
	Map<String, Map<String, Object>> query = queryRunner.query(sql, new KeyedHandler<String>("category_id"));
	for (Map.Entry<String, Map<String, Object>> e : query.entrySet()) {
		System.out.println(e.getKey());
		System.out.println(e.getValue());
	}
	
}

9.ColumnListHandler

/**
 * columListHandler:
 * 			將制定列中的所有值封裝成list集合。
 * 	new ColumnListHandler<T>(columName)
 * 	T:列的類型對應了java中的數據類型。
 * 	columName:指定的表中的列名,如果不指定列名,那麼默認的就是第一列。
 * @throws SQLException
*/
@Test
public void columListHandlerTest() throws SQLException{
	//首先創建一個queryRunner對象
	QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
	String sql ="select * from product";
	List<String> query = queryRunner.query(sql, new ColumnListHandler<String>("pname"));
	for (String integer : query) {
		System.out.println(integer);
	}
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章