DBUtils使用方法詳解
目錄
- DBUtils使用方法詳解
- 一、前言
- 二、JDBC介紹
- 1.基本概念
- 2.JDBC訪問資料庫的流程
- 三、DBUtils介紹
- 1.基本概念
- 2.組態檔
- 3.創建JDBCUtils類
- 4.實作對資料表的增刪改查
- 四、對以上代碼的說明
- 五、總結
一、前言
本文是關于DBUtils使用方法的介紹,但在介紹DBUtils之前,首先介紹一些JDBC的基礎知識,有不足之處歡迎大家指正!
二、JDBC介紹
1.基本概念
JDBC,英文名為:Java DataBase Connectivity它是Java和資料庫之間的橋梁,是一個獨立于特定資料庫管理系統、通用的SQL資料庫存取和操作的公共介面(一組API),定義了用來訪問資料庫的標準Java類別庫(java.sql,javax.sql)使用這些類別庫可以以一種標準的方法,方便的訪問資料庫資源,
它最大的優點是為訪問不同的資料庫提供了一種統一的途徑,接下來用兩張圖形象的說明這一特點,
- 沒有JDBC時,Java程式訪問資料庫時:

- 有了JDBC,Java程式訪問資料庫時:

本文中的代碼都是針對于MySql資料庫實作的,并且所有代碼都經過測驗,各位放心食用,
2.JDBC訪問資料庫的流程
- 加載驅動(DriverManager)
- 獲取連接(DriverManager,Connection)
- 獲取執行SQL物件(Statement,PrepareStatement)
- 決議結果集(ReslutSet)
- 釋放資源(close())
以上五個步驟每寫一個操作資料庫的類都是需要的,例如加載驅動、獲取資料庫連接、釋放資源這三個步驟都要寫到,為了簡化代碼,讓程式的可移植性和觀賞性更高,更加靈活的應對各種變化,需要撰寫一個工具類來處理這些重復的步驟,這樣就引出了DBUtils工具類,
三、DBUtils介紹
1.基本概念
DBUtils:它是Apache組織提供的一個對JDBC進行簡單封裝的開源工具類,使用它能簡化JDBC應用程式的開發,提高代碼的可移植性和觀賞性,同時也不會影響程式的性能,
2.組態檔
首先需要在專案(Project)的src目錄下創建一個"jdbc.properties"的組態檔,在創建檔案時要注意是在src目錄下,否則會有錯誤,
組態檔內容為:
//用戶名和密碼
user=root
password=root
//資料庫路徑
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8
//資料庫驅動
driverClass=com.mysql.cj.jdbc.Driver
組態檔的好處是:
- 實作資料和代碼分離,實作了解耦;
- 如果需要修改組態檔資訊,可以避免程式重新打包;
- 資料庫路徑、用戶名、密碼或者驅動發生變更時,無需改動代碼,直接修改組態檔,大大提高了生產效率;
出現的問題:
配置資料庫路徑開始設定url為:
String url = "jdbc:mysql://localhost:3306/test";
運行后出現java.sql.SQLException例外, 并顯示 The server time zone value '�й���??��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
通過查看資料,將url修改為:
String url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8
解決了問題,在連接字串后面加上?useUnicode=true& characterEncoding =UTF-8目的是為了解決中文亂碼輸入問題;加上userSSL=false是為了符合不使用SSL的現有應用程式,通過設定userSSL=false顯示禁用SSL;serverTimezone=GMT%2B8作用是統一標準世界時間,
3.創建JDBCUtils類
里面包含了獲取資料庫的連接、加載驅動方法和釋放資源方法
獲取資料庫的連接、加載驅動方法:
public static Connection getConnection() throws Exception {
/**
* 獲取資料庫的連接
*/
//1.讀取組態檔的4個基本資訊
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties();
pros.load(is);
String user = pros.getProperty("user");
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//2.加載驅動
Class.forName(driverClass);
//3.獲取連接
Connection con = DriverManager.getConnection(url,user,password);
System.out.println(con);
return con;
}
說明:
- 首先通過InputStream讀取組態檔的4個基本資訊,利用ClassLoader呼叫getSystemClassLoader()方法實際上相當ConnectionTest.class.getClassLoader()的作用,但使用前者的好處是避免了出現第三方API;
- 定義4個String型別的字串接識訓取到的基本資訊;
- 此處省略了注冊驅動操作,是因為在mysql的Driver實作類中,宣告如下操作,故在實際的代碼撰寫中不需要在重新進行注冊驅動,
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
非查詢類釋放資源方法:
/**
* 關閉連接和Statement
* @param con
* @param ps
*/
public static void closeResource(Connection con,Statement ps) {
//資源關閉
try {
if(ps != null)
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(con != null)
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
說明: 非查詢類釋放資源程序中只需要關閉連接Connection和Statement,通過判斷Statement的物件ps和Connection的物件con是否非空即可執行資源關閉,
查詢類釋放資源方法:
/**
* 關閉連接、Statement和ResultSet
* @param con
* @param ps
*/
public static void closeResource(Connection con,Statement ps,ResultSet rs) {
//資源關閉
try {
if(ps != null)
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(con != null)
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(rs != null)
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
說明: 查詢類釋放資源程序中不僅僅要關閉連接Connection和Statement,還需要關閉查詢程序中得到的結果集ResultSet,
4.實作對資料表的增刪改查
(1)向student表中插入一條資料
說明: 預期目的是為了將(“鄭**”,“304728796@qq.com”,“2000-01-01”)資料插入到資料庫中,運行后結果如圖所示,
@Test
//向student表中插入一條資料
public void testInsert(){
Connection con = null;
PreparedStatement ps = null;
try {
//1.讀取組態檔的4個基本資訊
InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties();
pros.load(is);
String user = pros.getProperty("user");
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//2.加載驅動
Class.forName(driverClass);
//3.獲取連接
con = DriverManager.getConnection(url,user,password);
System.out.println(con);
//4.預編譯SQL陳述句,回傳PreparedStatement的實體
String sql = "insert into student(name,email,birth)values(?,?,?)";//?:占位符
ps = con.prepareStatement(sql);
//5.填充占位符
ps.setString(1, "鄭**");
ps.setString(2, "304728796@qq.com");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date = sdf.parse("2000-01-01");
ps.setDate(3,new Date(date.getTime()));
//6.執行SQL
ps.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//7.資源關閉
try {
if(ps != null)
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(con != null)
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
插入之前資料庫中原始資料為:

在插入之后資料庫中資料為:

(2)修改student表中的資料
**說明:利用ps.setObject(1, “小華”);ps.setObject(2, 3); 預期目的是為了修改行號為3,列號為2的資料,由"鄭"修改為"小華",運行后結果如圖所示,
//修改student表的一條記錄
@Test
public void testUpdate() {
//1.獲取資料庫連接
Connection con = null;
PreparedStatement ps = null;
try {
con = JDBCUtils.getConnection();
//2.預編譯SQL陳述句,回傳PraparedStatement的實體
String sql = "update student set name =? where id = ?";
ps = con.prepareStatement(sql);
//3.填充占位符
ps.setObject(1, "小華");
ps.setObject(2, 3);
//4.執行SQL
ps.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//5.資源的關閉
JDBCUtils.closeResource(con,ps);
}
}
修改之前資料庫中原始資料為:

在修改之后資料庫中資料為:

(3)通用的增刪改操作資料庫
說明:
- 該方法不僅僅適用于該表,其他表也適用;
- 該方法根據testCommonUpdate方法中sql陳述句的改變而進行不同的操作;可實作增(insert)、刪(delete)、改(update)操作;
- update方法中的args為可變引數,sql中的占位符的個數與可變形參長度相同;
- 利用update(sql,2)方法,預期目的是洗掉行號為2的資料,運行后結果如圖所示,
@Test
public void testCommonUpdate() {
String sql = "delete from student where id = ?";
update(sql,2);
}
//通用的增刪改操作
public void update(String sql,Object ...args){//sql中占位符的個數與可變形參長度相同
Connection con = null;
PreparedStatement ps = null;
try {
//1.獲取資料庫連接
con = JDBCUtils.getConnection();
//2.預編譯SQL陳述句,回傳PraparedStatement的實體
ps = con.prepareStatement(sql);
//3.填充占位符
for(int i=0;i<args.length;i++) {
ps.setObject(i+1, args[i]);//引數宣告:列號從1開始
}
//4.執行SQL
ps.execute();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//5.資源的關閉
JDBCUtils.closeResource(con,ps);
}
}
洗掉之前資料庫中原始資料為:

洗掉之后資料庫中資料為:

(4)查詢資料庫中的資料
package com.javaweb3.preparedstatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
import com.javaweb4.util.JDBCUtils;
/**
* 針對于student表的查詢
* @author 敷衍zgf
*
*/
public class StudentForQuery {
@Test
public void testQuery1(){
Connection con = null;
PreparedStatement ps = null;
//執行并回傳結果集
ResultSet resultSet = null;
try {
con = JDBCUtils.getConnection();
String sql = "select id,name,email,birth from student where id = ?";
ps = con.prepareStatement(sql);
ps.setObject(1, 1);
resultSet = ps.executeQuery();
//處理結果集
if(resultSet.next()) {//判斷結果集的下一條是否有資料,如果有資料回傳true,并且指標下移;如果回傳false,指標不會下移
//獲取當前字條資料的各個欄位值
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String email = resultSet.getString(3);
Date birth = resultSet.getDate(4);
/*處理結果集
* 方式一:
*/
System.out.println("id = "+id+",name = "+name+",email = "+email+",birth = "+birth);
//方式二:
Object[] data = new Object[] {id,name,email,birth};
for(int i=0;i<data.length;i++) {
System.out.print(data[i]+" ");
}
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//關閉資源
JDBCUtils.closeResource(con, ps, resultSet);
}
}
}
資料庫中的資料:

查詢后得到的結果:

四、對以上代碼的說明
以上對資料庫資料的增刪查操作全都是使用PreparedStatement實作的,PreparedStatement是從Statement擴展而來的,不使用Statement是因為它不僅需要拼寫sql陳述句,更嚴重的是存在SQL注入的問題,PreparedStatement是預編譯的,對于批量處理可以大大提高效率,
五、總結
以上就是本人對JDBC和DBUtils工具類的全部認識和簡單的運用方法,如有不足之處歡迎大家批評指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/165854.html
標籤:java
