java数据库编程——执行SQL 语句
【0】README
1) 本文文字描述+source code 均轉自 core java volume 2 , 旨在理解 java數據庫編程——執行SQL 語句 的基礎知識 ;
2)for source code, please visit : https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapter4/executeSQL
3)for database connection config, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/database.properties
【1】java數據庫編程——執行SQL 語句相關
1)執行 SQL 命令前, 首先需要創建一個 Statement 對象: 要創建 statement 對象,不需要調用 DriverManager.getConnection 方法所獲得的 Connection對象;(干貨——Statement object == 語句對象)
- step1) Statement stat = conn.createStatement();
step2) 將要執行的 SQL 語句放入字符串中,如:
String command = “update ….”;
step3) 然后,調用Statement 接口中的executeUpdate 方法:
stat.executeUpdate(command); // executeUpdate 方法:將返回受SQL命令影響的行數, 或者對于不返回行數的語句返回0; (干貨——executeUpdate返回受SQL命令影響的行數,或者0)
2)execute系列方法: (干貨——execute系列方法:executeUpdate + executeQuery + execute)
- 2.1)executeUpdate 方法:既可以執行諸如 insert, update, 和 delete之類的操作(DML), 也可以執行諸如 create , drop 之類的數據定義語句(DDL);
- 2.2)executeQuery方法: 執行 select 查詢語句時 必須使用 executeQuery 方法;
- 2.3)execute 方法: 可以執行任意的sql 語句, 通常只用于用戶提供的交互式查詢;
3)查詢結果(ResultSet 類型): executeQuery 方法返回一個ResultSet類型的對象, 可以通過它來每次一行地迭代遍歷所有查詢結果;
ResultSet rs = stat.executeQuery(“select * from books”);
3.1)分析結果集時通常可以使用類似如下循環語句的代碼:
while(rs.next() )
{
look at a row of the result set
}Warnning)
- W1)ResultSet接口的 迭代協議與 java.util.Iterator 接口稍有不同。 對于ResultSet 接口, 迭代器初始化時被設定在第一行之前的位置,必須調用 next 方法將它移動到第一行; (干貨——ResultSet接口的 迭代協議與 java.util.Iterator 接口稍有不同)
- W2)另外,它沒有hasNext方法, 我們需要不斷地調用 next, 直至該方法返回 false;
- W3)結果集中行的順序是任意的, 不能為行序強加任何意義; (干貨——ResultSet結果集中行的順序是任意的, 不能為行序強加任何意義)
3.2)查看每一行,需要知道每一列的內容:
String str = rs.getString(1);
double price = rs.getDouble(1);3.3)不同的數據類型有不同的訪問器: 比如 getString 和 getDouble; 每個訪問器都有兩種形式,一種接收數字類型參數,一個接收字符串類型參數;
Warning) 數據庫的列序號從1開始算 ;
3.4)當使用 字符串參數時, 指的是結果集中以該字符串為列名的列;如,
rs.getDouble(“price”) 返回列名為 Price 的列所對應的值;- 3.5)當get方法的類型和列的數據類型不一致時, 每個get 方法都會進行合理的類型轉換;
【2】管理連接、語句和結果集
1)每個Connection對象都可以創建一個或多個 Statement對象;
- 1.1)同一個Statement對象可以用于不相關的命令和查詢;
- 1.2)但是,一個Statement對象最多只能有一個打開的結果集;
- 1.3)需要說明的是: 至少有一種常用的數據庫(Microsoft SQL Server) 的JDBC驅動程序只允許同時存在一個活動的 Statement 對象。使用 DatabaseMetaData 接口中的 getMaxStatements 方法可以獲取JDBC 驅動程序支持的同時活動的語句對象的總數;
- 1.3.1)這看上去很有局限性。實際上,我們通常并不需要同時處理多個 結果集。對數據庫進行組合查詢比使用 java 程序遍歷多個結果集要高效得多; (干貨——我們通常并不需要同時處理多個 結果集,對數據庫進行組合查詢比使用 java 程序遍歷多個結果集要高效得多)
- 1.4)close方法:使用完 ResultSet , Statement , Connection對象后,立即調用 close方法;
- 1.5)closeOnCompletion方法: 在java 7中, 可以在 Statement 上調用 closeOnCompletion 方法, 在其所有結果集都被關閉后, 該語句會立即被自動關閉; (干貨——java7引入的新方法closeOnCompletion)
1.6)如果所用連接都是短時的,無需考慮關閉語句和結果集。 只需要將 close 語句放 在 帶資源的try語句中, 以便確保最終連接對象不可能繼續保持打開狀態:
try (Connnection conn =…)
{
Statement stat = conn.createStatement();
ResultSet result = stat.executeQuery(queryStr);
process query result
}
Attention) 應該使用帶資源的try 語句塊來關閉連接,并使用一個單獨的 try /catch 塊處理異常。 分離 try 程序塊可以 提高代碼的可讀性和可維護性;
【3】分析 SQL 異常(SQLException)
1) java 6 改進了 SQLException 類,讓其實現了 Iterable接口, 其 iterator() 方法可以產生一個 Iterable< Throwable>;
1.1) 這個迭代器是可以迭代這兩個鏈, 首先迭代第一個 SQLException 的成因鏈, 然后迭代下一個 SQLException ,以此類推;如,
for(Throwable t : sqlException)
{
do sth with t
}1.2)可以在 SQLException 上調用 getSQLState 和 getErrorCode 方法來進一步分析它;
2) SQLException 按照層次結構樹的方式組合到了一起, 如下圖所示:
- 2.1)數據庫驅動程序將非致命問題作為警告報告,我們可以從連接(Connection), 語句(Statement)或結果集(ResultSet)中獲取這些警告;
- 2.2)SQLWarning: 是 SQLException的子類,我們可以調用 getSQLState 和 getErrorCode 來獲取有關警告的更多信息; (干貨——SQLWarning 定義)
2.3)要獲得所有警告,使用下面的循環:
SQLWarning w = stat.getWarning()
while(w != null)
{
do wth with w
w = w.nextWarning();
}2.4)當數據從數據庫中讀出并意外被截斷時, SQLWarning 的 DataTruncation 子類就派上用場了; 如果數據截斷發送在更新語句中, 那么DataTrucation 將會被當做異常拋出;
【4】組裝數據庫
1)看個荔枝:(用java 操作數據庫)
step1)連接數據庫。
- step1.1) getConnection 方法:讀取database.properties 文件中的 屬性信息,并將屬性jdbc.drivers 添加到系統屬性中;
- step1.2) 驅動程序管理器:使用屬性jdbc.drivers 加載相應的驅動程序;
- step1.3) getConnection方法: 使用 jdbc.url , jdbc.username, jdbc.password 等屬性打開數據庫連接;
step2)使用 sql 語句打開文件;
- step3) 使用 泛化的execute 方法執行每條語句;
- step4) 如果產生了結果集, 則打印結果;
- step5) 如果運行過程中出現 SQL 異常, 則打印出這個異常以及所有可能包含在其中的與其連接在一起的相關異常;
- step6)關閉數據庫連接;
2)運行結果如下:
(java -classpath .;D:\Software_Cluster\Development\mysql\mysql-connector-java-5.1.17\mysql-connector-java-5.1.17-bin.jar com.corejava.chapter4.ExecSQL)
3)source code at a glance
class ExecSQL {private static String cur_dir = System.getProperty("user.dir") + File.separator + "com" + File.separator + "corejava" + File.separator + "chapter4" + File.separator;public static void main(String args[]) throws IOException{try{Scanner in = args.length == 0 ? new Scanner(System.in) : new Scanner(Paths.get(args[0]));try (Connection conn = getConnection()){Statement stat = conn.createStatement();while (true){if (args.length == 0) System.out.println("Enter command or EXIT to exit:");if (!in.hasNextLine()) return;String line = in.nextLine();if (line.equalsIgnoreCase("EXIT")) return;if (line.trim().endsWith(";")) // remove trailing semicolon{line = line.trim();line = line.substring(0, line.length() - 1);}try{boolean isResult = stat.execute(line);if (isResult){ResultSet rs = stat.getResultSet(); //結果集showResultSet(rs); // 打印結果集}else{int updateCount = stat.getUpdateCount();System.out.println(updateCount + " rows updated");}}catch (SQLException ex){for (Throwable e : ex)e.printStackTrace();}}}}catch (SQLException e){for (Throwable t : e)t.printStackTrace();}}public static Connection getConnection() throws SQLException, IOException{Properties props = new Properties();try (InputStream in = Files.newInputStream(Paths.get(cur_dir + "database.properties"))){props.load(in);}String drivers = props.getProperty("jdbc.drivers");if (drivers != null) System.setProperty("jdbc.drivers", drivers);String url = props.getProperty("jdbc.url");String username = props.getProperty("jdbc.username");String password = props.getProperty("jdbc.password");return DriverManager.getConnection(url, username, password);}public static void showResultSet(ResultSet result) throws SQLException{ResultSetMetaData metaData = result.getMetaData(); // 結果集元數據int columnCount = metaData.getColumnCount();for (int i = 1; i <= columnCount; i++){if (i > 1) System.out.print(", ");System.out.print(metaData.getColumnLabel(i));}System.out.println();while (result.next()) // 循環打印結果集{for (int i = 1; i <= columnCount; i++){if (i > 1) System.out.print(", ");System.out.print(result.getString(i));}System.out.println();}} }總結
以上是生活随笔為你收集整理的java数据库编程——执行SQL 语句的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ps图层添加蒙版快捷键(ps图层蒙版快捷
- 下一篇: java数据库编程——执行查询操作(一)