JDBC基本詳解


前言

由於目前市面上存在的多種數據庫,為了使Java編寫的程序不依賴具體的數據庫,Java提供了專門用於操作數據庫的API,就是JDBC(Java Data Base Connectivity)Java數據庫連接。使用JDBC的應用程序和數據庫連接后,就可以使用JDBC提供的API操作數據庫。

基本步驟:

  • 與一個數據庫建立連接
  • 向連接的數據庫發送SQL語句
  • 處理SQL語句返回的結果
連接數據庫

在開發中常用的連接方式是加載JDBC-數據庫驅動(連接器),即JDBC調用本地的JDBC-數據庫驅動和相應數據庫建立連接。連接需要經歷兩個步驟:

  1. 加載JDBC-數據庫驅動
  2. 和指定的數據庫建立連接。

如果JDK擴展沒用JDBC-MySQL驅動,可登錄MySQL官網下載,選擇JDBC Driver for MySQL,例如下載的是mysql-connector-java-5.1.40.zip,解壓后復制到JDK擴展目錄中,例如E:\jdk1.8\jre\lib\ext。之后便開始加載JDBC-MySQL數據庫驅動,負責加載驅動的代碼為:

try {//MySQL驅動被封裝在Driver類中
	Class.forName("com.mysql.jdbc.Driver");
	//oracle
	Class.forName("oracle.jdbc.driver.OracleDriver");
    //加載SQLServer驅動
    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    //加載Derby驅動
    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
}catch(Exception e){ }

之后第三步開始連接數據庫,java.sql包中的DriverManager類有兩個用於建立連接的類方法:

  • Connection getConnection(String ,String ,String)
  • ConnectiongetConnection(String)

上述兩個方法都有可能返回SQLException異常,DriverManager類調用上述方法可以和數據庫建立連接,可以返回一個Connection對象。注意,連接時MySQL數據庫服務器啟動,默認端口為3306

Connection con;
String url = "jdbc:mysql://127.0.0.1:3306/users?user=root&password=123456&useSSL=true";
//String url = "jdbc:mysql://127.0.0.1:3306/users?useSSL=true&characterEncoding=utf-8";
//String sqlserver_url="jdbc:sqlserver://localhost:1433;DatabaseName=users";
//String derby="jdbc:derby:users;create=true";創建並連接users數據庫
//String user = "root";
//String password = "123456";
try{//連接MySQL數據庫users
    con = DriverManager.getConnection(url);
    //con  = DriverManager.getConnection(url,user,password);
}catch(SQLException e){
    System.out.println(e);
}

需要注意的是,如果連接數據庫的表中有漢字,那么建立連接時要多傳一個參數characterEncoding,取值utf-8或gb2312

查詢操作

建立連接后就可以發送SQL語句了,和數據庫進行交互,常見操作有查詢、修改和更新等。步驟具體如下:

  1. 向數據庫發送查詢語句

    使用statement聲明一個SQL語句對象,然后讓連接對象con調用方法creatStatement()創建這個SQL語句對象。

    try{
    	Statement sql = con.createStatement();	
    }catch(SQLException e){
        System.out.println(e);
    }
    
  2. 處理查詢結果

    有了SQL語句對象后,這個對象就可以調用相應的方法實現對數據庫的查詢和修改,並將查詢結果存放在一個ResultSet類聲明的對象中,即查詢結果將返回一個ResultSet對象,對象由按字段組織的數據行構成。

    ResultSet rs1 = sql.executeQuery("SELECT * FROM users");
    ResultSet rs2 = sql.executeQuery("SELECT name,height FROM users");
    

    結果集rs1的列數和users的列數相同,結果集rs2列數只有2列。ResultSet對象一次只能看到一個數據行,使用next()移到下一行,獲得一行數據后,ResultSet對象可以使用getXxx方法獲得字段值,將位置索引或列名傳遞給getXxx方法即可。無論字段為何種屬性,總可以使用getString(int columnIndex)getString(String columnName)方法返回字段的串表示。

  3. 關閉連接

    ResultSet對象和數據庫連接對象實現了緊密的綁定,則一旦連接對象被關閉,ResultSet對象中的數據立刻消失。

    con.close();  //關閉連接將無法獲取數據
    
順序查詢

ResultSet對象一次只能看到一個數據行,使用next()方法移到下一個數據行,next()最初查詢位置,即游標位置,在第一行前面。next()向下移動游標,移動成功返回true,否則返回false

rs = sql.executeQuery("SELECT * FROM users");
while(rs.next()){
    String number = rs.getString(1);
    String name = rs.getString(2);
    Date date = rs.getDate(3);
    System.out.println(number);
    System.out.println(name);
    System.out.println(date);
}
con.close();
控制游標

調用next()方法使游標向下移動,若需要在結果集中上下移動、顯示某一條記錄或隨機顯示若干記錄,必須返回一個可滾動的結果集。為了得到一個可滾動的結果集可使用如下方法:

