原生JDBC

来源:http://www.cnblogs.com/caigq/archive/2017/07/02/7049215.html
-Advertisement-
Play Games

JDBCJava DataBase Connectivity,java資料庫連接,是一種用於執行SQL語句的Java API。JDBC是Java訪問資料庫的標準規範,可以為不同的關係型資料庫提供統一訪問,它由一組用Java語言編寫的介面和類組成。 驅動JDBC需要連接驅動,驅動是兩個設備要進行通信, ...


JDBC
Java DataBase Connectivity,java資料庫連接,是一種用於執行SQL語句的Java API。
JDBC是Java訪問資料庫的標準規範,可以為不同的關係型資料庫提供統一訪問,它由一組用Java語言編寫的介面和類組成。

驅動
JDBC需要連接驅動,驅動是兩個設備要進行通信,滿足一定通信數據格式,數據格式由設備提供商規定,設備提供商為設備提供驅動軟體,通過軟體可以與該設備進行通信。

JDBC規範(掌握四個核心對象
DriverManager:用於註冊驅動
Connection: 表示與資料庫創建的連接
Statement: 操作資料庫sql語句的對象
ResultSet: 結果集或一張虛擬表

使用JDBC技術,通過mysql提供的驅動程式,操作資料庫實現步驟:
1.註冊驅動
告知JVM我們使用的是什麼驅動程式(mysql,oracle....)
DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建議使用
原因有2個:
>導致驅動被註冊2次。
>強烈依賴資料庫的驅動jar
解決辦法:
Class.forName("com.mysql.jdbc.Driver");
2.獲取資料庫的連接
資料庫是TCP程式伺服器,連接伺服器(通過3次握手)
就相當於建立了一條java程式通往資料庫伺服器的連接通路
static Connection getConnection(String url, String user, String password)
試圖建立到給定資料庫 URL 的連接。
參數說明:url 需要連接資料庫的位置(網址) user用戶名 password 密碼
例如:getConnection("jdbc:mysql://localhost:3306/day06", "root", "root");
URL:SUN公司與資料庫廠商之間的一種協議。
jdbc:mysql://localhost:3306/day06
協議子協議 IP :埠號資料庫
mysql: jdbc:mysql://localhost:3306/day04或者jdbc:mysql:///day14(預設本機連接)
oracle資料庫: jdbc:oracle:thin:@localhost:1521:sid
3.獲取執行者對象
執行SQL語句的對象,作用就是執行SQL
介面的實現在資料庫驅動中。所有與資料庫交互都是基於連接對象的。
Statement createStatement(); //創建操作sql語句的對象
4.執行SQL語句,獲取結果集
使用執行者對象執行SQL語句
獲取SQL語句的結果集(增刪改:整數,執行有效行數 查詢:返回的就是一個結果集)
常用方法:
? int executeUpdate(String sql); --執行insert update delete語句.
? ResultSet executeQuery(String sql); --執行select語句.
? boolean execute(String sql); --僅當執行select並且有結果時才返回true,執行其他的語句返回false.
5.處理結果集
ResultSet實際上就是一張二維的表格,我們可以調用其boolean next()方法指向某行記錄,當第一次調用next()方法時,便指向第一行記錄的位置,這時就可以使用ResultSet提供的getXXX(int col)方法(與索引從0開始不同個,列從1開始)來獲取指定列的數據:
rs.next();//指向第一行
rs.getInt(1);//獲取第一行第一列的數據
常用方法:
? Object getObject(int index) / Object getObject(String name) 獲得任意對象
? String getString(int index)/ String getString(String name) 獲得字元串
? int getInt(int index)/int getInt(String name) 獲得整形
? double getDouble(int index)/ double getDouble(String name) 獲得雙精度浮點型
6.釋放資源
與IO流一樣,使用後的東西都需要關閉!關閉的順序是先得到的後關閉,後得到的先關閉。
使用JDBC對資料庫進行增刪改查代碼演示:

  1 public static void main(String[] args) throws Exception {
  2         //1.註冊驅動
  3         Class.forName("com.mysql.jdbc.Driver");
  4         //2.獲取資料庫連接
  5         String url = "jdbc:mysql://localhost:3306/mybase4";
  6         String user = "root";
  7         String password = "root"; 
  8         Connection conn = DriverManager.getConnection(url, user, password);
  9         //3.獲取執行者對象
 10         Statement stat = conn.createStatement();
 11         //調用更新數據的方法
 12         //update(stat);
 13         //調用刪除數據的方法
 14         //delete(stat);
 15         //調用增加數據的方法
 16         //insert(stat);
 17         //調用查詢數據的方法
 18         select(stat);
 19         //6.釋放資源
 20         stat.close();
 21         conn.close();
 22     }
 23 
 24     /*
 25      * 使用JDBC技術,查詢資料庫中表的數據
 26      */
 27     private static void select(Statement stat) throws Exception {
 28         //拼接sql語句
 29         String sql = "SELECT * FROM category";
 30         /*
 31          * 4.執行sql語句
 32          * 使用Statement中的方法
 33          * ResultSet executeQuery(String sql) 執行給定的 SQL 語句,該語句返回單個 ResultSet 對象。 
 34          * 返回值ResultSet標準介面的實現類對象,實現類對象由mysql驅動提供,可以使用ResultSet介面接收
 35          */
 36         ResultSet rs = stat.executeQuery(sql);
 37         System.out.println(rs);//com.mysql.jdbc.JDBC4ResultSet@1acb189
 38         /*
 39          * 5.處理結果
 40          * ResultSet中有一個方法
 41          * boolean next() 將游標從當前位置向前移一行。
 42          * 如果新的當前行有效,則返回 true;如果不存在下一行,則返回 false 
 43          * 如果有結果集返回true,若果沒有結果集返回false
 44          * 相當於迭代器中的hasNext方法
 45          */
 46         while(rs.next()){
 47             /*
 48              * next返回true,有結果集
 49              * 取出結果集
 50              * 使用ResultSet中的方法getXXX(參數);
 51              * 參數:
 52              *     int columnIndex:列所在的索引,從1開始
 53              *     String columnLabel:列名
 54              * 註意:
 55              *     如果使用getInt,getDouble指定數據類型的方法,返回值就是對應的數據類型
 56              *     如果使用getObject方法返回值是object類型(只是列印可用)
 57              * 如果使用getString方法返回值是String類型
 58              */
 59             /*int i1 = rs.getInt(1);
 60             String s2 = rs.getString(2);
 61             System.out.println(i1+"\t"+s2);*/
 62             
 63             //System.out.println(rs.getObject(1)+"\t"+rs.getObject(2));
 64             System.out.println(rs.getObject("cid")+"\t"+rs.getObject("cname"));
 65             //5.釋放資源
 66             rs.close();
 67         }
 68     }
 69 
 70     /*
 71      * 使用JDBC技術,對資料庫中的表數據進行增加
 72      */
 73     private static void insert(Statement stat) throws SQLException {
 74         //拼接sql語句
 75         String sql = "INSERT INTO category(cname) VALUES('玩具')";
 76         //4.執行sql語句
 77         int row = stat.executeUpdate(sql);
 78         //5.處理結果
 79         if(row>0){
 80             System.out.println("增加數據成功!");
 81         }else{
 82             System.out.println("增加數據失敗!");
 83         }
 84         
 85     }
 86 
 87     /*
 88      * 使用JDBC技術,對資料庫中的表數據進行刪除
 89      */
 90     private static void delete(Statement stat) throws Exception {
 91         //拼接sql語句
 92         String sql = "DELETE FROM category WHERE cid=5";
 93         //4.執行sql語句
 94         int row = stat.executeUpdate(sql);
 95         //5.處理結果
 96         if(row>0){
 97             System.out.println("刪除數據成功!");
 98         }else{
 99             System.out.println("刪除數據失敗!");
100         }
101     }
102 
103     /*
104      * 使用JDBC技術,對資料庫中的表數據進行更新
105      */
106     private static void update(Statement stat) throws Exception {
107         //拼接sql語句
108         String sql = "UPDATE category SET cname='鞋帽' WHERE cid=6";
109         //4.執行sql語句
110         int row = stat.executeUpdate(sql);
111         //5.處理結果
112         if(row>0){
113             System.out.println("更新數據成功!");
114         }else{
115             System.out.println("更新數據失敗!");
116         }
117     }
 1 JDBC工具類
 2 “獲得資料庫連接”操作,將在以後的增刪改查所有功能中都存在,可以封裝工具類JDBCUtils。提供獲取連接對象的方法,從而達到代碼的重覆利用。
 3 代碼演示:
 4 public class JDBCUtils {
 5     
 6     //私有構造方法,防止外界創建對象調用方法
 7     private JDBCUtils() {
 8     }
 9     
10     //定義Connectionn變數
11     private static Connection conn;
12     
13     //保證代碼只執行一次,可以放入靜態代碼塊中
14     static{
15         try {
16             //註冊驅動
17             Class.forName("com.mysql.jdbc.Driver");
18             //獲取連接
19             String url="jdbc:mysql://127.0.0.1:3306/mybase4";
20             String user="root";
21             String password = "root";
22             conn = DriverManager.getConnection(url, user, password);
23         } catch (Exception e) {
24             //註意,如果連接資料庫失敗,停止程式
25             throw new RuntimeException(e+"連接資料庫失敗");
26         }
27     }
28     
29     //創建一個靜態方法,獲取資料庫連接對象,並返回
30     public static Connection getConnection(){
31         return conn;
32     }
33     
34     /*
35      * 創建一個靜態方法,對資源進行釋放
36      * ResultSet rs
37      * Statement stat
38      * Connection conn
39      */
40     public static void close(ResultSet rs,Statement stat,Connection conn){
41         try {
42             if(rs!=null){
43                 rs.close();
44             }
45         } catch (SQLException e) {
46             e.printStackTrace();
47         }
48         try {
49             if(stat!=null){
50                 stat.close();
51             }
52         } catch (SQLException e) {
53             e.printStackTrace();
54         }
55         try {
56             if(conn!=null){
57                 conn.close();
58             }
59         } catch (SQLException e) {
60             e.printStackTrace();
61         }
62     }
63 }

sql註入問題
SQL註入:用戶輸入的內容作為了SQL語句語法的一部分,改變了原有SQL真正的意義。
假設有登錄案例SQL語句如下:
SELECT * FROM 用戶表 WHERE NAME = 用戶輸入的用戶名 AND PASSWORD = 用戶輸的密碼;
此時,當用戶輸入正確的賬號與密碼後,查詢到了信息則讓用戶登錄。但是當用戶輸入的賬號為XXX 密碼為:XXX’ OR ‘a’=’a時,則真正執行的代碼變為:
SELECT * FROM 用戶表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’a’=’a’;
此時,上述查詢語句時永遠可以查詢出結果的。那麼用戶就直接登錄成功了,顯然我們不希望看到這樣的結果,這便是SQL註入問題。
為此,我們使用PreparedStatement來解決對應的問題。

preparedStatement:預編譯對象,是Statement對象的子類。
特點:
性能高
會把sql語句先編譯
能過濾掉用戶輸入的關鍵字。

PreparedStatement預處理對象,處理的每條sql語句中所有的實際參數,都必須使用占位符?替換。
String sql = "select * from user where username = ? and password = ?";
PreparedStatement使用,需要通過以下3步驟完成:
1.PreparedStatement預處理對象代碼:
獲得預處理對象,需要提供已經使用占位符處理後的SQL語句
PreparedStatement psmt = conn.prepareStatement(sql)
2.設置實際參數
void setXxx(int index, Xxx xx) 將指定參數設置指定類型的值
參數1:index 實際參數序列號,從1開始。
參數2:xxx 實際參數值,xxx表示具體的類型。
例如:
setString(2, "1234") 把SQL語句中第2個位置的占位符?替換成實際參數 "1234"
3.執行SQL語句:
int executeUpdate(); --執行insert update delete語句.
ResultSet executeQuery(); --執行select語句.
boolean execute(); --執行select返回true 執行其他的語句返回false.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 需求:最近公司需要做一個樓宇對講的功能:門口機(連接WIFI)撥號對室內機(對應的WIFI)的設備進行呼叫,室內機收到呼叫之後將對收到的數據進行UDP廣播的轉發,手機(連接對應的WIFI)收到視頻流之後,實時的展示視頻數據(手機可以接聽,掛斷,手機接聽之後,室內機不展示視頻,只是進行轉發。) 簡單點 ...
  • 原作者,介紹Kotlin中密封類。這些新概念讓您更接近函數式編程成為可能。 ...
  • 把我認為最好的知識,拿來與他人分享,是這一生快事之一! React Native 項目常用第三方組件彙總: react-native-animatable 動畫 react-native-carousel 輪播 react-native-countdown 倒計時 react-native-devi ...
  • 一、GCD基本概念 GCD 全稱Grand Central Dispatch(大中樞隊列調度),是一套低層API,提供了⼀種新的方法來進⾏併發程式編寫。從基本功能上講,GCD有點像NSOperationQueue,他們都允許程式將任務切分為多個單一任務,然後提交⾄⼯作隊列來併發的或者串⾏的執行。GC ...
  • RocksDB作為一個開源的存儲引擎支持事務的ACID特性,而要支持ACID中的I(Isolation),併發控制這塊是少不了的,本文主要討論RocksDB的鎖機制實現,細節會涉及到源碼分析,希望通過本文讀者可以深入瞭解RocksDB併發控制原理。文章主要從以下4方面展開,首先會介紹RocksDB鎖 ...
  • 準備工作 繼續連接到mongo 查看資料庫和集合 創建簡單索引 數據準備,在CMD命令視窗中輸入如下初始化腳本: 1、先檢查一下查詢性能 執行如下腳本:var start=new Date()db.books.find({number:20540})var end=new Date()end - s ...
  • 背景 最近我們遷移了一批伺服器,因我們在azure portal 上新開的VM暫時預設只有英文系統,所以我們在開設好的資料庫伺服器的時候,都會重置資料庫字元排序成中文,避免出現中文亂碼問題,重置參考路徑。但最近有個項目反饋,遷移後出現轉換datatime類型時報錯。 系統環境 Microsoft S ...
  • 本文出處:http://www.cnblogs.com/wy123/p/7106861.html (保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他) 最近在SQL Server中多次遇到開發人員提交過來的有性能問題的SQL, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...