JDBC的使用流程,通過JDBC進行對資料庫增刪改查的操作及代碼封裝。 ...
JDBC的概念
JDBC(Java DataBase Connectivity,java資料庫連接)是一種用於執行SQL語句的Java API,可以為多種關係資料庫提供統一訪問,它由一組用Java語言編寫的類和介面組成。JDBC提供了一種基準,據此可以構建更高級的工具和介面,使資料庫開發人員能夠編寫資料庫應用程式。
JDBC的使用流程
導入jar包
1、下載有關資料庫的jar包(下載地址:http://central.maven.org/maven2/mysql/mysql-connector-java/)
2、導入jar包,在Build Path里配置環境
Build Path-->Add JARs
載入驅動
// 載入驅動程式:Class.forName(driverClass) // 載入mysql驅動: Class.forName("com.mysql.jdbc.Driver"); Class.forName("com.mysql.cj.jdbc.Driver"); // 8.0版本以後的mysql驅動 // 載入oracle驅動: Class.forName("oracle.jdbc.driver.OracleDriver");
獲取資料庫連接對象
String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, user, password);
參數含義:
url: 表示要連接的數據地址
user: 資料庫的用戶名
password: 資料庫的密碼
作用:
連接到指定的資料庫並返回連接對象。
創建sql命令對象(編譯和發送sql命令給資料庫)
Statement stmt = conn.createStatement();
創建sql命令
String sql = "insert into user values(13,'王13','wang13')";
指定sql命令,獲得返回結果
int i = stmt.executeUpdate(sql);
ResultSet rs = stmt.executeQuery(sql)
增刪改 時調用 stmt.executeUpdate(sql)方法。返回值為 int類型。大於等於 1 時表示成功,為 0 時表示失敗。
查詢 調用 stmt.executeQuery(sql)方法。返回ResultSet 類型,表示一個結果集。
ResultSet對象是基於指針進行數據存儲的,類似枚舉。不便於數據的針對性的獲取。可將數據轉換到ArrayList中進行存儲。
關閉資源
stmt.close();
conn.close();
關閉之前打開的資源。需要拋出異常。
對數據的增刪改查
增加 (insert)
// 聲明jdbc變數 Connection conn = null; Statement stmt = null; // 聲明jdbc參數 String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; try { // 1 載入驅動類 Class.forName(driver); // 2.獲取資料庫連接對象(連接指定資料庫) conn = DriverManager.getConnection(url, user, password); // 3.創建sql命令對象(編譯和發送sql命令給資料庫) stmt = conn.createStatement(); // 4.創建sql命令 String sql = "insert into user values(13,'王13','wang13')"; // 5.指定sql命令 int i = stmt.executeUpdate(sql); System.out.println("執行結果:" + i); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // 6.關閉資源 try { stmt.close(); conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
修改 (update)
// 聲明jdbc變數 Connection conn = null; Statement stmt = null; // 聲明jdbc參數 String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; try { // 1 載入驅動類 Class.forName(driver); // 2.獲取資料庫連接對象(連接指定資料庫) conn = DriverManager.getConnection(url, user, password); // 3.創建sql命令對象(編譯和發送sql命令給資料庫) stmt = conn.createStatement(); // 4.創建sql命令 String sql = "update user set username='王update' where id=13"; // 5.指定sql命令 int i = stmt.executeUpdate(sql); System.out.println("執行結果:" + i); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // 6.關閉資源 try { stmt.close(); conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
刪除 (delete)
// 聲明jdbc變數 Connection conn = null; Statement stmt = null; // 聲明jdbc參數 String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; try { // 1 載入驅動類 Class.forName(driver); // 2.獲取資料庫連接對象(連接指定資料庫) conn = DriverManager.getConnection(url, user, password); // 3.創建sql命令對象(編譯和發送sql命令給資料庫) stmt = conn.createStatement(); // 4.創建sql命令 String sql = "delete from user where id=11"; // 5.指定sql命令 int i = stmt.executeUpdate(sql); System.out.println("執行結果:" + i); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // 6.關閉資源 try { stmt.close(); conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
查詢(select)
// 聲明jdbc變數 Connection conn = null; Statement stmt = null; // 聲明jdbc參數 String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; try { // 1 載入驅動類 Class.forName(driver); // 2.獲取資料庫連接對象(連接指定資料庫) conn = DriverManager.getConnection(url, user, password); // 3.創建sql命令對象(編譯和發送sql命令給資料庫) stmt = conn.createStatement(); // 4.創建sql命令 String sql = "select * from user"; // 5.指定sql命令 ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { System.out.println(rs.getInt(1) + " " + rs.getString("username") + " " + rs.getString(3)); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // 6.關閉資源 try { stmt.close(); conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
JDBC的事務管理
事務:一個事件的完成需要幾個子操作的聯合完成。只要有一個子操作執行失敗,則數據回滾到原始狀態,都成功則提交數據。
JDBC預設為自動提交事務。進行增刪改操作時應將其設置為手動提交。
conn.setAutoCommit(false);
預設值為true,自動提交。 false 為手動提交。
使用try catch進行SQL命令執行提交和回滾。
try { conn.commit(); } catch (SQLException e) { conn.rollback(); e.printStackTrace(); }
try 中使用 conn.commit() 進行數據提交,若報錯則在 catch 中使用 conn.rollback() 進行事務回滾。
使用PreparedStatement對象進行資料庫操作
PreparedStatement對象與Statement對象的比較
Statement對象進行資料庫操作時可能會出現 sql 註入的風險。
preparedStatement對象在sql語句中使用占位符,可以防止sql註入。可以預編譯,批量執行同一條SQL語句時效率遠大於Statement對象。
// statement對象執行sql語句 Statement stmt = conn.createStatement(); String sql = "insert into user values(13,'王13','wang13')"; int i = stmt.executeUpdate(sql); // preparedStatement對象執行sql語句 String sql = "insert into user values(?,?,?)"; PraparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 15); ps.setString(2, "王15"); ps.setString(3, "123456"); int i = ps.executeUpdate();
優化封裝代碼
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/test user=root password=123456db.properties
1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Properties; 10 11 public class JUtil { 12 private static String driver; 13 private static String url; 14 private static String user; 15 private static String password; 16 17 static { 18 // 創建properties對象獲取屬性文件的內容 19 Properties p = new Properties(); 20 // 獲取屬性文件的讀取對象流 21 InputStream is = JUtil.class.getResourceAsStream("/db.properties"); 22 try { 23 // 載入屬性配置文件 24 p.load(is); 25 // 獲取jdbc參數 26 driver = p.getProperty("driver"); 27 url = p.getProperty("url"); 28 user = p.getProperty("user"); 29 password = p.getProperty("password"); 30 // 載入驅動 31 Class.forName(driver); 32 } catch (IOException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } catch (ClassNotFoundException e) { 36 // TODO Auto-generated catch block 37 e.printStackTrace(); 38 } 39 } 40 41 // 獲取Connection對象 42 public static Connection getConn() { 43 Connection conn = null; 44 try { 45 conn = DriverManager.getConnection(url, user, password); 46 } catch (SQLException e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 return conn; 51 } 52 53 // 獲取PreparedStatement對象 54 public static PreparedStatement getPre(Connection conn,String sql) { 55 PreparedStatement ps = null; 56 try { 57 ps = conn.prepareStatement(sql); 58 } catch (SQLException e) { 59 // TODO Auto-generated catch block 60 e.printStackTrace(); 61 } 62 return ps; 63 } 64 65 // 關閉資源 66 public static void closeAll(Statement stmt,Connection conn) { 67 try { 68 stmt.close(); 69 } catch (SQLException e) { 70 // TODO Auto-generated catch block 71 e.printStackTrace(); 72 } 73 try { 74 conn.close(); 75 } catch (SQLException e) { 76 // TODO Auto-generated catch block 77 e.printStackTrace(); 78 } 79 } 80 }工具類Jutil
1 /** 2 * 封裝DML 3 * @param sql sql語句 4 * @param objs 參數數組 5 * @return i 大於等於 1 時執行成功,等於 0 時執行失敗。 6 */ 7 private int executeDML(String sql,Object ... objs) { 8 Connection conn = null; 9 PreparedStatement ps = null; 10 int i= 0; 11 try { 12 // 創建連接對象 13 conn = JUtil.getConn(); 14 // 手動提交事物 15 conn.setAutoCommit(false); 16 // 獲得sql語句及參數 17 ps = JUtil.getPre(conn, sql); 18 // 給占位符賦值 19 for(int j = 0; j < objs.length; j++) { 20 ps.setObject(j+1, objs[j]); 21 } 22 // 執行sql命令 23 i = ps.executeUpdate(); 24 // 提交 25 conn.commit(); 26 } catch (SQLException e) { 27 try { 28 // 回滾 29 conn.rollback(); 30 } catch (SQLException e1) { 31 e1.printStackTrace(); 32 } 33 } finally { 34 JUtil.closeAll(ps, conn); 35 } 36 return i; 37 }封裝DML(增刪改)
1 /** 2 * 增加 3 * @param id 4 * @param name 5 * @param pwd 6 * @return i 大於等於 1 時執行成功,等於 0 時執行失敗。 7 */ 8 public int insert(int id,String name,String pwd) { 9 String sql = "insert into user values(?,?,?)"; 10 int i = executeDML(sql,id,name,pwd); 11 return i; 12 }insert增加
1 /** 2 * 修改 3 * @param id 4 * @param name 5 * @param pwd 6 * @return i 大於等於 1 時執行成功,等於 0 時執行失敗。 7 */ 8 public int update(int id,String name,String pwd) { 9 String sql = "update user set username=? where id=?"; 10 int i = executeDML(sql,name,id); 11 return i; 12 }update修改
1 /** 2 * 刪除 3 * @param id 4 * @param name 5 * @param pwd 6 * @return i 大於等於 1 時執行成功,等於 0 時執行失敗。 7 */ 8 public int delete(int id,String name,String pwd) { 9 String sql = "delete from user where id=?"; 10 int i = executeDML(sql, id); 11 return i; 12 }delete刪除
1 /** 2 * 查詢 3 * @return 4 */ 5 public List<User> select() { 6 Connection conn = JUtil.getConn(); 7 String sql = "select * from user"; 8 PreparedStatement ps = JUtil.getPre(conn, sql); 9 List<User> us = new ArrayList<User>(); 10 try { 11 ResultSet rs = ps.executeQuery(); 12 while(rs.next()) { 13 User u = new User(); 14 u.setId(rs.getInt(1)); 15 u.setName(rs.getString(2)); 16 u.setPwd(rs.getString(3)); 17 us.add(u); 18 } 19 } catch (SQLException e) { 20 e.printStackTrace(); 21 } finally { 22 JUtil.closeAll(ps, conn); 23 } 24 return us; 25 }select查詢
常見的JDBC錯誤
1. ClassNotFoundException:
驅動類未找到
2. java.sql.SQLException: No suitable driver found for :mysql://localhost:3306/test
URL錯誤
3. No database selected
未找到資料庫
4. Access denied for user 'root1'@'localhost' (using password: YES)
用戶名或密碼錯誤
5. java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax;
sql語句錯誤
6. java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '13' for key 'PRIMARY'
主鍵衝突