【DBUtils工具概述】
爲了簡化JDBC開發,使用apache commons 組件一個成員:DBUtils。
DBUtils 是java編程中的數據庫操作實用工具,小巧簡單實用。
Dbutils三個核心功能介紹:
(1) QueryRunner 中提供對sql語句操作的API
a. 方法update() 實現對數據庫的 insert 、delete、update
b. 方法query() 實現對數據庫的查詢 select 返回值是T泛型
(2) ResultSetHandler接口 用於定義select操作後,怎樣封裝結果集
a. 接口實現類 ArrayHandler -- 將結果集的第一行存儲到對象數組中 Object[]
b. 接口實現類 ArrayListHandler -- 結果集的每一行都存儲在對象數組中,再將這些數組存儲在List集合中
c. 接口實現類 BeanHandler -- 將結果集的第一行數據,封裝成javaBean對象
d. 接口實現類 BeanListHandler -- 結果集每一行數據,都裝成javaBean對象,將這些對象存儲List集合中
e. 接口實現類 ColumnListHandler -- 將結果集指定列存儲到List<Object>集合中
f. 接口實現類 ScalarHandler -- 查詢後結果集中只有1個結果 類型爲long
g. 接口實現類 MapHandler -- 將結果集的第1行數據封裝到Map集合中去 Map<列名, 列數據>
(3) DbUtils類 是一個工具類,定義了關閉資源與事務處理的方法
【連接池】
用池來管理Connection ,這樣就可以重複使用Connection了。可以通過池來獲取Connection對象,使用完後再歸還給池。java爲數據庫連接池提供的公共接口:javax.sql.DataSource 。常見的連接池DBCP C3P0。
【DBCP連接池】
作用:自身維護了多個Connection對象
DataSource 接口 它是java與每種數據庫連接池 連接的標準規範
BasicDataSource類 它是DataSource接口的實現類
【DBCP連接池常見配置】
必須項 |
driverClassName |
數據庫驅動名稱 |
url |
數據庫的地址 |
|
username |
用戶名 |
|
password |
密碼 |
|
基本項 |
maxActive |
最大連接數量 |
initialSize |
連接池中初始化多少個Connection連接對象 |
|
擴展項 |
maxWait |
超時等待時間以毫秒爲單位 1000等於1秒 |
【1. QueryRunner 方法update】
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import usst.javacode.JDBCutils.JDBCutils;
/*
* 使用QueryRunner類,實現對數據表的 增insert 刪 delete 改 update
* 1.方法 update(Connection con, String sql, Object...params)
* Object...params Object類型 可變參數,SQL語句出現?佔位符
* 使用自己定義的工具類 創建數據庫連接對象 JDBCutils.getConnection()
*/
public class QueryRunnerDemo1 {
private static Connection con = JDBCutils.getConnection();
public static void main(String[] args) throws SQLException {
//insert();
//update();
delete();
}
// 1. 使用QueryRunner類 向數據庫中添加數據
public static void insert() throws SQLException{
// 創建QueryRunner類對象
QueryRunner qr = new QueryRunner();
String sql = "INSERT INTO sort1 (sname,sprice,sdesc) VALUES (?,?,?)";
// 調用qr對象的方法 update 執行SQL語句
Object[] params = {"鼠標",99,"雷蛇"}; // 將三個實際佔位符的參數寫在數組中
int row = qr.update(con, sql, params);
System.out.println(row);
DbUtils.closeQuietly(con);
}
// 2. 使用QueryRunner類 修改數據庫中的數據
public static void update() throws SQLException{
// 創建QueryRunner類對象
QueryRunner qr = new QueryRunner();
String sql = "UPDATE sort1 SET sname = ?,sprice = ?, sdesc = ? WHERE sid = ?";
// 定義Object數組,存儲?中的參數
Object[] params = {"記錄本",49,"精裝",13};
int row = qr.update(con, sql, params);
System.out.println(row);
DbUtils.closeQuietly(con);
}
// 3. 使用QueryRunner類 刪除數據庫中的數據
public static void delete() throws SQLException{
// 創建QueryRunner類對象
QueryRunner qr = new QueryRunner();
String sql = "DELETE FROM sort1 WHERE sid = ?";
int row = qr.update(con, sql, 12);
System.out.println(row);
DbUtils.closeQuietly(con);
}
}
【javaBean】
javaBean就是一個類,在開發中常用封裝數據。具有以下特性:
(1) 需要實現接口:java.io.Serializable,通常實現接口這個步驟省略,不會影響程序
(2) 提供私有字段:private 類型 字段名
(3) 提供getter/setter方法
(4) 提供無參構造方法
【2. QueryRunner方法query()】
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
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.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import usst.javacode.JDBCutils.JDBCutils;
import usst.javacode.JDBCutils.Sort;
/*
* QueryRunner類數據查詢操作:
方法 query(Connection con,String sql,ResultSetHandler r,Object...params)
* ResultSetHandler r 結果集的處理方式 傳遞ResultSetHandler接口的實現類
* Object...params SQL語句中?號佔位符的參數
* 注意:query方法返回的是 T 泛型,具體返回值類型,跟隨結果集處理方式變化
*
*/
public class QueryRunnerDemo2 {
private static Connection con = JDBCutils.getConnection();
public static void main(String[] args) throws SQLException {
//arrayHandler();
//arrayListHandler();
//beanHandler();
//beanListHandler();
//columnListHandler();
//scalarHandler();
//mapHandler();
mapListHandler();
}
// 1. 結果集第一種處理方法 ArrayHandler 將結果集的第一行存儲到對象數組中 Object[]
public static void arrayHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用query方法執行查詢,(傳遞連接對象,SQL語句,結果集處理方式的實現類)
// 返回對象數組
Object[] result = qr.query(con,sql,new ArrayHandler());
for(Object res:result){
System.out.print(res+"\t"); // 打印sort1數據表中第一行
// 1 家電 3000.0 廠家促銷
}
}
// 2. 結果集第二種處理方法 ArrayListHandler 將結果集的每一行,封裝到對象數組中Object[] 對象數組存儲到List集合
public static void arrayListHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用query方法 , 結果集處理的參數上,傳遞實現類ArrayListHandler
// 返回值 每一行是一個對象數組,存儲到List中
List<Object[]> result = qr.query(con, sql,new ArrayListHandler());
// 集合遍歷
for(Object[] objs:result){
// 遍歷對象數組
for(Object obj:objs){
System.out.print(obj+"\t"); // 打印sort1表中的所有內容
// 1 家電 3000.0 廠家促銷 ......
}
System.out.println();
}
}
// 3. 結果集第三種處理方法,BeanHandler 將結果集的第一行數據 封裝成javaBean對象
// 注意: 被封裝成數據 到javaBean對象Sort類,必須有空參數的構造方法
public static void beanHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用方法query 傳遞結果集實現類BeanHandler
// BeanHandler(Class<T> type)
Sort s = qr.query(con, sql, new BeanHandler<Sort>(Sort.class));
System.out.println(s); // 打印sort1數據表中第一行
// Sort [sid=1, sname=家電, sprice=3000.0, sdesc=廠家促銷]
}
// 4. 結果集第四種處理方法BeanListHandler 將數據結果集的每一行,封裝成javaBean對象 多個javaBean對象封裝到List集合中
public static void beanListHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用方法query 傳遞結果集實現類beanListHandler
// BeanListHandler(Class<T> type)
List<Sort> result = qr.query(con,sql, new BeanListHandler<Sort>(Sort.class));
// 遍歷
for(Sort res:result){
System.out.println(res); // 打印sort1表中的所有內容
// Sort [sid=1, sname=家電, sprice=3000.0, sdesc=廠家促銷] ......
}
}
// 5. 結果集第五種處理方法 ,ColumnListHandler 將結果集中指定列的數據,存儲到List集合 List<Object> 每個類數據類型不同
public static void columnListHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用方法query, 傳遞結果集實現ColumnListHandler 實現類構造方法中使用字符串的列名
List<Object> result = qr.query(con, sql, new ColumnListHandler<Object>("sname"));
System.out.println(result);
// [家電, 傢俱, 兒童玩具, 生鮮, 服裝, 洗髮水, 新能源汽車, 羽絨服, 新能源汽車, 新能源汽車, 鼠標1, 記錄本]
for(Object res:result){
System.out.println(res);
// 家電 傢俱 ......
}
}
// 6. 結果集第六種處理方法,ScalarHandler 用於單數據 查詢後只有一個結果
public static void scalarHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT COUNT(*) FROM sort1";
// 調用query方法,傳遞結果集實現類ScalarHandler
long count = qr.query(con,sql,new ScalarHandler<Long>());
System.out.println(count); // 12
}
// 7. 結果集第七種處理方法,MapHandler,將結果集中的第一行封裝到Map集合中 Map<鍵,值> 鍵:列名 值:這列的數據
public static void mapHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用query方法,傳遞結果集實現類MapHandler
// 返回值:Map集合,Map接口實現類,泛型
Map<String,Object> map = qr.query(con, sql,new MapHandler());
// 遍歷Map集合
for(String key:map.keySet()){
System.out.println(key+"="+map.get(key));
}
/*
* 打印結果
sid=1
sname=家電
sprice=3000.0
sdesc=廠家促銷
*/
}
// 8. 結果集第八種處理方法,MapListHandler 獎結果集的每一行存儲到Map集合中,鍵:列名 值:這列的數據
// Map集合過多,存儲到List集合中去
public static void mapListHandler() throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM sort1";
// 調用query方法,傳遞結果集實現類MapListHandler
// 返回值是List集合,裏面存儲的是Map集合
List<Map<String,Object>> list = qr.query(con,sql,new MapListHandler());
// 遍歷集合List
for(Map<String,Object> map:list){
for(String key:map.keySet()){
System.out.print(key+"="+map.get(key)+"\t");
}
System.out.println();
}
/*
* sid=1 sname=家電 sprice=3000.0 sdesc=廠家促銷
sid=2 sname=傢俱 sprice=8900.0 sdesc=傢俱價格上調
sid=3 sname=兒童玩具 sprice=300.0 sdesc=銷量火爆
... .... ... ...
*/
}
}
【連接池工具類】 -- BasicDataSource
實際開發中“獲得連接”和“釋放連接”是非常消耗系統資源的兩個過程,爲了解決此類問題我們採用連接池技術,來共享連接Connection。
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
/*
* 使用DBCP實現數據庫的連接池
* 連接池配置:
* 最基本四項配置 1. 數據庫驅動名稱:setDriverClassName 2. 數據庫地址:setUrl
* 3. 用戶名:setUsername 4. 密碼:setPassword
* 基本項(擴展) 1. 初始化的連接數量:setInitialSize 2. 最大連接數量:setMaxActive
* 3. 最大空閒數:setMaxIdle 4. 最小空閒數:setMinIdle
*/
public class JDBCutils {
// 創建出BasicDataSource類對象
private static BasicDataSource dataSource = new BasicDataSource();
// 靜態代碼塊,進行配置
static{
// 連接數據庫的4個基本信息,通過對象方法setXXX進行設置 (必須進行配置)
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybase1");
dataSource.setUsername("root");
dataSource.setPassword("123");
// 對 dataSource連接池對象 的連接數量進行配置 (可選配置,有默認配置)
dataSource.setInitialSize(10); // 初始化的連接數量
dataSource.setMaxActive(8); // 最大連接數量
dataSource.setMaxIdle(5); // 最大空閒數
dataSource.setMinIdle(1); // 最小空閒數
}
// 定義靜態方法,返回BasicDataSource類對象
public static DataSource getDataSource(){
return dataSource;
}
// 定義靜態方法,返回Connection對象
public static Connection getConnection(){
return dataSource.getConnection;
}
}
【測試連接池工具類】
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
/*
* 測試寫好的工具類:JDBCutils 靜態方法getDataSource() 返回值類型是DataSource
QueryRunner 類構造方法,接受DataSource接口的實現類
*/
public class QueryRunnerDemo {
// 定義2個方法,實現數據表的添加 、數據表的查詢
// QueryRunner類對象寫在成員變量位置
private static QueryRunner qr =new QueryRunner(JDBCutils.getDataSource());
public static void main(String[] args) {
//insert();
select();
}
// 數據表添加數據
public static void insert(){
String sql = "INSERT INTO sort1 (sname,sprice,sdesc) VALUES(?,?,?)";
Object[] params = {"核桃",29.9,"新疆乾果"};
try{
int row = qr.update(sql,params); // 無須傳遞Connection對象
System.out.println(row);
}catch(SQLException ex){
throw new RuntimeException(ex+"數據庫添加失敗");
}
}
// 數據表查詢函數
public static void select(){
String sql = "SELECT * FROM sort1";
try{
List<Object[]> lists = qr.query(sql, new ArrayListHandler());
for(Object[] list:lists){
for(Object l:list){
System.out.print(l+"\t");
}
System.out.println();
}
}catch(SQLException ex){
throw new RuntimeException(ex+"數據庫查詢失敗");
}
/* 打印結果
* 1 家電 3000.0 廠家促銷
2 傢俱 8900.0 傢俱價格上調
3 兒童玩具 300.0 銷量火爆
... ...
*/
}
}
【連接池工具】-- 讀取 .properties文件配置數據庫
db.properties文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybase1
username=root
password=123
DBCPUtils類 獲取連接池 和 連接對象的靜態方法
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class DBCPUtils {
// 聲明DataSource類型成員變量
private static DataSource dataSource;
static {
try {
// 使用類的加載器讀取數據庫.properties配置文件(在src目錄下)
InputStream in = DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties");
// 加載輸入流
Properties pros = new Properties();
pros.load(in);
// 使用工具類創建連接池(數據源)
dataSource = BasicDataSourceFactory.createDataSource(pros);
} 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);
}
}
}
【c3p0連接池工具】
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:///mybase1</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="namedConfig">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///mybase1</property>
<property name="user">root</property>
<property name="password">123</property>
</named-config>
</c3p0-config>
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Utils {
// 使用默認配置 -- 自動讀取c3p0-config.xml中的配置信息
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 使用命名配置
//private static ComboPooledDataSource dataSource = new ComboPooledDataSource("namedConfig");
// 靜態方法獲得連接池
public static DataSource getDataSource() {
return dataSource;
}
// 靜態方法獲得連接
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}