【12-JDBC編程】

JDBC編程java


JDBC概述mysql

 

  •經過使用JDBC API,Java程序能夠很是方便地操做各類主流數據庫,這是使Java語言的巨大程序員

魅力所在。並且因爲Java語言的跨平臺特性,因此使用JDBC API所編寫的程序不只能夠實現跨數據正則表達式

庫,還能夠跨平臺,具備很是優秀的可移植性。sql

 

  •程序使用JDBC API以統一的方式來鏈接不一樣的數據庫,而後經過Statement對象來執行標準數據庫

SQL語句,並能夠得到SQL語句訪問數據庫的結果。所以掌握標準SQL語句是學習JDBC編程的基礎,編程

本章將會簡要介紹關係數據庫理論基礎,並以MySQL數據庫爲例來說解標準SQL語句的語法細節。包安全

括基本查詢語句,多表鏈接查詢和子查詢等。併發


 

 JDBC驅動示意編程語言

 

 

•爲了JDBC程序能夠跨平臺,則須要不一樣數據庫廠商提供相應的驅動,下圖顯示了JDBC驅動的示意

圖。

 


JDBC驅動程序類型 

 

 

•第一種JDBC驅動:稱爲JDBC–ODBC橋,這種驅動是最先實現的JDBC驅動程序,主要目的是爲了

快速推廣JDBC。這種驅動程序將JDBC API映射到ODBC API。JDBC-ODBC也須要驅動,這種驅

動由Sun公司提供實現。

 

•第二種JDBC驅動:直接將JDBC API映射成數據庫特定的客戶端API。這種驅動程序包含特定數據

庫的本地代碼,用於訪問特定數據庫的客戶端。

 

•第三種JDBC驅動:支持三層結構的JDBC訪問方式。主要用於Applet階段,經過Applet訪問數據

庫。

 

•第四種JDBC驅動:是純Java的,直接與數據庫實例交互。這種驅動是智能的,它知道數據庫使用的

底層協議。這種驅動是目前最流行的JDBC驅動。


 

 安裝MySQL

 

 

•(1)下載MySQL安裝文件

•(2)開始安裝MySQL後,在出現的對話框中單擊「Next」按鈕。

•(3)單擊對話框的「Next」按鈕,將出現選擇安裝組件和安裝路徑的對話框。

•(4)單擊對話框中的「Next」按鈕,將可開始安裝MySQL數據庫系統。安裝成功後,系統還要求配置MySQL數據庫。

•(5)配置數據庫時注意選擇合適的字符集,並設置密碼。


 

 MySQL的常見命令

 

 

•show databases;

•drop database 數據庫名;

•use 數據庫名

•show tables;

•desc 表名


MySQL的兩種存儲機制

 

 

•MyISAM:這是MySQL早期默認的存儲機制,對事務支持不夠好。

 

•InnoDB:InnoDB提供事務安全的存儲機制。InnoDB經過創建行級鎖來保證事務完整性,並以

Oracle風格的共享鎖來處理Select語句。 系統默認啓動InnoDB機制,若是不想使用 InnoDB表,

可使用skip-innodb 選項。


 

 

 SQL語句 

 

 

 

•SQL的全稱是Structured Query Language,也就是結構化查詢語言。SQL是操做和檢索關係型

數據庫的標準語言,標準SQL語句可用於操做任何關係數據庫。

 

•使用SQL語句,程序員和數據庫管理員(DBA)能夠完成以下的任務:

–在數據庫中檢索須要的信息。

–對數據庫的信息進行更新。

–改變數據庫的結構。

–更改系統的安全設置。

–增長用戶對數據庫或表的許可權限。


 

 SQL語句分類

 

 

•查詢語句:主要因爲select關鍵字完成,查詢語句是SQL語句中最複雜,功能也最豐富的語句。

•DML語句(Data Manipulation Language,即數據操做語言):主要由  insertupdatedelete三個關鍵字完成。

•DDL語句(Data Definition Language,即便數據定義語言):主要由create、alter、drop和truncate四個關鍵字完成。

•DCL語句(Data Control Language,即便數據控制語言):主要由grantrevoke兩個關鍵字完成。

•事務控制語句:主要由commitrollbacksavepoint三個關鍵字完成。


 

 DDL語句 

 

 

•DDL語句是操做數據庫對象的語句,包括

–建立(create)

–刪除(drop)

–修改(alter)數據庫對象。 


 

 數據庫對象

 

 

對象名稱

對應關鍵字

描述

table

表是存儲數據的邏輯單元,以行和列的形式存在;列就是字段,行就是記錄。

數據字典

 

就是系統表,存放數據庫相關信息的表。系統表裏的數據一般由數據庫系統維護。程序員一般不該該手動修改系統表及內部數據,程序員只可查看系統表的數據。

約束

constraint

執行數據校驗的規則,用於保證了數據完整性的規則。

視圖

view

一個或者多個數據表裏數據的邏輯顯示。視圖並不存儲數據。

索引

index

用於提升查詢的性能,至關於書的目錄。

函數

function

用於完成一次特定的計算,具備一個返回值。

存儲過程

procedure

用於完成一次完整的業務處理,沒有返回值,但可經過傳出參數將多個值傳給調用環境。

觸發器

trigger

至關於一個事件監聽器,當數據庫發生特定事件後,觸發器被觸發,完成響應的處理。

 


建立表的語法

 

 

create table [模式名.]表名 ( -- 能夠有多個列定義 columnName1 datatype [default expr] , … )

 


 

修改表(增長列)的語法

 

 

alter table 表名 add ( -- 能夠有多個列定義 column_name1 datatype [default expr] , … );

 

 修改表(修改列)的語法

 

 

alter table 表名 modify column_name datatype [default expr] [first|after col_name];

修改表(刪除列)的語法

 

 

•alter table 表名

•drop column_name


 

 刪除表的語法

 

 

•drop table 表名;


約束

 

 

•大部分數據庫支持下面五類完整性約束:

–NOT NULL:非空約束,指定某列不能爲空。

–UNIQUE:惟一約束,指定某列或者幾列組合不能重複。

–PRIMARY KEY:主鍵,指定該列的值能夠惟一地表示該條記錄。

–FOREIGN KEY:外鍵,指定該行記錄從屬於主表中的一條記錄,主要用於保證參照完整性。

–CHECK:檢查,指定一個布爾表達式,用於指定對應列的值必須知足該表達式。


 

 索引

 

 

•索引是存放在模式(schema)中的一個數據庫對象,雖然索引老是從屬於數據表,但它也和數據表

同樣,屬於數據庫對象。建立索引惟一的做用就是加速對錶的查詢,索引經過使用快速路徑訪問方法來