Statement st = con.createStatement(int type,int concurrency);

type的取值決定滾動方式:

  • ResultSet.TYPE_FORWORD_ONLY:結果集的游標只能向下滾動。
  • ResultSet.TYPE_SCROLL_INSENSITIVE:結果集的游標可以上下移動,當數據庫變化時,當前結果集不變。
  • ResultSet.TYPE_SCROLL_SENSITIVE:返回可滾動的結果集,當數據庫變化時,當前結果集同步改變。

concurrency取值決定是否可以用結果集更新數據庫:

  • ResultSet.CONCUR_READ_ONLY:只讀,不能用結果集更新數據庫中的表。
  • ResultSet.CONCUR_UPDATABLE:能用結果集更新數據庫中的表。

滾動查詢經常會用到一些實例方法,大家可自行查詢了解和使用。例如public void last()移到最后一行,public int getRow()返回當前行號。

條件和排序查詢

需要條件進行查詢時,可在SQL語句中添加條件。

  • where子語句

    select 字段 from 表 where 條件
    
  1. 字段值和固定值比較

    select name from users where name='騷年'
    
  2. 字段值在某個范圍內

    select * from users where height>1.60 and height<1.8
    select * from users where weight>45 and name!='張三'
    
  3. 使用某些特殊日期函數,如year,month,day

    select * from users where year(birthday)<2013 and month(birthday)<=10
    select * from users where year(birthday) between 2000 and 2014
    
  4. 使用某些特殊的時間函數,如hour,minute,second

    select * from timelist where second(shijian)=32 
    
  5. 使用操作符like進行模式匹配,使用%代替0給或多個字符,用下划線_代替一個字符,例如在name字段查詢含‘凱’字的記錄。

    select * form users where name like '%凱%'
    
  • 排序

    order by子語句進行排序,例如:

    select * from users order by height
    select * from users where name like '%凱%' order by name 
    
增刪改操作

Statement對象調用方法:

public int executeUpdate(String sqlStatement);

通過參數sqlStatement指定的方式實現對數據庫中記錄的更新、添加和刪除操作。

  1. 更新

    下述SQL語句將users表中name值為“張三”的記錄的height字段的值更新為1.77:

    update 表 set 字段 = 新值 where <條件子句>
    update users set height = 1.77 where name='張三'
    
  2. 添加

    以下SQL語句將users表中添加兩條新的記錄(記錄之間用逗號分隔):

    insert into 表(字段列表) values (對應的具體的記錄)
    insert into 表 values (對應的具體的記錄)
    insert into users values
    ('R1001','基地','2020-11-21',1.67),('R1002','包有為','2020-12-20',1.79)
    
  3. 刪除

    下述SQL語句將刪除users表中的number字段值為R1002的記錄:

    delete from 表名 where <條件子句>
    delete from users where number='R1002'
    

當返回結果集后,沒用立即輸出結果集的記錄,而是接着執行了更新語句,那么結果集就不能輸出記錄,如果要返回結果集就必須重新返回結果集。

使用預處理語句

Java提供了更高效的數據庫處理機制,就是PreparedStatement預處理語句對象。它的目的是減輕數據庫SQL解釋器的負擔,事先將SQL語句解釋為數據庫底層的內部命令,然后讓數據庫去執行這個命令,從而提高了訪問數據庫的速度。

連接對象調用preparedStatement(String sql)方法對參數sql指定的SQL語句進行預編譯處理,生成數據庫底層的內部命令,並將該命令封裝在PreparedStatement對象中,那么該對象調用下列方法都可以使得該命令被數據庫執行。

  • ResultSet executeQuery()
  • boolean execute()
  • int executeUpdate()

只要編譯好了PreparedStatement對象,那么該對象可以隨時執行上述方法。

使用通配符?來代替字段的值,只要在預處理語句之前再設置通配符所代表的具體值即可。

String str = "select * from users where height < ? and name= ?";
PreparedStatement sql = con.preparedStatement(str);

sql對象執行之前,必須調用相應的方法設置通配符?代表的具體值,例如:

sql.setFloat(1,1.76f);
sql.setString(2,"哦哦");

通配符按照它們在預處理語句中從左到右依次出現的順序分別為第1、2···n個通配符,使用通配符可以隨時改變SQL語句中的條件。常用方法有以下幾個:

void setDate(int paraIndex,Date x);
void setDouble(int paraIndex,double x);
void setFloat(int paraIndex,float x);
void setInt(int paraIndex,int x);
void setLong(int paraIndex,long x);
void setString(int paraIndex,String x);
通用查詢

編寫一個類,用戶將數據庫名、SQL語句傳遞給該類對象,那么該對象就用一個二維數組返回查詢結果。為了編寫通用查詢,需要知道數據庫的列的名字,特別是表的列數(字段的個數),簡單的方法就是使用返回到程序的結果集獲取相關信息。結果集ResultSet對象調用getMetaData()方法返回一個ResultSetMetaData對象(結果集的元數據對象)。

