1. 程式人生 > >14.JDBC原理介紹及增刪改查示範

14.JDBC原理介紹及增刪改查示範

本文為《Spark大型電商專案實戰》 系列文章之一,主要介紹JDBC的原理以及對MySQL資料庫增刪改查的具體實現過程。

JDBC原理介紹

JDBC代表了JDK提供的一套面向資料庫的一套開發介面,大部分僅僅是介面而已,Java應用程式光有JDBC是操作不了資料庫的,更不用談增刪改查等功能。JDBC真正的意義在於通過介面統一了java程式對各種資料庫的訪問規範。

資料庫廠商會提供JDBC驅動:JDBC Driver,在這套實現類中,不同的資料廠商就實現了針對自己資料庫的一套連線、執行SQL語句等等實際的功能。

本次實驗專案主要使用的是MySQL資料庫,以下例子是針對MySQL資料庫開發。

實現增刪改查功能

在包com.erik.sparkproject.test中建立類JdbcCRUD.java,實現對MySQL資料庫的增刪改查功能,程式碼如下:

package com.erik.sparkproject.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * JDBC增刪改查
 * @author
Erik * */
public class JdbcCRUD { public static void main(String[] args) { // TODO Auto-generated method stub //insert(); //update(); //delete(); //select(); preparedStatement(); } /** * 測試插入資料 */ private static void insert() { //引用JDBC相關的所有介面或者是抽象類的時候,必須是引用java.sql包下的
//java.sql包下的,才代表了java提供的JDBC介面,只是一套規範 Connection conn = null; //定義SQL語句執行控制代碼:Statement物件 //Statement物件其實就是底層基於Connection資料庫連線 Statement stmt = null; try { //第一步,載入資料庫驅動 //使用Class.forName()方式載入資料庫的驅動類 //Class.forName()是Java提供的一種基於反射的方式,直接根據類的全限定名(包+類) //從類所在的磁碟檔案(.class檔案)中載入類對應的內容,並建立對應的class物件 Class.forName("com.mysql.jdbc.Driver"); //獲取資料庫的連線 //使用DriverManager.getConnection()方法獲取針對資料庫的連線 //需要給方法傳入三個引數,包括url、user、password //其中url就是有特定格式的資料庫連線串,包括“主協議:子協議“//主機名:埠號//資料庫” conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sparkproject", "root", "****");//這裡根據實際情況填寫本地MySQL資料庫root密碼 //基於資料庫連線的Connection物件,建立SQL語句執行控制代碼,Statement物件 //Statement物件 ,就是用於基於底層的Connection代表的資料庫連線 //允許我們通過Java程式,通過Statement物件,向MySQL資料庫傳送SQL語句 //從而實現通過傳送的SQL語句來執行增刪改查等邏輯 stmt = conn.createStatement(); //基於Statement物件,來執行insert SQL語句插入一條資料 //Statement.executeUpdate()方法可以用來執行insert、update、delete語句 //返回型別是int值,也就是SQL語句影響的行數 //String sql = "insert into test_user(name,age) values('張三',25)"; String sql = "insert into test_user(name,age) values('李四',26)"; int rtn = stmt.executeUpdate(sql); System.out.println("SQL語句影響了【"+rtn+"】行。"); }catch (Exception e){ e.printStackTrace(); } finally { //最後一定要記得在finally程式碼塊中,儘快在執行完SQL語句之後,就釋放資料庫連線 try { if(stmt != null){ stmt.close(); } if(conn != null){ conn.close(); } } catch (Exception e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } } /** * 測試更新資料 */ private static void update() { Connection conn =null; Statement stmt = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sparkproject", "root", "erik"); stmt = conn.createStatement(); String sql = "update test_user set age=27 where name='李四'"; int rtn = stmt.executeUpdate(sql); System.out.println("SQL語句影響了【"+rtn+"】行。"); }catch (Exception e) { e.printStackTrace(); } finally { try { if (stmt != null) { stmt.close(); } if(conn != null) conn.close(); } catch (Exception e2) { e2.printStackTrace(); } } } /** * 測試刪除資料 */ private static void delete() { Connection conn =null; Statement stmt = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sparkproject", "root", "erik"); stmt = conn.createStatement(); String sql = "delete from test_user where name='李四'"; int rtn = stmt.executeUpdate(sql); System.out.println("SQL語句影響了【"+rtn+"】行。"); }catch (Exception e) { e.printStackTrace(); } finally { try { if (stmt != null) { stmt.close(); } if(conn != null) conn.close(); } catch (Exception e2) { e2.printStackTrace(); } } } /** * 測試查詢資料 */ private static void select() { Connection conn = null; Statement stmt = null; //對於select查詢語句,需要定義ResultSet //ResultSet代表了select語句查詢出來的資料 //需要通過ResutSet物件,來遍歷查詢出來的每一條資料,然後對資料進行儲存或者處理 ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sparkproject", "root", "erik"); stmt = conn.createStatement(); String sql = "select * from test_user"; rs = stmt.executeQuery(sql); //獲取到ResultSet以後,就要對其進行遍歷,然後獲取查詢出來的每一條資料 while(rs.next()) { int id = rs.getInt(1); String name = rs.getString(2); int age = rs.getInt(3); System.out.println("id="+id+",name="+name+",age="+age); } }catch (Exception e) { e.printStackTrace(); } finally { try { if (stmt != null){ stmt.close(); } if (conn != null) { conn.close(); } } catch (Exception e) { e.printStackTrace(); } } } /** * 使用Statement時,必須在SQL語句中,實際地區嵌入值,容易發生SQL注入 * 而且效能低下 * * 使用PreparedStatement,就可以解決上述的兩個問題 * 1.SQL主任,使用PreparedStatement時,是可以在SQL語句中,對值所在的位置使用?這種佔位符, * 實際的值是放在陣列中的引數,PreparedStatement會對數值做特殊處理,往往處理後會使惡意注入的SQL程式碼失效。 * 2.提升效能,使用P熱怕熱的Statement後,結構類似的SQL語句會變成一樣的,因為值的地方會變成?, * 一條SQL語句,在MySQL中只會編譯一次,後面的SQL語句過來,就直接拿編譯後的執行計劃加上不同的引數直接執行, * 可以大大提升效能 */ private static void preparedStatement() { Connection conn = null; PreparedStatement pstmt = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/sparkproject?characterEncoding=utf8", "root", "erik"); //第一個,SQL語句中,值所在的地方,都用問號代表 String sql = "insert into test_user(name,age) values(?,?)"; pstmt = conn.prepareStatement(sql); //第二個,必須呼叫PreparedStatement的setX()系列方法,對指定的佔位符賦值 pstmt.setString(1, "李四"); pstmt.setInt(2, 26); //第三個,執行SQL語句時,直接使用executeUpdate()即可 int rtn = pstmt.executeUpdate(); System.out.println("SQL語句影響了【"+rtn+"】行。"); }catch (Exception e){ e.printStackTrace(); } finally { try { if(pstmt != null){ pstmt.close(); } if(conn != null){ conn.close(); } } catch (Exception e2) { e2.printStackTrace(); } } } }

使用以上程式碼可以對本地MySQL資料庫實現增刪改查等功能。

總結

JDBC最基本的使用過程:
1. 載入驅動類:Class.forName()
2. 獲取資料庫連線:DriverManager.getConnection()
3. 建立SQL語句執行控制代碼:Connection.createStatement()
4. 執行SQL語句:Statement.executeUpdate()
5. 釋放資料庫連線資源:finally,Connection.close()