Java中JDBC的使用教程詳解
概念
Java DataBase Connectivity Java 數(shù)據(jù)庫連接, Java語言操作數(shù)據(jù)庫 JDBC本質(zhì):其實是官方(sun公司)定義的一套操作所有關系型數(shù)據(jù)庫的規(guī)則,即接口。各個數(shù)據(jù)庫廠商去實現(xiàn)這套接口,提供數(shù)據(jù)庫驅(qū)動jar包。我們可以使用這套接口(JDBC)編程,真正執(zhí)行的代碼是驅(qū)動jar包中的實現(xiàn)類。
快速入門
步驟
1.導入驅(qū)動jar包
<!--MySQL數(shù)據(jù)庫驅(qū)動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency>
2.注冊驅(qū)動
3.獲取數(shù)據(jù)庫連接對象 Connection
4.定義sql
5.獲取執(zhí)行sql語句的對象 Statement
6.執(zhí)行sql,接受返回結(jié)果
7.處理結(jié)果
8.釋放資源
代碼實現(xiàn)
//1. 導入驅(qū)動jar包 //2.注冊驅(qū)動 Class.forName("com.mysql.jdbc.Driver"); //3.獲取數(shù)據(jù)庫連接對象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root"); //4.定義sql語句 String sql = "update account set balance = 500 where id = 1"; //5.獲取執(zhí)行sql的對象 Statement Statement stmt = conn.createStatement(); //6.執(zhí)行sql int count = stmt.executeUpdate(sql); //7.處理結(jié)果 System.out.println(count); //8.釋放資源 stmt.close(); conn.close();
詳解各個對象
DriverManager:驅(qū)動管理對象
功能:
1.注冊驅(qū)動:告訴程序該使用哪一個數(shù)據(jù)庫驅(qū)動jar
static void registerDriver(Driver driver)
:注冊與給定的驅(qū)動程序 DriverManager 。 寫代碼使用: Class.forName("com.mysql.jdbc.Driver"); 通過查看源碼發(fā)現(xiàn):在com.mysql.jdbc.Driver類中存在靜態(tài)代碼塊
static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
注意:mysql5之后的驅(qū)動jar包可以省略注冊驅(qū)動的步驟。
2.獲取數(shù)據(jù)庫連接:
方法:static Connection getConnection(String url, String user, String password)
參數(shù):
url:指定連接的路徑
語法:jdbc:mysql://ip地址(域名):端口號/數(shù)據(jù)庫名稱 例子:jdbc:mysql://localhost:3306/db3 細節(jié):如果連接的是本機mysql服務器,并且mysql服務默認端口是3306,則url可以簡寫為:jdbc:mysql:///數(shù)據(jù)庫名稱
- user:用戶名
- password:密碼
Connection:數(shù)據(jù)庫連接對象
功能:
獲取執(zhí)行sql 的對象
Statement createStatement() PreparedStatement prepareStatement(String sql)
管理事務:
開啟事務:setAutoCommit(boolean autoCommit) :調(diào)用該方法設置參數(shù)為false,即開啟事務 提交事務:commit() 回滾事務:rollback()
Statement:執(zhí)行sql的對象
1.執(zhí)行sql
boolean execute(String sql)
:可以執(zhí)行任意的sql 了解 int executeUpdate(String sql)
:執(zhí)行DML(insert、update、delete)語句、DDL(create,alter、drop)語句 返回值:影響的行數(shù),可以通過這個影響的行數(shù)判斷DML語句是否執(zhí)行成功 返回值>0的則執(zhí)行成功,反之,則失敗。 ResultSet executeQuery(String sql)
:執(zhí)行DQL(select)語句
2.練習:
- account表 添加一條記錄
- account表 修改記錄
- account表 刪除一條記錄
代碼:
Statement stmt = null; Connection conn = null; try { //1. 注冊驅(qū)動 Class.forName("com.mysql.jdbc.Driver"); //2. 定義sql String sql = "insert into account values(null,'王五',3000)"; //3.獲取Connection對象conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root"); //4.獲取執(zhí)行sql的對象 Statement stmt = conn.createStatement(); //5.執(zhí)行sql int count = stmt.executeUpdate(sql);//影響的行數(shù) //6.處理結(jié)果 System.out.println(count); if(count > 0){ System.out.println("添加成功!"); }else{ System.out.println("添加失??!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally { //stmt.close(); //7. 釋放資源 //避免空指針異常 if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
ResultSet:結(jié)果集對象,封裝查詢結(jié)果
boolean next()
: 游標向下移動一行,判斷當前行是否是最后一行末尾(是否有數(shù)據(jù)),如果是,則返回false,如果不是則返回true getXxx(參數(shù))
:獲取數(shù)據(jù) Xxx:代表數(shù)據(jù)類型 如: int getInt() , String getString() 參數(shù):
- int:代表列的編號,從1開始 如: getString(1)
- String:代表列名稱。 如: getDouble("balance")
注意: 使用步驟:
- 游標向下移動一行
- 判斷是否有數(shù)據(jù)
- 獲取數(shù)據(jù)
//循環(huán)判斷游標是否是最后一行末尾。 while(rs.next()){ //獲取數(shù)據(jù) //6.2 獲取數(shù)據(jù) int id = rs.getInt(1); String name = rs.getString("name"); double balance = rs.getDouble(3); System.out.println(id + "---" + name + "---" + balance); }
PreparedStatement:執(zhí)行sql的對象
- SQL注入問題:在拼接sql時,有一些sql的特殊關鍵字參與字符串的拼接。會造成安全性問題
- 輸入用戶隨便,輸入密碼:a' or 'a' = 'a
- sql:select from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
- 解決sql注入問題:使用PreparedStatement對象來解決
- 預編譯的SQL:參數(shù)使用?作為占位符
- 步驟:
- 導入驅(qū)動jar包 mysql-connector-java-5.1.37-bin.jar
- 注冊驅(qū)動
- 獲取數(shù)據(jù)庫連接對象 Connection
- 定義sql
注意:sql的參數(shù)使用?作為占位符。 如:select from user where username = ? and password = ?;
- 獲取執(zhí)行sql語句的對象 PreparedStatement Connection.prepareStatement(String sql)
- 給?賦值:
方法: setXxx(參數(shù)1,參數(shù)2) 參數(shù)1:?的位置編號 從1 開始 參數(shù)2:?的值
- 執(zhí)行sql,接受返回結(jié)果,不需要傳遞sql語句
- 處理結(jié)果
- 釋放資源
- 注意:后期都會使用PreparedStatement來完成增刪改查的所有操作
- 可以防止SQL注入
- 效率更高
抽取JDBC工具類 : JDBCUtils
目的:簡化書寫
分析
1.注冊驅(qū)動也抽取
2.抽取一個方法獲取連接對象
需求:不想傳遞參數(shù)(麻煩),還得保證工具類的通用性。 解決:配置文件jdbc.properties
url=
user=
password=
3.抽取一個方法釋放資源
代碼實現(xiàn)
public class JDBCUtils { private static String url; private static String user; private static String password; private static String driver; /** 文件的讀取,只需要讀取一次即可拿到這些值。使用靜態(tài)代碼塊 */ static{ //讀取資源文件,獲取值。 try { //1. 創(chuàng)建Properties集合類。 Properties pro = new Properties(); //獲取src路徑下的文件的方式--->ClassLoader 類加載器 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); URL res = classLoader.getResource("jdbc.properties"); String path = res.getPath(); System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties //2. 加載文件 // pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties")); pro.load(new FileReader(path)); //3. 獲取數(shù)據(jù),賦值 url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); //4. 注冊驅(qū)動 Class.forName(driver); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** 獲取連接 @return 連接對象 */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password); } /** 釋放資源 @param stmt @param conn */ public static void close(Statement stmt,Connection conn){ if( stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if( conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** 釋放資源 @param stmt @param conn */ public static void close(ResultSet rs,Statement stmt, Connection conn){ if( rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if( stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if( conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
練習
需求
- 通過鍵盤錄入用戶名和密碼
- 判斷用戶是否登錄成功
select from user where username = "" and password = ""; 如果這個sql有查詢結(jié)果,則成功,反之,則失敗
步驟
1.創(chuàng)建數(shù)據(jù)庫表 user
CREATE TABLE USER( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32), PASSWORD VARCHAR(32) ); INSERT INTO USER VALUES(NULL,'zhangsan','123'); INSERT INTO USER VALUES(NULL,'lisi','234');
2.代碼實現(xiàn)
public class JDBCDemo9 { public static void main(String[] args) { //1.鍵盤錄入,接受用戶名和密碼 Scanner sc = new Scanner(System.in); System.out.println("請輸入用戶名:"); String username = sc.nextLine(); System.out.println("請輸入密碼:"); String password = sc.nextLine(); //2.調(diào)用方法 boolean flag = new JDBCDemo9().login(username, password); //3.判斷結(jié)果,輸出不同語句 if(flag){ //登錄成功 System.out.println("登錄成功!"); }else{ System.out.println("用戶名或密碼錯誤!"); } } /** 登錄方法 */ public boolean login(String username ,String password){ if(username == null || password == null){ return false; } //連接數(shù)據(jù)庫判斷是否登錄成功 Connection conn = null; Statement stmt = null; ResultSet rs = null; //1.獲取連接 try { conn = JDBCUtils.getConnection(); //2.定義sql String sql = "select from user where username = '"+username+"' and password = '"+password+"' "; //3.獲取執(zhí)行sql的對象 stmt = conn.createStatement(); //4.執(zhí)行查詢 rs = stmt.executeQuery(sql); //5.判斷 /if(rs.next()){//如果有下一行,則返回true return true; }else{ return false; }*/ return rs.next();//如果有下一行,則返回true } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(rs,stmt,conn); } return false; } }
JDBC控制事務
事務
一個包含多個步驟的業(yè)務操作。如果這個業(yè)務操作被事務管理,則這多個步驟要么同時成功,要么同時失敗。
操作
- 開啟事務
- 提交事務
- 回滾事務
使用Connection對象來管理事務
開啟事務:setAutoCommit(boolean autoCommit) :調(diào)用該方法設置參數(shù)為false,即開啟事務 在執(zhí)行sql之前開啟事務 提交事務:commit() 當所有sql都執(zhí)行完提交事務 回滾事務:rollback() 在catch中回滾事務
代碼
public class JDBCDemo10 { public static void main(String[] args) { Connection conn = null; PreparedStatement pstmt1 = null; PreparedStatement pstmt2 = null; try { //1.獲取連接 conn = JDBCUtils.getConnection(); //開啟事務 conn.setAutoCommit(false); //2.定義sql //2.1 張三 - 500 String sql1 = "update account set balance = balance - ? where id = ?"; //2.2 李四 + 500 String sql2 = "update account set balance = balance + ? where id = ?"; //3.獲取執(zhí)行sql對象 pstmt1 = conn.prepareStatement(sql1); pstmt2 = conn.prepareStatement(sql2); //4. 設置參數(shù) pstmt1.setDouble(1,500); pstmt1.setInt(2,1); pstmt2.setDouble(1,500); pstmt2.setInt(2,2); //5.執(zhí)行sql pstmt1.executeUpdate(); // 手動制造異常 int i = 3/0; pstmt2.executeUpdate(); //提交事務 conn.commit(); } catch (Exception e) { //事務回滾 try { if(conn != null) { conn.rollback(); } } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { JDBCUtils.close(pstmt1,conn); JDBCUtils.close(pstmt2,null); } } }
以上就是Java中JDBC的使用教程詳解的詳細內(nèi)容,更多關于Java JDBC的資料請關注腳本之家其它相關文章!
相關文章
測試springboot項目出現(xiàn)Test Ignored的解決
這篇文章主要介紹了測試springboot項目出現(xiàn)Test Ignored的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11JavaWeb項目打開網(wǎng)頁出現(xiàn)Session Error的異常解決方案
這篇文章主要介紹了JavaWeb項目打開網(wǎng)頁出現(xiàn)Session Error的異常解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-10-10java面試題之try中含return語句時代碼的執(zhí)行順序詳解
這篇文章主要介紹了關于java中的一道面試題,這套題就是在try中含return語句時代碼的執(zhí)行順序,這個問題看似簡單,卻暗藏殺機啊!文中通過一個個例子詳細介紹了其中玄機,需要的朋友可以參考學習,下面來一起看看吧。2017-04-04