快速定位數據,從而減小了磁盤的I/O。

 

•建立索引有兩種方式:

–自動:當在表上定義主鍵約束、惟一約束和外鍵約束時,系統會爲該數據列自動建立對應的索引。

–手動:用戶能夠手動建立索引來加速查詢。

 

•刪除索引也有兩種方式:

–自動:數據表被刪除時,該表上的索引自動被刪除。

–手動:用戶能夠手動刪除指定數據表上的指定索引。


 

 視圖

 

 

•視圖看上去很是像一個數據表,但它不是數據表,由於它並不能存儲數據。視圖只是一個或多個數據表中數據的邏輯顯示。使用視圖有以下幾個好處:

–能夠限制對數據的訪問。

–可使複雜的查詢變得簡單。

–提供了數據的獨立性。

–提供了對相同數據的不一樣顯示。


 

 建立視圖的語法

 

 

•create or replace view 視圖名

•as

•subquery


 

 DML語句

 

 

•與DDL操做數據庫對象不一樣,DML主要操做數據表裏的數據,使用DML能夠完成以下三個任務:

–插入新數據。

–修改已有數據。

–刪除不須要的數據。


 

 insert into

 

 

•insert into用於向指定數據表中插入記錄。對於標準SQL語句而言,每次只能插入一條記錄。

insert into命令的語法格式以下:

–insert into table_name [(column [, column...])]

–values(value [, value...]);


 

 update語句

 

 

•update語句用於修改數據庫記錄,每次修改能夠修改多條記錄,可經過使用where子句限定修改哪些記錄。where子句是一個條件表達式,該條件表達式相似於Java編程語言的if,只有符合該條件的記錄纔會被修改。若是沒有where子句意味着where子句的表達式值老是true,即該表的全部記錄都會被修改。update語句的語法格式以下:

–update table_name

–set column1= value1[, column2 = value2] …

–[WHERE condition];


 

 delete from語句

 

 

•delete from語句用於刪除指定數據表的記錄,使用delete from刪除時不須要指定列名,由於刪除老是整行整行地刪除。

•delete from刪除能夠一次刪除多行,刪除哪些行採用where子句限定,只刪除知足where條件的記錄。沒有where子句將會把表裏的所有記錄刪除。

•delete from語句的語法格式以下:

–delete from table_name

–[WHERE condition];


 

 SELECT語句

 

 

•select語句功能就是查詢數據,select語句也是SQL語句中功能最豐富的語句,select語句不只能夠執行單表查詢,還能夠執行多表鏈接查詢,還能夠進行子查詢,select語句用於從一個或多個數據表中選出特定行、特定列的交集。

•最簡單的select語句的語法格式以下:

–select column1, column2 ...

–from 數據源

–[where condition]


 

 SELECT語句的規則

 

 

•當使用select語句進行查詢時,還能夠在select語句中使用算術運算符(+  -  *  /),從而造成算術表達式,使用算數表達式的規則以下:

–對數值型數據列、變量、常量可使用算數操做符(+  -  *  /)建立表達式。

–對日期型數據列、變量、常量可使用部分算數操做符建立表達式 (+  -),兩個日期之間能夠進行減法運算,日期和數值之間可進行加、減運算。

–運算符不只能夠在列和常量、變量之間進行運算,也能夠在兩列之間進行運算。


 

 特殊比較運算符

 

 


 數據庫函數

 

 

•每一個數據庫都會在標準SQL基礎上擴展一些函數,這些函數用於進行數據處理或複雜計算,

•根據函數對多行數據的處理方式,函數被分爲單行函數和多行函數,單行函數對每行輸入值單獨計算,每行獲得一個計算結果返回給用戶。多行函數對多行輸入值總體計算,最後只會獲得一個結果。單行函數和的多行函數的示意如圖所示:


組函數

 

 

•組函數也就是前面提到多行函數,組函數將一組記錄做爲總體計算,每一組記錄返回一個結果,而不是每一條記錄返回一個結果。經常使用的組函數有以下5個:

avg([distinct|all]expr):計算多行expr的平均值,其中expr能夠是變量、常量或數據列,但其數據類型必須數值型。還能夠在變量、列前使用distinct或all關鍵字,若是使用distinct代表不計算重複值;all用和不用的效果徹底同樣,代表須要計算重複值。

count({ *|[distinct|all]expr}):計算多行expr的平均值,其中expr能夠是變量、常量或數據列,其數據類型能夠是任意類型。用星號(*)表示統計該表內的記錄行數。其中distinct表示不計算重複值。

max([distinct]expr):計算多行expr的平均值,其中expr能夠是變量、常量或數據列,其數據類型能夠是任意類型。其中distinct表示不計算重複值。

min([distinct]expr):計算多行expr的平均值,其中expr能夠是變量、常量或數據列,其數據類型能夠是任意類型。其中distinct表示不計算重複值。

sum([distinct|all]expr):計算多行expr的總和,其中expr能夠是變量、常量或數據列,但其數據類型必須數值型。其中distinct表示不計算重複值。


 

 多表鏈接查詢 

 

 

•多表鏈接查詢有兩種規範,較早的SQL92規範中支持以下幾種多表鏈接查詢:

–等值鏈接。

–非等值鏈接。

–外鏈接。

–廣義笛卡爾積。


 

 SQL99的多表鏈接查詢

 

 

•SQL99規則提供了可讀性更好的多表鏈接語法,並提供更多類型的鏈接查詢,SQL99支持以下幾種多表鏈接查詢:

–交叉鏈接。

–天然鏈接。

–使用using子句的鏈接。

–使用on子句的鏈接。

–全外鏈接或者左右外鏈接。 


 

 子查詢

 

 

•子查詢就是指在查詢語句中嵌套另外一個查詢,子查詢能夠支持多層嵌套。對於一個普通查詢語句而言,子查詢能夠出如今兩個位置:

–出如今from語句後當成數據表,這種用法也被稱爲行內視圖,由於該子查詢的實質就是一個臨時視圖。

–出如今where條件後做爲過濾條件的值。


 

 使用子查詢的注意點

 

 

•使用子查詢時有以下幾個注意點:

–子查詢要用括號括起來。

–子查詢當成數據表時,能夠爲該子查詢起別名,尤爲是要做爲前綴來限定數據列時,必須給子查詢起別名。

–子查詢當過濾條件時,將子查詢放在比較運算符的右邊,這樣能夠加強查詢的可讀性。

–子查詢當過濾條件時,單行子查詢使用單行運算符,多行子查詢使用多行運算符。


 

 JDBC經常使用接口和類 

 

 

•DriverManager

•Connection

•Statement

•PreparedStatement

•ResultSet


JDBC編程步驟 

 

 

•(1)加載數據庫驅動。

