本文實例講述了JDBC基礎知識與技巧。分享給大家供大家參考。具體分析如下:
1.什麼是JDBC?
通俗來講JDBC技術就是透過java程式來傳送SQL語句到資料庫,資料庫收到SQL語句後執行,把結果回傳給java程式管理。
2.使用JDBC要有什麼條件呢?
A)目標資料庫主機的位址
B)資料庫軟體在該主機上所佔用的連接埠號碼
C)登陸資料庫用的使用者名
D)該使用者名稱的密碼
E)連接資料庫
3.JDBC技術的原理
我們知道,資料庫是有各種類型的,不同的廠商生產的資料庫標格和規格是不同的,這時候,如果我們用JAVA程式碼來傳送SQL語句,就要根據不同的資料庫來寫一套又一套的操作程式碼,這對程式開發者的開發成本是十分巨大的,所以,SU N公司在開發JDBC技術的時候,規定了一套標準接口,數據庫產商都必須提供一個驅動來實現這套接口,那麼,只要程序開發者在開發時使用了該數據庫的驅動,就用一致的方法來開發了,而不需自己寫一套有一套的程式碼去適應不同的資料庫。
4.JDBC中的核心API
|- Driver : 驅動程式類別實作的介面。
|-Connection connect(String url, Properties info) --用於連接資料庫,得到連接對象
Properties 裡需要設定的參數:
url:資料庫連接的URL字串。協定+資料庫子協定+主機+連接埠+資料庫
user: 資料庫使用者名稱
password: 使用者的密碼
|-Connection : 與資料庫連接的接口
|- Statement createStatement() --建立Statement對象,用於傳送sql語句
|- PreparedStatement prepareStatement(String sql) -建立PreparedStatement對象,用於傳送預先編譯的sql語句
|-CallableStatement prepareCall(String sql) --建立CallableStatement對象,用於呼叫預存程序。
|-Statement: 用於執行靜態sql語句
|-int executeUpdate(String sql) --執行更新操作(DDL+DML)
|-ResultSet executeQuery(String sql) --執行查詢運算(DQL)
|- PreparedStatement: 用於執行預編譯的sql語句
|- int executeUpdate() -- 執行更新操作
|- ResultSet executeQuery() -- 執行查詢操作
|- CallableStatement: 用於執行預存程序的sql
|- ResultSet executeQuery() --呼叫預存程序
|- ResultSet: 結果集。用於封裝資料庫的查詢後的數據
|- boolean next() --將記錄遊標移到下一行
|- Object getObject(int columnIndex) -- 得到欄位上的值
了解完又哪些API,下面我們就來使用JDBC發送SQL語句吧~
5.使用Statement物件操作資料庫
DDL與DML操作
步驟1
導包,因為我使用的是MySQL資料庫,所以要使用JDBC技術,必須使用由MySQL資料庫產商提供的資料庫驅動,所以,第一步我們要把資料庫驅動包匯入工程裡。
使用的套件名稱:mysql-connector-java-5.1.7-bin.jar
步驟2
建立一個普通的類,在裡面新增一個方法,在該方法中按照以下步驟複製程式碼程式碼如下://URL
private String url = "jdbc:mysql://localhost:3306/vmaxtam";
//user
private String user = "root";
//password
private String password = "root";
public void testDDL()throws Exception{
//1.註冊驅動
Class.forName("com.mysql.jdbc.Driver");
//2.取得連接
Connection conn = DriverManager.getConnection(url, user, password);
//3.建立Statement對象
Statement stmt = conn.createStatement();
//4.準備sql語句
String sql ="CREATE TABLE student(sid INT PRIMARY KEY,sname VARCHAR(20),age INT)";
//5.透過statement物件傳送sql語句,傳回執行結果
int count = stmt.executeUpdate(sql);
//6.列印執行結果
System.out.println("影響了"+count+"筆記錄");
}
//7.關閉資源
if(statement!=null)
{
statement.close();
}
if(conn!=null)
{
conn.close();
}
如果要進行DQL與DDL操作,都可以把SQL語句寫好,然後呼叫statement的executlUpdate方法來給資料庫執行SQL語句,這個方法傳回一個整數值,表示資料庫中有多少行受到了影響。
如果我們不改變上述的程序,想要再向資料庫發出SQL語句,那麼又要寫一個程序來再次連接,操作完後又要關閉statement對象和connection對象,這是十分繁瑣的。所以,我們一般會把連接過程和釋放物件的過程抽取到一個工具類別中。工具類別中的程式碼如下:
複製程式碼程式碼如下:public class sqlUtil {
private static String url = "jdbc:mysql://localhost:3306/vmaxtam";
private static String user = "root";
private static String password = "root";
// 取得連接
public static Connection getconnection() {
Connection conn = null;
try {
// 1.註冊驅動
Class.forName("com.mysql.jdbc.Driver");
// 2.取得連接
conn = DriverManager.getConnection(url, user, password);
// 3.取得statement對象
Statement statement = conn.createStatement();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
// 7.關閉資源
public static void close(Statement statement, Connection connection) {
{
try {
if (statement != null)
statement.close();
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
還要考慮的情況就是:
一)一個用戶只需要註冊一次驅動就行,不用每次連接資料庫都註冊驅動,所以我們把註冊驅動的過程寫在靜態程式碼區塊中。
二)url 和用戶名,密碼還有驅動類名,在程式裡是寫死的,為了能夠在不改代碼的前提下更換資料庫或更換用戶,我們通常把這些資訊寫到一份設定檔中。
設定檔寫在工程的src目錄下,名為db.properties
複製代碼代碼如下:url=jdbc:mysql://localhost:3306/vmaxtam
user=root
password=root
driverClass=com.mysql.jdbc.Drive
然後再sqlUtil讀取該設定文件,最後優化成下面程式碼複製程式碼如下:public class sqlUtil {
private static String url = null;
private static String user = null;
private static String password = null;
private static String driverClass= null;
static{
try {
//1.取得字節碼對象
Class clazz = sqlUtil.class;
//2.呼叫getResourceAsStream取得路徑
InputStream inputStream = clazz.getResourceAsStream("/db.properties");
Properties pro = new Properties();
pro.load(inputStream);
//3.讀取參數
url=pro.getProperty("url");
password=pro.getProperty("password");
user=pro.getProperty("user");
driverClass=pro.getProperty("driverClass");
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
System.out.println("註冊失敗!" + e.getMessage());
throw new RuntimeException(e);
}
}
// 取得連接
public static Connection getconnection() {
Connection conn = null;
try {
// 取得連接
conn = DriverManager.getConnection(url, user, password);
// 取得statement對象
Statement statement = conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
// 關閉資源
public static void close(Statement statement, Connection connection) {
{
try {
if (statement != null)
statement.close();
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
DQL操作
那麼如何用JDBC來查詢資料庫中的資料呢?
複製代碼代碼如下:@Test
public void testdsl() throws Exception {
//取得連接
cnn2=sqlUtil.getconnection();
Statement statement = cnn2.createStatement();
//準備SQL語句
String sql = "select * from subject";
//呼叫executeQuery執行查詢語句
ResultSet res = statement.executeQuery(sql);
//查詢結束後res會指向表頭,想要取得資料必須不斷指向查詢結果的下一行,當沒有下一行資料時,回傳0.
while(res.next())
{
//取得查詢結果中欄位為「sjid」的值,並且要明確類型
int id = res.getInt("sjid");
//取得查詢結果中欄位為「sjname」的值,並且要明確類型
String name = res.getString("sjname");
System.out.println("ID:" + id + " NAME:" + name);
}
sqlUtil.close(statement, cnn2);
}
以上就是使用Statement物件來操作資料庫了~
6.使用PreparedStatement操作資料庫
PreparedStatement物件其實就是一個特殊的Statement對象,它能夠預先編譯SQL語句,當你把參數設定好,然後就可以去執行SQL語句了~
DDL與DML操作複製程式碼如下:package com.vmaxtam.sqltest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.Test;
public class PreparedStatementTest {
Connection connection = null;
@Test
public void ddldmlTest() throws Exception {
// 1.取得連接
connection = sqlUtil.getconnection();
// 2.準備SQL語句,預編譯語句,參數用?號佔位
String sql = "INSERT INTO SUBJECT VALUES(?,?)";
// 3.取得對象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
/*
* 4.設定SQL參數需要參數是第幾個,並且知道它的型別下面第一句表示:SQL語句第一個參數是int型別,參數值設定為3,如此類推
*/
preparedStatement.setInt(1, 3);
preparedStatement.setString(2, "英文");
// 5.交給資料庫執行SQL
int num = preparedStatement.executeUpdate();
System.out.println("有" + num + "筆記錄受到了影響");
sqlUtil.close(preparedStatement , connection );
}
}
以上就是使用PreparedStatement物件來進行插入語句的發送,同理,DDL與DML類別的語句都可以根據這樣來發送.
PreparedStatement預編譯的好處:
PreparedStatement的預編譯可以讓你可以透過設定不同的參數來查詢不同的目標,在資料庫端,只會儲存一段預編譯語句,但是如果你使用Statement來傳送語句,每傳送一條,資料庫中就會存一條,這可能會造成佔用大量記憶體。
DQL操作複製代碼代碼如下:@Test
public void dqlTest() throws Exception {
// 1.取得連接
connection = sqlUtil.getconnection();
// 2.準備SQL語句,預編譯語句,參數用?號佔位
String sql = "select * from subject where sjid=? or sjname=?";
// 3.取得對象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
/*
* 4.設定SQL參數需要參數是第幾個,並且知道它的型別下面第一句表示:SQL語句第一個參數是int型別,參數值設定為3,如此類推
*/
preparedStatement.setInt(1, 2);
preparedStatement.setString(2, "語文");
// 5.交給資料庫執行SQL
ResultSet rst = preparedStatement.executeQuery();
//6.迭代結果集
while(rst.next())
{
int id = rst.getInt("sjid");
String name = rst.getString("sjname");
System.out.println("ID:" + id + " NAME:" + name);
}
//7.關閉連接
sqlUtil.close(preparedStatement, connection);
}
也是呼叫executeQuery();方法即可,得到結果集後迭代輸出~
既然Statement 與PreparedStatement那麼相似,比較它們的優缺點吧~
Statement 與PreparedStatement的差異:
1.語法不同
Statement只支援靜態編譯,SQL語句是寫死的。
PreparedStatement支援預編譯,用?號來佔位。
2.效率不同
Statement每次都要發送SQL語句,不支援緩存,執行效率低。
PreparedStatement支援預編譯,快取在資料庫,只要傳送參數,執行效率快。
3.安全性不同
Statement容易被注入。
注入:狡猾的分子可以寫一個特殊的SQL語句來入侵資料庫。
例如:要查詢某個使用者的信息
一般情況:SELECT * FROM user_list where username=xxx and password=xxx;(這裡的xxx本來應為使用者填入自己的使用者名稱和密碼)
注入情況:SELECT * FROM user_list where username='abc' or 1=1 -- password=xxx;
這樣1=1恆等,而且在password前面加上了「--」號,後面的內容變成了註解不被執行。也就是說,這樣就能不用密碼地查詢所有的使用者資料。
PreparedStatement,因為規定了SQL語句中的參數,所以可以防止注入。
結論:建議使用PreparedStatement,因為它更快更安全。
7.使用CallableStatement執行預存程序
使用CallableStatement只是執行預存程序,建立預存程序我們還是要在資料庫內建立的。
步驟1
現在資料庫建好一個預存程序:
複製代碼代碼如下:DELIMITER $
CREATE PROCEDURE pro_add(IN a INT , IN b VARCHAR(20),OUT c INT)
BEGIN
SELECT * FROM SUBJECT WHERE sjid=a OR sjname=b;
SET c=a+a+a+a;
END $
步驟2
利用java程式碼執行,並得到輸出參數複製程式碼如下:@Test
public void calaST() throws Exception {
//取得連接
connection= sqlUtil.getconnection();
//準備SQL語句
String sql = "CALL pro_add(?,?,?)";
//得到callableStatement對象
CallableStatement cbs = connection.prepareCall(sql);
//設定輸入參數,和preparedStatement一樣
cbs.setInt(1, 3);
cbs.setString(2, "數學");
/*那麼如何設定輸出參數呢?
* 需要註冊輸出參數!
*/
cbs.registerOutParameter(3, java.sql.Types.INTEGER);//需要使用內建物件來設定參數類型
//執行SQL語句
cbs.executeQuery();
//利用getXXX方法得到對應位置的輸出參數
Integer num= cbs.getInt(3);
System.out.println("a*4 is " + num);
//關閉資源
sqlUtil.close(cbs, connection);
}
希望本文所述對大家的Java程式設計有幫助。