JDBC技术详解
文章目錄
- 1 綜述
- 2 JDBC相關概念
- 2.1 什么是JDBC
- 2.2 JDBC有什么用
- 2.3 數據庫驅動
- 2.4 JDBC架構
- 2.4.1 雙層結構
- 2.4.2 三層架構
- 3 JDBC常用接口
- 3.1 Driver接口
- 3.2 Connection接口
- 3.3 Statement接口
- 3.4 ResultSet接口
- 4 JDBC使用方法
- 4.1 下載jar包
- 4.2 導入jar包
- 4.3 JDBC使用步驟
- 4.4 使用代碼示例
- 4.4.1 插入更新操作
- 5 封裝提取工具類
- 6 SQL注入
- 6.1 sql注入演示
- 6.2 PreparedStatement使用示例
- 7 JDBC操縱事務
- 8 批處理
1 綜述
本文檔主要對JDBC進行詳細說明,包括JDBC的相關概念、架構說明、工作原理、常用接口以及具體的使用方法等。
2 JDBC相關概念
2.1 什么是JDBC
JDBC英文名為:Java Data Base Connectivity(Java數據庫連接)
官方解釋它是Java編程語言和廣泛的數據庫之間獨立于數據庫的連接標準的Java API,根本上說JDBC是一種規范,它提供的接口,一套完整的,允許便捷式訪問底層數據庫。可以用JAVA來寫不同類型的可執行文件:JAVA應用程序、JAVA Applets、Java Servlet、JSP等,不同的可執行文件都能通過JDBC訪問數據庫,又兼備存儲的優勢。簡單說它就是JAVA與數據庫的連接的橋梁或者插件,用JAVA代碼就能操作數據庫的增刪改查、存儲過程、事務等。
2.2 JDBC有什么用
我們用JAVA就能連接到數據庫;創建SQL或者MYSQL語句;執行SQL或MYSQL的查詢數據庫;查看和修改結果記錄。
2.3 數據庫驅動
我們安裝好數據庫之后,我們的應用程序也是不能直接使用數據庫的,必須要通過相應的數據庫驅動程序,通過驅動程序去和數據庫打交道。其實也就是數據庫廠商的JDBC接口實現,即對Connection等接口的實現類的jar文件。
下載地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java
2.4 JDBC架構
分為雙層架構和三層架構。
2.4.1 雙層結構
- 作用:此架構中,Java Applet 或應用直接訪問數據源。
- 條件:要求 Driver 能與訪問的數據庫交互。
- 機制:用戶命令傳給數據庫或其他數據源,隨之結果被返回。
- 部署:數據源可以在另一臺機器上,用戶通過網絡連接,稱為 C/S配置(可以是內聯網或互聯網)。
2.4.2 三層架構
3 JDBC常用接口
3.1 Driver接口
Driver接口由數據庫廠家提供,作為java開發人員,只需要使用Driver接口就可以了。在編程中要連接數據庫,必須先裝載特定廠商的數據庫驅動程序,不同的數據庫有不同的裝載方法。如:
- 裝載MySql驅動:
- 裝載Oracle驅動:
3.2 Connection接口
Connection與特定數據庫的連接,在連接上下文中執行sql語句并返回結果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定義的數據庫Connection連接上。
- 連接MySql數據庫:
- 連接Oracle數據庫:
- 連接SqlServer數據庫:
常用方法:
- createStatement():創建向數據庫發送sql的statement對象。
- prepareStatement(sql) :創建向數據庫發送預編譯sql的PrepareSatement對象。
- prepareCall(sql):創建執行存儲過程的callableStatement對象。
- setAutoCommit(boolean autoCommit):設置事務是否自動提交。
- commit() :在鏈接上提交事務。
- rollback() :在此鏈接上回滾事務。
3.3 Statement接口
用于執行靜態SQL語句并返回它所生成結果的對象。
三種Statement類:
常用Statement方法:
- execute(String sql):運行語句,返回是否有結果集
- executeQuery(String sql):運行select語句,返回ResultSet結果集。
- executeUpdate(String sql):運行insert/update/delete操作,返回更新的行數。
- addBatch(String sql) :把多條sql語句放到一個批處理中。
- executeBatch():向數據庫發送一批sql語句執行。
3.4 ResultSet接口
ResultSet提供檢索不同類型字段的方法,常用的有:
- getString(int index)、getString(String columnName):獲得在數據庫里是varchar、char等類型的數據對象。
- getFloat(int index)、getFloat(String columnName):獲得在數據庫里是Float類型的數據對象。
- getDate(int index)、getDate(String columnName):獲得在數據庫里是Date類型的數據。
- getBoolean(int index)、getBoolean(String columnName):獲得在數據庫里是Boolean類型的數據。
- getObject(int index)、getObject(String columnName):獲取在數據庫里任意類型的數據。
- 等還有其他的獲取類型方法。
ResultSet還提供了對結果集進行滾動的方法:
- next():移動到下一行
- Previous():移動到前一行
- absolute(int row):移動到指定行
- beforeFirst():移動resultSet的最前面。
- afterLast():移動到resultSet的最后面。
注意:使用后依次關閉對象及連接:ResultSet → Statement → Connection。
4 JDBC使用方法
4.1 下載jar包
上面以及展示下載地址,下載合適的版本即可。
4.2 導入jar包
4.3 JDBC使用步驟
使用JDBC的步驟:
4.4 使用代碼示例
package com.wzh.demo01;import java.sql.*;public class JdbcDemo01 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1 加載JDBC驅動程序Class.forName("com.mysql.jdbc.Driver");// 2 構造數據庫鏈接信息(以MySql為例)String url = "jdbc:mysql://localhost:3306/test_go?useUnicode=true&characterEncoding=utf8&useSSL=true";String username = "root";String pwd = "root";// 3 建立數據庫連接ConnectionConnection connection = DriverManager.getConnection(url, username, pwd);// 4 創建執行SQL的語句Statement對象Statement statement = connection.createStatement();// 5 使用Statement對象執行SQLString sql = "select * from user";ResultSet resultSet = statement.executeQuery(sql);// 6 處理執行結果ResultSetwhile (resultSet.next()) {System.out.println("id=" + resultSet.getObject("id"));System.out.println("name=" + resultSet.getObject("name"));System.out.println("birthday=" + resultSet.getObject("birthday"));}// 7 釋放資源 (注意關閉順序)resultSet.close();statement.close();connection.close();} }4.4.1 插入更新操作
String sql = "insert into user(name,birthday) value ('hao','2021-06-28')"; int i = statement.executeUpdate(sql); if(i>0){System.out.println("插入數據成功"); }String sql1 = "update user set name='nn' where id = 2"; int i1 = statement.executeUpdate(sql1); if(i1 > 0){System.out.println("更新數據成功"); }5 封裝提取工具類
6 SQL注入
詳細可觀看此篇博文:https://www.cnblogs.com/myseries/p/10821372.html
6.1 sql注入演示
package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class Sql注入 {public static void main(String[] args) {//正常使用//login("hao", "123456");// 此時為sql注入login(" 'or '1=1","123456");}public static void login(String username, String password) {Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();st = conn.createStatement();String sql_login = "select * from user where name='" + username + "' and password='" + password + "'";rs = st.executeQuery(sql_login);if (rs.next()) {System.out.println("登錄成功");}else{System.out.println("登錄失敗");}} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}}}由上可知Statement是不安全的,PreparedStatement可以防止SQL注入。效率更高。
6.2 PreparedStatement使用示例
package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.*;public class JdbcDemo03 {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();// 區別:先寫sql// 使用 ? 占位符代替參數String sql_i = "insert into user(name,birthday) value (?,?)";st = conn.prepareStatement(sql_i); // 預編譯sql,// 手動給參數賦值st.setString(1, "lisi");st.setDate(2, new java.sql.Date(new java.util.Date().getTime()));int i = st.executeUpdate();if (i > 0) {System.out.println("插入成功");}} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}} }此種方式可以避免sql注入。
7 JDBC操縱事務
事務的四大特性:
- 原子性(Atomictiy):不可再分割
- 一致性(Consistency):數據前后一致,總量保持不變
- 隔離性(Isolation):多個事務互不干擾
- 持久性(Durability):一旦提交不可逆,持久化到數據庫
事務的隔離級別:
隔離性問題:
- 臟讀:一個事務讀取了另一個沒有提交的事務數據
- 不可重復讀:在同一個事務內,相同的語句讀取出來的數據不一致
- 幻讀:在一個事務內,讀取到別的數據插入的數據,導致前后讀出來的數據結果條數不一致。
修改事務隔離級別
conn = JdbcUtils.getConnection(); conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);//避免臟讀 conn.setAutoCommit(false);8 批處理
package com.wzh.demo02;import com.wzh.demo02.utils.JdbcUtils;import java.sql.*;public class JdbcDemo04 {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();conn.setAutoCommit(false); //設為手動提交long start = System.currentTimeMillis();st = conn.createStatement();for (int i = 0; i < 100; i++) {st.addBatch("insert into user (name,birthday) values ('hao'" + i + ",'2021-06-28')");}st.executeBatch();conn.commit(); //提交事務long end = System.currentTimeMillis();System.out.println("插入100條數據,耗時(ms):" + (end - start));} catch (Exception e) {e.printStackTrace();} finally {try {JdbcUtils.release(conn, st, rs);} catch (SQLException e) {e.printStackTrace();}}} }以上基本就是jdbc基本的使用方式,后續會再專門寫一篇關于數據庫連接池技術c3p0,dbcp與druid的使用。
總結
- 上一篇: robotframework 常用关键字
- 下一篇: web 三联发票针式打印_打印机共享操作