•(2)經過DriverManager獲取數據庫鏈接。

•(3)經過Connection對象建立Statement對象。

•(4)使用Statement執行SQL語句。全部Statement都有以下三個方法來執行SQL語句。

•(5)操做結果集。若是執行的SQL語句是查詢語句,執行結果將返回一個ResultSet對象,該對象裏保存了SQL語句查詢的結果。程序能夠經過操做該ResultSet對象來取出查詢結果。 


JDBC執行SQL語句的方式

 

 

•使用executeUpdate執行DDL和DML語句

•使用execute方法執行SQL語句

•使用executeQuery方法執行查詢語句 


PreparedStatement

 

 

•JDBC提供了PreparedStatement接口,它是Statement接口的子接口,它能夠預編譯SQL語句,預編譯後的SQL語句被存儲在PreparedStatement對象中。而後可使用該對象屢次高效地執行該語句。簡而言之,使用PreparedStatement比使用Statement的效率要高。

•使用PreparedStatement比使用Statement多了以下三個好處:

–PreparedStatement預編譯SQL語句,性能更好。

–PreparedStatment無需「拼接」SQL語句,編程更簡單。

–PreparedStatement能夠防止SQL注入,安全性更好。


 

 CallableStatment

 

 

•調用存儲過程使用CallableStatement,能夠經過Connection的prepareCall方法來建立

CallableStatement對象,建立該對象時須要傳入調用存儲過程的SQL語句,調用存儲過程的SQL語

句老是這種格式:{call 過程名(?,?,?...)},其中的問號做爲存儲過程參數的佔位符。

 

•存儲過程的參數既有傳入參數,也有傳出參數。所謂傳入參數就是Java程序必須爲這些參數傳入

值,那麼能夠經過CallableStatement的setXxx方法爲傳入參數設置值;所謂傳出參數就是Java程

序能夠經過該參數獲取存儲過程裏的值,那麼CallableStatement須要調用

registerOutParameter方法來註冊該參數。 


 

 可滾動、可更新的結果集 

 

 

•以默認方式打開的ResultSet是不可更新的,若是但願建立可更新的ResultSet,必須在建立

Statement或PreparedStatement時傳入額外的參數。Connection在建立Statement或

PreparedStatement時還可額外傳入兩個參數:

 

•resultSetType:控制ResultSet的類型,該參數能夠是以下三個值:

–ResultSet.TYPE_FORWARD_ONLY:該常量控制記錄指針只能向前移動。這是JDK1.4之前的默認值。

–ResultSet.TYPE_SCROLL_INSENSITIVE:該常量控制記錄指針能夠自由移動(可滾動結果集),但底層數據的改變不會影響ResultSet的內容。

–ResultSet.TYPE_SCROLL_SENSITIVE:該常量控制記錄指針能夠自由移動(可滾動結果集),並且底層數據的改變會影響ResultSet的內容。

•resultSetConcurrency:控制ResultSet的併發類型,該參數能夠接受以下兩個值:

–ResultSet.CONCUR_READ_ONLY:該常量指示ResultSet是隻讀的併發模式(默認)。

–ResultSet.CONCUR_UPDATABLE:該常量指示ResultSet是可更新的併發模式。 


 

 處理Blob類型數據 

 

 

•因此將Blob數據插入數據庫須要使用PreparedStatement,該對象有一個方法:

setBinaryStream(int parameterIndex, InputStream x),該方法能夠爲指定參數傳入二進制

輸入流,從而能夠實現將Blob數據保存到數據庫的功能。

 

•當咱們須要從ResultSet裏取出Blob數據時,能夠調用ResultSet的getBlob(int

columnIndex)方法,該方法將返回一個Blob對象,Blob對象提供了getBinaryStream方法來獲

取該Blob數據的輸入流,也可以使用Blob對象提供的getBytes方法直接取出該Blob對象封裝的二進制

數據。


 

 使用ResultSetMetaData

 

 

•ResultSet裏包含一個getMetaData()方法,該方法返回該ResultSet對應的

ResultSetMetaData對象。一旦得到了ResultSetMetaData對象,就可經過

ResultSetMetaData提供的大量的方法來返回ResultSet的描述信息,經常使用的方法有以下三個:

 

–int getColumnCount():返回該ResultSet的列數量。

–String getColumnName(int column):返回指定索引的列名。

–int getColumnType(int column):返回指定索引的列類型。


 

 事務

 

 

•事務是由一步或幾步數據庫操做序列組成的邏輯執行單元,這系列操做要麼所有執行,要麼所有放棄執行。程序和事務是兩個不一樣的概念。通常而言:一段程序中可能包含多個事務。

•事務具有四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、和持續性(Durability)。這四個特性也簡稱爲ACID性。

原子性(Atomicity)

一致性(Consistency)

隔離性(Isolation)

持續性(Durability)


 

 事務的組成

 

 

•數據庫的事務由下列語句組成:

–一組DML語句,通過這組DML修改後數據將保持較好的一致性。

–一個 DDL 語句。

–一個 DCL 語句。

•DDL和DCL語句最多隻能有一個,由於DDL和DCL語句都會致使事務當即提交。


 

 事務的結束

 

 

•當事務所包含的所有數據庫操做都成功執行後,應該提交(commit)事務,使這些修改永久生效。事務提交有兩種方式:顯式提交和自動提交。

–顯式提交:使用commit

–自動提交:執行DDL或DCL,或者程序正常退出。

•當事務所包含的任意一個數據庫操做執行失敗後,應該回滾(rollback)事務,使該事務中所做的修改所有失效。事務回滾有兩種方式:顯式回滾和自動回滾。

–顯式回滾:使用rollback

–自動回滾:系統錯誤或者強行退出。


 

 JDBC的事務支持 

 

 

•Connection的setAutoCommit方法來關閉自動提交,開啓事務,以下SQL語句所示:

conn.setAutoCommit(false);

•程序能夠調用Connection的commit方法來提交事務,以下代碼所示:

conn.commit();

•若是任意一條SQL語句執行失敗,咱們應該用Connection的rollback來回滾事務,以下代碼所示:

conn.rollback();


 

 事務的中間點

 

 

•Connection也提供了設置中間點的方法:setSavepoint,Connection提供了兩個方法來設置中間點:

–Savepoint setSavepoint():在當前事務中建立一個未命名的中間點),並返回表明該中間點的Savepoint對象。

–Savepoint setSavepoint(String name):在當前事務中建立一個具備指定名稱的中間點,並返回表明該中間點的Savepoint對象。

•一般來講,設置中間點時沒有太大的必要指定名稱,由於Connection回滾到指定中間點時,並非