ResultSetMetaData metaData = rs.getMetaData();

之后metaData調用getColumnCount()方法就可以返回結果集中的列的數目,調用getColumnName(int i)就可以返回結果集中的第i列的名字。

int columnCount  = metaData.getColumnCount();
String columnName = metaData.getColumnName(i);
事務

事務由一組SQL語句組成,所謂事務處理,是指應用程序保證事務中的SQL語句要么全部執行要么一個都不執行。事務處理是保證數據庫中數據完整性與一致性的重要機制。應用程序與數據庫建立連接后,可能使用多條SQL語句操作數據庫中的一個或多個表。例如管理資金轉賬的應用程序,保證轉賬雙方資金安全合理,則SQL語句都執行或都不執行。

JDBC處理事務的步驟:

  1. setAutoCommit(boolean b)方法關閉自動提交模式

    關閉自動提交就是關閉SQL語句的即可生效性,連接對象的提交模式是自動提交模式,連接對象產生的StatementPreparedStatement對象對數據庫提交的任何SQL語句都會立即生效,而我們的要求是讓一組提交的SQL語句同步生效。就是歸納為不能立刻生效,不能不生效!

    連接對象con首先調用setAutoCommit(boolean autoCommit)方法,參數取值false即可關閉。注意,先關閉再獲取Statement對象。

    sql = con.createStatement();
    
  2. commit()方法處理事務

    關閉后,連接對象產生的Statement對象對數據庫提交的任何一條SQL語句都不會立刻生效,這樣Statement對象可以提交多條SQL語句,這些SQL語句就是一個事務,事務中的SQL語句不會立刻生效。連接對象調用commit()方法就是試圖讓事務中的SQL語句全部生效。

  3. rollback()方法處理事務失敗

    處理事務失敗就是撤銷事務所做的操作。事務中任何一個SQL語句未能生效,就拋出SQLException異常,在處理該異常時,必須讓連接對象con調用rollback()方法,作用是撤銷事務中成功執行的SQL語句對數據庫所做的更新、插入和刪除操作,讓數據庫中的數據恢復為之前的狀態。

事務的四大特點(ACID)

  • Atomicity(原子性):表示一個事務內的所有操作是一個整體,要么全部成功,要么全失敗;
  • Consistency(一致性):表示一個事務內有一個操作失敗時,所有的更改過的數據都必須回滾到修改前的狀態;
  • Isolation(隔離性):事務查看數據時數據所處的狀態,要么是另一並發事務修改它之前的狀態,要么是另一事務修改它之后的狀態,事務不會查看中間狀態的數據。
  • Durability(持久性):持久性事務完成之后,它對於系統的影響是永久性的。

事務隔離級別從低到高

  • 讀取未提交(Read Uncommitted)
  • 讀取已提交(Read Committed)
  • 可重復讀(Repeatable Read)
  • 序列化(serializable)

批處理Batch

  • 靈活指定SQL語句中的變量
    PreparedStatement
  • 對存儲過程進行調用
    CallableStatement
  • 運用事務處理
    Transaction
  • 批處理
    Batch
    對於大量的批處理,建議使用Statement,因為PreparedStatement的預編譯空間有限,當數據量特別大時,會發生異常。
CLOB文本大對象操作
  • CLOB(Character Large Object)
    用於存儲大量的文本數據-大字段有些特殊,不同數據庫處理的方式不一樣,大字段的操作常常是以流的方式來處理的。而非一般的字段,一次即可讀出數據。
  • Mysql中相關類型:
    TINYTEXT最大長度為255(2^8-1)字符的TEXT列。
    TEXT[(M)]最大長度為65535(2^16-1)字符的TEXT列。
    MEDIUMTEXT最大長度為16,777,215(2^24-1)字符的TEXT列。
    LONGTEXT最大長度為4,294,967,295或4GB(2^32-1)字符的TEXT列。
BLOB二進制大對象的使用
  • BLOB(Binary Large Object) 用於存儲大量的二進制數據
    大字段有些特殊,不同數據庫處理的方式不一樣,大字段的操作常常是以流的方式來處理的。而非一般的字段,一次即可讀出數據。
  • Mysql中相關類型:
    TINYBLOB最大長度為255(2^8-1)字節的BLOB列。
    BLOB[(M)]最大長度為65535(2^16-1)字節的BLOB列。
    MEDIUMBLOB最大長度為16,777,215(2^24-1)字節的BLOB列。
    LONGBLOB最大長度為4,294,967,295或4GB(2^32-1)字節的BLOB列。
最后

以上就是JDBC的基本內容了,在學JDBC的同時,最好提前了解熟悉一下MySQL。如果有問題,可以上公眾號菜雞干Java上加wx交流,公眾號上會分享一些知識干貨哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM