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,即數據操做語言):主要由 insert、update和delete三個關鍵字完成。 •DDL語句(Data Definition Language,即便數據定義語言):主要由create、alter、drop和truncate四個關鍵字完成。 •DCL語句(Data Control Language,即便數據控制語言):主要由grant 和revoke兩個關鍵字完成。 •事務控制語句:主要由commit、rollback和savepoint三個關鍵字完成。
DDL語句
•DDL語句是操做數據庫對象的語句,包括 –建立(create) –刪除(drop) –修改(alter)數據庫對象。
數據庫對象
建立表的語法
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); create table user_inf ( user_id int primary key auto_increment, user_name varchar(255) ); 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)); } } } }
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(); } }
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/select_test user=root pass=32147 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("-----建表成功-----"); } } 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 + "條記錄受影響--"); } } 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"); } } 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(); } } 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(); } }
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/select_test user=root pass=32147
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; } } 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(); } } 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"); } } 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)); } } } 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); } } 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"); } } 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"); } }
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); } }
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(); } } |