根據名字回滾的,而是根據中間點對象回滾的。Connection提供了rollback(Savepoint

savepoint)方法來回滾到指定中間點。


 

 批量更新

 

 

•JDBC還提供了一個批量更新的功能,使用批量更新時,多條SQL語句將會被做爲一批操做被同時收

集、並同時提交。

 

•批量更新必須獲得底層數據庫的支持,能夠經過調用DatabaseMetaData的

supportsBatchUpdates方法來查看底層數據庫是否支持批量更新。

 

•使用批量更新也須要先建立一個Statement對象,而後利用該對象addBatch方法將多條SQL語句

同時收集起來,最後調用Statement對象的executeBatch同時執行這些SQL語句。


 

 DatabaseMetaData

 

 

•JDBC提供了DatabaseMetaData來封裝數據庫鏈接對應數據庫的信息,經過Connection提供的

getMetaData()方法就能夠獲取到數據庫對應的DatabaseMetaData對象。

 

•許多DatabaseMetaData方法以 ResultSet 對象的形式返回查詢的信息,使用ResultSet的常規

方法(例如getString 和 getInt)便可從這些ResultSet對象中獲取數據。若是查詢的信息不可

用,則將返回一個空ResultSet對象。

 

•不少DatabaseMetaData方法都須要傳入一個xxxPattern的模式字符串,這裏的xxxPattern不

是正則表達式,而是SQL裏的模式字符串,即用百分號(%)表明任意多個字符,使用下劃線(_)代

表一個字符。一般狀況下,若是把該模式字符串參數值設置爲null,即代表該參數不做爲過濾條件。 


 

 使用數據庫系統表

 

 

•MySQL的數據庫系統表使用information_schema數據庫來保存,在該數據庫裏包含了大量系統表,經常使用系統表的簡單介紹以下:

–tables-存放數據庫裏全部數據表的信息。

–schemata-存放數據庫裏全部數據庫(與MySQL的Schema一一對應)的信息

–views-存放數據庫裏全部視圖的信息。

–columns-存放數據庫裏全部列的信息。

–triggers-存放數據庫裏全部觸發器的信息。

–routines-存放數據庫裏全部存儲過程和函數的信息。

–key_column_usage-存放數據庫裏全部具備約束的鍵信息。

–table_constraints-存放數據庫所有約束的表信息。

–statistics-存放了數據庫裏所有索引的信息。


 

 數據庫鏈接池

 

 

•數據庫鏈接池的解決方案是:當應用程序啓動時,系統主動創建足夠的數據庫鏈接,並將這些鏈接組

成一個鏈接池。每次應用程序請求數據庫鏈接時,無需從新打開鏈接,而是從池中取出已有的鏈接使

用,使用完後,再也不關閉數據庫鏈接,而是直接將該鏈接歸還給鏈接池。經過使用鏈接池,將大大提升

程序運行效率。

•數據庫鏈接池的經常使用參數有以下:

–數據庫的初始鏈接數。

–鏈接池的最大鏈接數。

–鏈接池的最小鏈接數。

–鏈接池的每次增長的容量。 


 

 兩種常見的開源數據源

 

 

•DBCP是Apache軟件基金組織下的開源鏈接池實現,該鏈接池依賴該組織下的另外一個開源系統:

common-pool。

 

•相比之下,C3P0數據源性能更勝一籌,Hibernate就推薦使用該鏈接池。C3P0鏈接池不只可自動

清理再也不使用的Connection,還能夠自動清理Statement和ResultSet。C3P0鏈接池須要版本爲

1.3以上的JRE,推薦使用1.4以上的JRE。


 

 如今貼出代碼:

 

drop database if exists select_test;
create database select_test;
use select_test;
# 爲了保證從表參照的主表存在,一般應該先建主表。
create table teacher_table
(
    # auto_increment:實際上表明全部數據庫的自動編號策略,一般用做數據表的邏輯主鍵。
    teacher_id int auto_increment,
    teacher_name varchar(255),
    primary key(teacher_id)
);
create table student_table
(
    # 爲本表創建主鍵約束
    student_id int auto_increment primary key,
    student_name varchar(255),
    # 指定java_teacher參照到teacher_table的teacher_id列
    java_teacher int,
    foreign key(java_teacher) references teacher_table(teacher_id)
);
insert into teacher_table
values
(null , 'Yeeku');
insert into teacher_table
values
(null , 'Leegang');
insert into teacher_table
values
(null , 'Martine');
insert into student_table
values
(null , '張三' , 1);
insert into student_table
values
(null , '張三' , 1);
insert into student_table
values
(null , '李四' , 1);
insert into student_table
values
(null , '王五' , 2);
insert into student_table
values
(null , '_王五' , 2);

insert into student_table
values
(null , null , 2);
insert into student_table
values
(null , '趙六' , null);
sql
create table user_inf
(
    user_id int primary key auto_increment,
    user_name varchar(255)
);
sql
public class ConnMySql {
    public static void main(String[] args) throws Exception {
        // 1.加載驅動,使用反射的知識,如今記住這麼寫。
        Class.forName("com.mysql.jdbc.Driver");
        try (
        // 2.使用DriverManager獲取數據庫鏈接,
        // 其中返回的Connection就表明了Java程序和數據庫的鏈接
        // 不一樣數據庫的URL寫法須要查驅動文檔知道,用戶名、密碼由DBA分配
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://127.0.0.1:3306/select_test", "root", "32147");
        // 3.使用Connection來建立一個Statment對象
                Statement stmt = conn.createStatement();
                // 4.執行SQL語句
                /*
                 * Statement有三種執行sql語句的方法: 1 execute 可執行任何SQL語句。- 返回一個boolean值,
                 * 若是執行後第一個結果是ResultSet,則返回true,不然返回false 2 executeQuery
                 * 執行Select語句 - 返回查詢到的結果集 3 executeUpdate 用於執行DML語句。- 返回一個整數,
                 * 表明被SQL語句影響的記錄條數
                 */
                ResultSet rs = stmt.executeQuery("select s.* , teacher_name"
                        + " from student_table s , teacher_table t"
                        + " where t.teacher_id = s.java_teacher")) {
            // ResultSet有系列的getXxx(列索引 | 列名),用於獲取記錄指針
            // 指向行、特定列的值,不斷地使用next()將記錄指針下移一行,
            // 若是移動以後記錄指針依然指向有效行,則next()方法返回true。
            while (rs.next()) {
                System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t"
                        + rs.getString(3) + "\t" + rs.getString(4));
            }
        }
    }
}
View Code

 


public class CallableStatementTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void callProcedure() throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個CallableStatment對象
                CallableStatement cstmt = conn
                        .prepareCall("{call add_pro(?,?,?)}")) {
            cstmt.setInt(1, 4);
            cstmt.setInt(2, 5);
            // 註冊CallableStatement的第三個參數是int類型
            cstmt.registerOutParameter(3, Types.INTEGER);
            // 執行存儲過程
            cstmt.execute();
            // 獲取,並輸出存儲過程傳出參數的值。
            System.out.println("執行結果是: " + cstmt.getInt(3));
        }
    }

    public static void main(String[] args) throws Exception {
        CallableStatementTest ct = new CallableStatementTest();
        ct.initParam("mysql.ini");
        ct.callProcedure();
    }
}
View Code

 

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/select_test
user=root
pass=32147
mysql.ini
public class ExecuteDDL {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void createTable(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個Statment對象
                Statement stmt = conn.createStatement()) {
            // 執行DDL,建立數據表
            stmt.executeUpdate(sql);
        }
    }

    public static void main(String[] args) throws Exception {
        ExecuteDDL ed = new ExecuteDDL();
        ed.initParam("mysql.ini");
        ed.createTable("create table jdbc_test "
                + "( jdbc_id int auto_increment primary key, "
                + "jdbc_name varchar(255), " + "jdbc_desc text);");
        System.out.println("-----建表成功-----");
    }
}
View Code
public class ExecuteDML {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public int insertData(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個Statment對象
                Statement stmt = conn.createStatement()) {
            // 執行DML,返回受影響的記錄條數
            return stmt.executeUpdate(sql);
        }
    }

    public static void main(String[] args) throws Exception {
        ExecuteDML ed = new ExecuteDML();
        ed.initParam("mysql.ini");
        int result = ed.insertData("insert into jdbc_test(jdbc_name,jdbc_desc)"
                + "select s.student_name , t.teacher_name "
                + "from student_table s , teacher_table t "
                + "where s.java_teacher = t.teacher_id;");
        System.out.println("--系統中共有" + result + "條記錄受影響--");
    }
}
View Code
public class ExecuteSQL {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void executeSql(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個Statement對象
                Statement stmt = conn.createStatement()) {
            // 執行SQL,返回boolean值表示是否包含ResultSet
            boolean hasResultSet = stmt.execute(sql);
            // 若是執行後有ResultSet結果集
            if (hasResultSet) {
                try (
                // 獲取結果集
                ResultSet rs = stmt.getResultSet()) {
                    // ResultSetMetaData是用於分析結果集的元數據接口
                    ResultSetMetaData rsmd = rs.getMetaData();
                    int columnCount = rsmd.getColumnCount();
                    // 迭代輸出ResultSet對象
                    while (rs.next()) {
                        // 依次輸出每列的值
                        for (int i = 0; i < columnCount; i++) {
                            System.out.print(rs.getString(i + 1) + "\t");
                        }
                        System.out.print("\n");
                    }
                }
            } else {
                System.out
                        .println("該SQL語句影響的記錄有" + stmt.getUpdateCount() + "條");
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ExecuteSQL es = new ExecuteSQL();
        es.initParam("mysql.ini");
        System.out.println("------執行刪除表的DDL語句-----");
        es.executeSql("drop table if exists my_test");
        System.out.println("------執行建表的DDL語句-----");
        es.executeSql("create table my_test"
                + "(test_id int auto_increment primary key, "
                + "test_name varchar(255))");
        System.out.println("------執行插入數據的DML語句-----");
        es.executeSql("insert into my_test(test_name) "
                + "select student_name from student_table");
        System.out.println("------執行查詢數據的查詢語句-----");
        es.executeSql("select * from my_test");
    }
}
View Code
public class LoginFrame {
    private final String PROP_FILE = "mysql.ini";
    private String driver;
    // url是數據庫的服務地址
    private String url;
    private String user;
    private String pass;
    // 登陸界面的GUI組件
    private JFrame jf = new JFrame("登陸");
    private JTextField userField = new JTextField(20);
    private JTextField passField = new JTextField(20);
    private JButton loginButton = new JButton("登陸");

    public void init()throws Exception
    {
        Properties connProp = new Properties();
        connProp.load(new FileInputStream(PROP_FILE));
        driver = connProp.getProperty("driver");
        url = connProp.getProperty("url");
        user = connProp.getProperty("user");
        pass = connProp.getProperty("pass");
        // 加載驅動
        Class.forName(driver);
        // 爲登陸按鈕添加事件監聽器
        loginButton.addActionListener(e -> {
            // 登陸成功則顯示「登陸成功」
            if (validate(userField.getText(), passField.getText()))
            {
                JOptionPane.showMessageDialog(jf, "登陸成功");
            }
            // 不然顯示「登陸失敗」
            else
            {
                JOptionPane.showMessageDialog(jf, "登陸失敗");
            }
        });
        jf.add(userField , BorderLayout.NORTH);
        jf.add(passField);
        jf.add(loginButton , BorderLayout.SOUTH);
        jf.pack();
        jf.setVisible(true);
    }

    // private boolean validate(String userName, String userPass)
    // {
    // // 執行查詢的SQL語句
    // String sql = "select * from jdbc_test "
    // + "where jdbc_name='" + userName
    // + "' and jdbc_desc='" + userPass + "'";
    // System.out.println(sql);
    // try(
    // Connection conn = DriverManager.getConnection(url , user ,pass);
    // Statement stmt = conn.createStatement();
    // ResultSet rs = stmt.executeQuery(sql))
    // {
    // // 若是查詢的ResultSet裏有超過一條的記錄,則登陸成功
    // if (rs.next())
    // {
    // return true;
    // }
    // }
    // catch(Exception e)
    // {
    // e.printStackTrace();
    // }
    // return false;
    // }

    private boolean validate(String userName, String userPass) {
        try (Connection conn = DriverManager.getConnection(url, user, pass);
                PreparedStatement pstmt = conn
                        .prepareStatement("select * from jdbc_test where jdbc_name=? and jdbc_desc=?")) {
            pstmt.setString(1, userName);
            pstmt.setString(2, userPass);
            try (ResultSet rs = pstmt.executeQuery()) {
                // 若是查詢的ResultSet裏有超過一條的記錄,則登陸成功
                if (rs.next()) {
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) throws Exception {
        new LoginFrame().init();
    }
}
View Code
public class PreparedStatementTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
        // 加載驅動
        Class.forName(driver);
    }

    public void insertUseStatement() throws Exception {
        long start = System.currentTimeMillis();
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個Statment對象
                Statement stmt = conn.createStatement()) {
            // 須要使用100條SQL語句來插入100條記錄
            for (int i = 0; i < 100; i++) {
                stmt.executeUpdate("insert into student_table values("
                        + " null ,'姓名" + i + "' , 1)");
            }
            System.out.println("使用Statement費時:"
                    + (System.currentTimeMillis() - start));
        }
    }

    public void insertUsePrepare() throws Exception {
        long start = System.currentTimeMillis();
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個PreparedStatement對象
                PreparedStatement pstmt = conn
                        .prepareStatement("insert into student_table values(null,?,1)"))

        {
            // 100次爲PreparedStatement的參數設值,就能夠插入100條記錄
            for (int i = 0; i < 100; i++) {
                pstmt.setString(1, "姓名" + i);
                pstmt.executeUpdate();
            }
            System.out.println("使用PreparedStatement費時:"
                    + (System.currentTimeMillis() - start));
        }
    }

    public static void main(String[] args) throws Exception {
        PreparedStatementTest pt = new PreparedStatementTest();
        pt.initParam("mysql.ini");
        pt.insertUseStatement();
        pt.insertUsePrepare();
    }
}
View Code

 

 


driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/select_test
user=root
pass=32147
mysql.ini

 

 

public class BlobTest {
    JFrame jf = new JFrame("圖片管理程序");
    private static Connection conn;
    private static PreparedStatement insert;
    private static PreparedStatement query;
    private static PreparedStatement queryAll;
    // 定義一個DefaultListModel對象
    private DefaultListModel<ImageHolder> imageModel = new DefaultListModel<>();
    private JList<ImageHolder> imageList = new JList<>(imageModel);
    private JTextField filePath = new JTextField(26);
    private JButton browserBn = new JButton("...");
    private JButton uploadBn = new JButton("上傳");
    private JLabel imageLabel = new JLabel();
    // 以當前路徑建立文件選擇器
    JFileChooser chooser = new JFileChooser(".");
    // 建立文件過濾器
    ExtensionFileFilter filter = new ExtensionFileFilter();
    static {
        try {
            Properties props = new Properties();
            props.load(new FileInputStream("mysql.ini"));
            String driver = props.getProperty("driver");
            String url = props.getProperty("url");
            String user = props.getProperty("user");
            String pass = props.getProperty("pass");
            Class.forName(driver);
            // 獲取數據庫鏈接
            conn = DriverManager.getConnection(url, user, pass);
            // 建立執行插入的PreparedStatement對象,
            // 該對象執行插入後能夠返回自動生成的主鍵
            insert = conn.prepareStatement("insert into img_table"
                    + " values(null,?,?)", Statement.RETURN_GENERATED_KEYS);
            // 建立兩個PreparedStatement對象,用於查詢指定圖片,查詢全部圖片
            query = conn.prepareStatement("select img_data from img_table"
                    + " where img_id=?");
            queryAll = conn.prepareStatement("select img_id, "
                    + " img_name from img_table");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void init()throws SQLException
    {
        // -------初始化文件選擇器--------
        filter.addExtension("jpg");
        filter.addExtension("jpeg");
        filter.addExtension("gif");
        filter.addExtension("png");
        filter.setDescription("圖片文件(*.jpg,*.jpeg,*.gif,*.png)");
        chooser.addChoosableFileFilter(filter);
        // 禁止「文件類型」下拉列表中顯示「全部文件」選項。
        chooser.setAcceptAllFileFilterUsed(false);
        // ---------初始化程序界面---------
        fillListModel();
        filePath.setEditable(false);
        // 只能單選
        imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JPanel jp = new JPanel();
        jp.add(filePath);
        jp.add(browserBn);
        browserBn.addActionListener(event -> {
            // 顯示文件對話框
            int result = chooser.showDialog(jf , "瀏覽圖片文件上傳");
            // 若是用戶選擇了APPROVE(贊同)按鈕,即打開,保存等效按鈕
            if(result == JFileChooser.APPROVE_OPTION)
            {
                filePath.setText(chooser.getSelectedFile().getPath());
            }
        });
        jp.add(uploadBn);
        uploadBn.addActionListener(avt -> {
            // 若是上傳文件的文本框有內容
            if (filePath.getText().trim().length() > 0)
            {
                // 將指定文件保存到數據庫
                upload(filePath.getText());
                // 清空文本框內容
                filePath.setText("");
            }
        });
        JPanel left = new JPanel();
        left.setLayout(new BorderLayout());
        left.add(new JScrollPane(imageLabel) , BorderLayout.CENTER);
        left.add(jp , BorderLayout.SOUTH);
        jf.add(left);
        imageList.setFixedCellWidth(160);
        jf.add(new JScrollPane(imageList) , BorderLayout.EAST);
        imageList.addMouseListener(new MouseAdapter()
        {
            public void mouseClicked(MouseEvent e)
            {
                // 若是鼠標雙擊
                if (e.getClickCount() >= 2)
                {
                    // 取出選中的List項
                    ImageHolder cur = (ImageHolder)imageList.
                    getSelectedValue();
                    try
                    {
                        // 顯示選中項對應的Image
                        showImage(cur.getId());
                    }
                    catch (SQLException sqle)
                    {
                        sqle.printStackTrace();
                    }
                }
            }
        });
        jf.setSize(620, 400);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }

    // ----------查找img_table填充ListModel----------
    public void fillListModel() throws SQLException {

        try (
        // 執行查詢
        ResultSet rs = queryAll.executeQuery()) {
            // 先清除全部元素
            imageModel.clear();
            // 把查詢的所有記錄添加到ListModel中
            while (rs.next()) {
                imageModel.addElement(new ImageHolder(rs.getInt(1), rs
                        .getString(2)));
            }
        }
    }

    // ---------將指定圖片放入數據庫---------
    public void upload(String fileName) {
        // 截取文件名
        String imageName = fileName.substring(fileName.lastIndexOf('\\') + 1,
                fileName.lastIndexOf('.'));
        File f = new File(fileName);
        try (InputStream is = new FileInputStream(f)) {
            // 設置圖片名參數
            insert.setString(1, imageName);
            // 設置二進制流參數
            insert.setBinaryStream(2, is, (int) f.length());
            int affect = insert.executeUpdate();
            if (affect == 1) {
                // 從新更新ListModel,將會讓JList顯示最新的圖片列表
                fillListModel();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // ---------根據圖片ID來顯示圖片----------
    public void showImage(int id) throws SQLException {
        // 設置參數
        query.setInt(1, id);
        try (
        // 執行查詢
        ResultSet rs = query.executeQuery()) {
            if (rs.next()) {
                // 取出Blob列
                Blob imgBlob = rs.getBlob(1);
                // 取出Blob列裏的數據
                ImageIcon icon = new ImageIcon(imgBlob.getBytes(1L,
                        (int) imgBlob.length()));
                imageLabel.setIcon(icon);
            }
        }
    }

    public static void main(String[] args) throws SQLException {
        new BlobTest().init();
    }
}

// 建立FileFilter的子類,用以實現文件過濾功能
class ExtensionFileFilter extends FileFilter {
    private String description = "";
    private ArrayList<String> extensions = new ArrayList<>();

    // 自定義方法,用於添加文件擴展名
    public void addExtension(String extension) {
        if (!extension.startsWith(".")) {
            extension = "." + extension;
            extensions.add(extension.toLowerCase());
        }
    }

    // 用於設置該文件過濾器的描述文本
    public void setDescription(String aDescription) {
        description = aDescription;
    }

    // 繼承FileFilter類必須實現的抽象方法,返回該文件過濾器的描述文本
    public String getDescription() {
        return description;
    }

    // 繼承FileFilter類必須實現的抽象方法,判斷該文件過濾器是否接受該文件
    public boolean accept(File f) {
        // 若是該文件是路徑,接受該文件
        if (f.isDirectory())
            return true;
        // 將文件名轉爲小寫(所有轉爲小寫後比較,用於忽略文件名大小寫)
        String name = f.getName().toLowerCase();
        // 遍歷全部可接受的擴展名,若是擴展名相同,該文件就可接受。
        for (String extension : extensions) {
            if (name.endsWith(extension)) {
                return true;
            }
        }
        return false;
    }
}

// 建立一個ImageHolder類,用於封裝圖片名、圖片ID
class ImageHolder {
    // 封裝圖片的ID
    private int id;
    // 封裝圖片的圖片名字
    private String name;

    public ImageHolder() {
    }

    public ImageHolder(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // id的setter和getter方法
    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

    // name的setter和getter方法
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    // 重寫toString方法,返回圖片名
    public String toString() {
        return name;
    }
}
View Code
public class QueryExecutor {
    JFrame jf = new JFrame("查詢執行器");
    private JScrollPane scrollPane;
    private JButton execBn = new JButton("查詢");
    // 用於輸入查詢語句的文本框
    private JTextField sqlField = new JTextField(45);
    private static Connection conn;
    private static Statement stmt;
    // 採用靜態初始化塊來初始化Connection、Statement對象
    static {
        try {
            Properties props = new Properties();
            props.load(new FileInputStream("mysql.ini"));
            String drivers = props.getProperty("driver");
            String url = props.getProperty("url");
            String username = props.getProperty("user");
            String password = props.getProperty("pass");
            // 加載數據庫驅動
            Class.forName(drivers);
            // 取得數據庫鏈接
            conn = DriverManager.getConnection(url, username, password);
            stmt = conn.createStatement();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // --------初始化界面的方法---------
    public void init() {
        JPanel top = new JPanel();
        top.add(new JLabel("輸入查詢語句:"));
        top.add(sqlField);
        top.add(execBn);
        // 爲執行按鈕、單行文本框添加事件監聽器
        execBn.addActionListener(new ExceListener());
        sqlField.addActionListener(new ExceListener());
        jf.add(top, BorderLayout.NORTH);
        jf.setSize(680, 480);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }

    // 定義監聽器
    class ExceListener implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
            // 刪除原來的JTable(JTable使用scrollPane來包裝)
            if (scrollPane != null) {
                jf.remove(scrollPane);
            }
            try (
            // 根據用戶輸入的SQL執行查詢
            ResultSet rs = stmt.executeQuery(sqlField.getText())) {
                // 取出ResultSet的MetaData
                ResultSetMetaData rsmd = rs.getMetaData();
                Vector<String> columnNames = new Vector<>();
                Vector<Vector<String>> data = new Vector<>();
                // 把ResultSet的全部列名添加到Vector裏
                for (int i = 0; i < rsmd.getColumnCount(); i++) {
                    columnNames.add(rsmd.getColumnName(i + 1));
                }
                // 把ResultSet的全部記錄添加到Vector裏
                while (rs.next()) {
                    Vector<String> v = new Vector<>();
                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
                        v.add(rs.getString(i + 1));
                    }
                    data.add(v);
                }
                // 建立新的JTable
                JTable table = new JTable(data, columnNames);
                scrollPane = new JScrollPane(table);
                // 添加新的Table
                jf.add(scrollPane);
                // 更新主窗口
                jf.validate();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new QueryExecutor().init();
    }
}
View Code
public class ResultSetTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void query(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 使用Connection來建立一個PreparedStatement對象
                // 傳入控制結果集可滾動,可更新的參數。
                PreparedStatement pstmt = conn.prepareStatement(sql,
                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                        ResultSet.CONCUR_UPDATABLE);
                ResultSet rs = pstmt.executeQuery()) {
            rs.last();
            int rowCount = rs.getRow();
            for (int i = rowCount; i > 0; i--) {
                rs.absolute(i);
                System.out.println(rs.getString(1) + "\t" + rs.getString(2)
                        + "\t" + rs.getString(3));
                // 修改記錄指針全部記錄、第2列的值
                rs.updateString(2, "學生名" + i);
                // 提交修改
                rs.updateRow();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ResultSetTest rt = new ResultSetTest();
        rt.initParam("mysql.ini");
        rt.query("select * from student_table");
    }
}
View Code

public class CachedRowSetPage {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public CachedRowSet query(String sql, int pageSize, int page)
            throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery(sql)) {
            // 使用RowSetProvider建立RowSetFactory
            RowSetFactory factory = RowSetProvider.newFactory();
            // 建立默認的CachedRowSet實例
            CachedRowSet cachedRs = factory.createCachedRowSet();
            // 設置每頁顯示pageSize條記錄
            cachedRs.setPageSize(pageSize);
            // 使用ResultSet裝填RowSet,設置從第幾條記錄開始
            cachedRs.populate(rs, (page - 1) * pageSize + 1);
            return cachedRs;
        }
    }

    public static void main(String[] args) throws Exception {
        CachedRowSetPage cp = new CachedRowSetPage();
        cp.initParam("mysql.ini");
        CachedRowSet rs = cp.query("select * from student_table", 3, 2); //// 向後滾動結果集
        while (rs.next()) {
            System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t"
                    + rs.getString(3));
        }
    }
}
View Code
public class CachedRowSetTest {
    private static String driver;
    private static String url;
    private static String user;
    private static String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public CachedRowSet query(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        // 使用RowSetProvider建立RowSetFactory
        RowSetFactory factory = RowSetProvider.newFactory();
        // 建立默認的CachedRowSet實例
        CachedRowSet cachedRs = factory.createCachedRowSet();
        // 使用ResultSet裝填RowSet
        cachedRs.populate(rs); //// 關閉資源
        rs.close();
        stmt.close();
        conn.close();
        return cachedRs;
    }

    public static void main(String[] args) throws Exception {
        CachedRowSetTest ct = new CachedRowSetTest();
        ct.initParam("mysql.ini");
        CachedRowSet rs = ct.query("select * from student_table");
        rs.afterLast();
        // 向前滾動結果集
        while (rs.previous()) {
            System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t"
                    + rs.getString(3));
            if (rs.getInt("student_id") == 3) {
                // 修改指定記錄行
                rs.updateString("student_name", "孫悟空");
                rs.updateRow();
            }
        }
        // 從新獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
        conn.setAutoCommit(false);
        // 把對RowSet所作的修改同步到底層數據庫
        rs.acceptChanges(conn);
    }
}
View Code
public class JdbcRowSetTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void update(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass);
                // 建立JdbcRowSetImpl對象
                JdbcRowSet jdbcRs = new JdbcRowSetImpl(conn)) //
        {
            // 設置SQL查詢語句
            jdbcRs.setCommand(sql);
            // 執行查詢
            jdbcRs.execute();
            jdbcRs.afterLast();
            // 向前滾動結果集
            while (jdbcRs.previous()) {
                System.out.println(jdbcRs.getString(1) + "\t"
                        + jdbcRs.getString(2) + "\t" + jdbcRs.getString(3));
                if (jdbcRs.getInt("student_id") == 3) {
                    // 修改指定記錄行
                    jdbcRs.updateString("student_name", "孫悟空");
                    jdbcRs.updateRow();
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        JdbcRowSetTest jt = new JdbcRowSetTest();
        jt.initParam("mysql.ini");
        jt.update("select * from student_table");
    }
}
View Code
public class RowSetFactoryTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void update(String sql) throws Exception {
        // 加載驅動
        Class.forName(driver);
        // 使用RowSetProvider建立RowSetFactory
        RowSetFactory factory = RowSetProvider.newFactory();
        try (
        // 使用RowSetFactory建立默認的JdbcRowSet實例
        JdbcRowSet jdbcRs = factory.createJdbcRowSet()) {
            // 設置必要的鏈接信息
            jdbcRs.setUrl(url);
            jdbcRs.setUsername(user);
            jdbcRs.setPassword(pass);
            // 設置SQL查詢語句
            jdbcRs.setCommand(sql);
            // 執行查詢
            jdbcRs.execute();
            jdbcRs.afterLast();
            // 向前滾動結果集
            while (jdbcRs.previous()) {
                System.out.println(jdbcRs.getString(1) + "\t"
                        + jdbcRs.getString(2) + "\t" + jdbcRs.getString(3));
                if (jdbcRs.getInt("student_id") == 3) {
                    // 修改指定記錄行
                    jdbcRs.updateString("student_name", "孫悟空");
                    jdbcRs.updateRow();
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        RowSetFactoryTest jt = new RowSetFactoryTest();
        jt.initParam("mysql.ini");
        jt.update("select * from student_table");
    }
}
View Code

 


 

public class TransactionTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void insertInTransaction(String[] sqls) throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (Connection conn = DriverManager.getConnection(url, user, pass)) {
            // 關閉自動提交,開啓事務
            conn.setAutoCommit(false);
            try (
            // 使用Connection來建立一個Statment對象
            Statement stmt = conn.createStatement()) {
                // 循環屢次執行SQL語句
                for (String sql : sqls) {
                    stmt.executeUpdate(sql);
                }
            }
            // 提交事務
            conn.commit();
        }
    }

    public static void main(String[] args) throws Exception {
        TransactionTest tt = new TransactionTest();
        tt.initParam("mysql.ini");
        String[] sqls = new String[] {
                "insert into student_table values(null , 'aaa' ,1)",
                "insert into student_table values(null , 'bbb' ,1)",
                "insert into student_table values(null , 'ccc' ,1)",
                // 下面這條SQL語句將會違反外鍵約束,
                // 由於teacher_table中沒有ID爲5的記錄。
                "insert into student_table values(null , 'ccc' ,5)" //
        };
        tt.insertInTransaction(sqls);
    }
}
View Code

 

 

public class DatabaseMetaDataTest {
    private String driver;
    private String url;
    private String user;
    private String pass;

    public void initParam(String paramFile) throws Exception {
        // 使用Properties類來加載屬性文件
        Properties props = new Properties();
        props.load(new FileInputStream(paramFile));
        driver = props.getProperty("driver");
        url = props.getProperty("url");
        user = props.getProperty("user");
        pass = props.getProperty("pass");
    }

    public void info() throws Exception {
        // 加載驅動
        Class.forName(driver);
        try (
        // 獲取數據庫鏈接
        Connection conn = DriverManager.getConnection(url, user, pass)) {
            // 獲取的DatabaseMetaData對象
            DatabaseMetaData dbmd = conn.getMetaData();
            // 獲取MySQL支持的全部表類型
            ResultSet rs = dbmd.getTableTypes();
            System.out.println("--MySQL支持的表類型信息--");
            printResultSet(rs);
            // 獲取當前數據庫的所有數據表
            rs = dbmd.getTables(null, null, "%", new String[] { "TABLE" });
            System.out.println("--當前數據庫裏的數據表信息--");
            printResultSet(rs);
            // 獲取student_table表的主鍵
            rs = dbmd.getPrimaryKeys(null, null, "student_table");
            System.out.println("--student_table表的主鍵信息--");
            printResultSet(rs);
            // 獲取當前數據庫的所有存儲過程
            rs = dbmd.getProcedures(null, null, "%");
            System.out.println("--當前數據庫裏的存儲過程信息--");
            printResultSet(rs);
            // 獲取teacher_table表和student_table之間的外鍵約束
            rs = dbmd.getCrossReference(null, null, "teacher_table", null,
                    null, "student_table");
            System.out.println("--teacher_table表和student_table之間" + "的外鍵約束--");
            printResultSet(rs);
            // 獲取student_table表的所有數據列
            rs = dbmd.getColumns(null, null, "student_table", "%");
            System.out.println("--student_table表的所有數據列--");
            printResultSet(rs);
        }
    }

    public void printResultSet(ResultSet rs) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        // 打印ResultSet的全部列標題
        for (int i = 0; i < rsmd.getColumnCount(); i++) {
            System.out.print(rsmd.getColumnName(i + 1) + "\t");
        }
        System.out.print("\n");
        // 打印ResultSet裏的所有數據
        while (rs.next()) {
            for (int i = 0; i < rsmd.getColumnCount(); i++) {
                System.out.print(rs.getString(i + 1) + "\t");
            }
            System.out.print("\n");
        }
        rs.close();
    }

    public static void main(String[] args) throws Exception {
        DatabaseMetaDataTest dt = new DatabaseMetaDataTest();
        dt.initParam("mysql.ini");
        dt.info();
    }
}
View Code
相關文章
相關標籤/搜索