日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

mysql和jdbc的区别_JDBC详解

發布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql和jdbc的区别_JDBC详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、 JDBC 簡介

1 什么是 JDBC

?JDBC(JavaDataBaseConnectivity)java 數據庫連接 ? 是 JavaEE 平臺下的技術規范 ? 定義了在 Java 語言中連接數據,執行 SQL 語句的標準 ? 可以為多種關系數據庫提供統一訪問

2 什么是數據庫驅動程序

? 數據庫廠商對 JDBC 規范的具體實現 ? 不同數據產品的數據庫驅動名字有差異 ? 在程序中需要依賴數據庫驅動來完成對數據庫的操作

3 程序操作數據庫流程

二、 JDBC3.0 標準中常用接口與類

1 Driver 接口

Driver 接口的作用是來定義數據庫驅動對象應該具備的一些能力。比如與數據庫建立連 接的方法的定義所有支持 java 語言連接的數據庫都實現了該接口,實現該接口的類我們稱 之為數據庫驅動類。在程序中要連接數據庫,必須先通過 JDK 的反射機制加載數據庫驅動 類,將其實例化。不同的數據庫驅動類的類名有區別。 加載 MySql 驅動:Class.forName("com.mysql.jdbc.Driver"); 加載 Oracle 驅動:Class.forName("oracle.jdbc.driver.OracleDriver");

2 DriverManager 類

DriverManager 通過實例化的數據庫驅動對象,能夠建立應用程序與數據庫之間建立連 接。并返回 Connection 接口類型的數據庫連接對象。

2.1常用方法

?getConnection(StringjdbcUrl,Stringuser,Stringpassword) 該方法通過訪問數據庫的 url、用戶以及密碼,返回對應的數據庫的 Connection 對象。

2.2JDBCURL

與數據庫連接時,用來連接到指定數據庫標識符。在 URL 中包括了該數據庫的類型、 地址、端口、庫名稱等信息。不同品牌數據庫的連接 URL 不同。

3 Connection 接口

Connection 與數據庫的連接(會話)對象。我們可以通過該對象執行 sql 語句并返回結

果。

連接 MySql 數據庫: Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password"); 連接 Oracle 數據庫: Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user","password"); 連接 SqlServer 數據庫: Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database","user","password");

3.1常用方法

?createStatement():創建向數據庫發送 sql 的 Statement 接口類型的對象。 ?preparedStatement(sql) :創建向數據庫發送預編譯 sql 的 PrepareSatement 接口類型的

對象。 ?prepareCall(sql):創建執行存儲過程的 CallableStatement 接口類型的對象。 ?setAutoCommit(booleanautoCommit):設置事務是否自動提交。 ?commit() :在鏈接上提交事務。 ?rollback() :在此鏈接上回滾事務。

4 Statement 接口

用于執行靜態 SQL 語句并返回它所生成結果的對象。 由 createStatement 創建,用于發送簡單的 SQL 語句(不支持動態綁定)。

4.1常用方法

?execute(String sql):執行參數中的 SQL,返回是否有結果集。 ?executeQuery(Stringsql):運行 select 語句,返回 ResultSet 結果集。 ?executeUpdate(Stringsql):運行 insert/update/delete 操作,返回更新的行數。 ?addBatch(Stringsql) :把多條 sql 語句放到一個批處理中。 ?executeBatch():向數據庫發送一批 sql 語句執行。

5 PreparedStatement 接口

繼承自 Statement 接口,由 preparedStatement 創建,用于發送含有一個或多個參數的 SQL 語句。PreparedStatement 對象比 Statement 對象的效率更高,并且可以防止 SQL 注入,所以 我們一般都使用 PreparedStatement。

5.1常用方法

?addBatch()把當前 sql 語句加入到一個批處理中。 ?execute() 執行當前 SQL,返回個 boolean 值 ?executeUpdate()運行 insert/update/delete 操作,返回更新的行數。 ?executeQuery() 執行當前的查詢,返回一個結果集對象 ?setDate(intparameterIndex,Date x)向當前SQL語句中的指定位置綁定一個java.sql.Date

值。

? setDouble(int parameterIndex, double x)向當前 SQL 語句中的指定位置綁定一個 double

?setFloat(intparameterIndex,floatx)向當前 SQL 語句中的指定位置綁定一個 float 值 ?setInt(intparameterIndex,intx)向當前 SQL 語句中的指定位置綁定一個 int 值 ?setString(intparameterIndex,Stringx)向當前 SQL 語句中的指定位置綁定一個 String 值

6 ResultSet 接口

ResultSet 提供檢索不同類型字段的方法。

6.1常用方法

?getString(intindex)、getString(StringcolumnName) 獲得在數據庫里是 varchar、char 等類型的數據對象。 ?getFloat(intindex)、getFloat(StringcolumnName) 獲得在數據庫里是 Float 類型的數據對象。 ?getDate(intindex)、getDate(StringcolumnName) 獲得在數據庫里是 Date 類型的數據。 ?getBoolean(intindex)、getBoolean(StringcolumnName) 獲得在數據庫里是 Boolean 類型的數據。 ?getObject(intindex)、getObject(StringcolumnName) 獲取在數據庫里任意類型的數據。

6.2ResultSet 對結果集進行滾動的方法

?next():移動到下一行。 ?Previous():移動到前一行。 ?absolute(introw):移動到指定行。 ?beforeFirst():移動 resultSet 的最前面。 ?afterLast() :移動到 resultSet 的最后面。

7 CallableStatement 接口

繼承自 PreparedStatement 接口,由方法 prepareCall 創建,用于調用數據庫的存儲過程。

三、 JDBC 的使用

加載數據庫驅動程序 → 建立數據庫連接 Connection → 創建執行 SQL 的語句 Statement→ 處理執行結果 ResultSet→ 釋放資源

1 下載數據庫驅動

1.1MySQL 驅動

1.2Oracle 驅動

數據庫安裝目錄\oracle\product\11.2.0\dbhome_1\jdbc\lib

2 創建項目添加驅動

3 通過 Statement 向表中插入數據

3.1注冊驅動

Class.forName("com.mysql.jdbc.Driver");

3.2獲取連接

// 創建連接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/

+ mysql?useSSL=false&useUnicode=true&" +

"characterEncoding=utf-8", "root", "root");

// jdbc:mysql://連接地址:連接端口號/連接那個數據庫?是否驗證&開啟編碼&編碼方式

// root登陸數據庫的賬戶 //root登陸數據庫的密碼

3.3執行 SQL

sta = conn.createStatement();//用于去提交事務的對象

String sql = "insert into usertable values(default,'"+age+"','"+userName+"','"+password+"')";

//所要執行的sql語句

boolean flage = sta.execute(sql);//執行sql語句

3.4釋放資源

finally {

try {

if(sta!=null) { //先關閉Statement

sta.close();

}

if(conn!=null) {//后關閉連接

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

更新表中的數據

public void updateUer(String userName,String passward,int age) {

Connection conn = null;

Statement sta = null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?"

+ "useSSL=false&useUnicode=true&" +

"characterEncoding=utf-8", "root", "root");

sta = conn.createStatement();

String sql = "update usertable set name='"+userName+"',passward="

+ "'"+passward+"',age='"+age+"'";

sta.executeUpdate(sql);

} catch (Exception e) {

e.printStackTrace();

}finally {

try {

if(sta!=null) {

sta.close();

}

if(conn!=null) {

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

4 ResultSet 講解

注意 ResultSet 中封裝的并不是我們查詢到的所有的結果集,而是返回了查詢到的結果 集的數據庫游標。通過 ResultSet 中的 next()方法操作游標的位置獲取結果集。

5 通過 ResultSet 實現邏輯分頁

sta = conn.createStatement();

String sql = "select * from usertable";

res = sta.executeQuery(sql);

int begin = (curretPage - 1) * pageSize + 1;// 指向當前頁的起始數據

int end = curretPage * pageSize; // 指向當前頁的最后一條數據

int currentCount = begin; // 指向當前頁的第幾條數據,最開始是指向第一條的

while (res.next()) {

if (currentCount >= begin && currentCount <= end) {

System.out.println(

res.getInt("id") + "\t" + res.getString("name") + "\t" + res.getString("passward"));

if (currentCount == end) {

break;

}

currentCount++;

}

}

6 SQL 注入問題

6.1什么是 SQL 注入

所謂 SQL 注入,就是通過把含有 SQL 語句片段的參數插入到需要執行的 SQL 語句中, 最終達到欺騙數據庫服務器執行惡意操作的 SQL 命令。

6.2SQL 注入案例

// SQL注入

public void sqlInject(String name) {

Connection conn = null;

Statement sta = null;

ResultSet res = null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?useSSL=false&

+"useUnicode=true&characterEncoding=utf-8", "root", "root");

sta = conn.createStatement();

String sql = "select * from usertable where name='" + name + "'";

res = sta.executeQuery(sql);

while (res.next()) {

System.out.println(res.getString("name") + "\t" + res.getString("id"));

}

} catch (SQLException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

JDBCTest test = new JDBCTest();

test.sqlInject("李四' or 1=1 -- ");// --空格在數據庫中表示注釋,會查出數據庫中的所有數據

}

7. PreparedStatement 對象的使用(重點)

7.1 PreparedStatement 特點:

?PreparedStatement 接口繼承 Statement 接口

?PreparedStatement 效率高于 Statement

?PreparedStatement 支持動態綁定參數

?PreparedStatement 具備 SQL 語句預編譯能力

? 使用 PreparedStatement 可防止出現 SQL 注入問題

7.2通過 PreparedStatement 對象向表中插入數據

代碼

public void insert(int age, String name, String password) {

Connection conn = null;

PreparedStatement ps = null;

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?useSSL=false&

+"useUnicode=true&characterEncoding=utf-8", "root", "root");

String sql = "insert into usertable values(default,?,?,?)";

try {

ps = conn.prepareStatement(sql);

ps.setInt(1, age);//將第一個問號的位置設置值

ps.setString(2, name);//將第二個問號的位置設置值

ps.setString(3, password);//將第三個問號的位置設置值

ps.execute();

} catch (SQLException e) {

e.printStackTrace();

}

}

8 PreparedStatement 的預編譯能力

8.1什么是預編譯

8.1.1 SQL 語句的執行步驟

? 語法和語義解析

? 優化 sql 語句,制定執行計劃

? 執行并返回結果

但是很多情況,我們的一條 sql 語句可能會反復執行,或者每次執行的時候只有個別的 值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。 如果每次都需要經過上面的詞法語義解析、語句優化、制定執行計劃等,則效率就明顯不行 了。 所謂預編譯語句就是將這類語句中的值用占位符替代,可以視為將 sql 語句模板化或者 說參數化 預編譯語句的優勢在于:一次編譯、多次運行,省去了解析優化等過程;此外預編譯語 句能防止 sql 注入

8.1.2 解析過程

8.1.2.1 硬解析 在不開啟緩存執行計劃的情況下,每次 SQL 的處理都要經過:語法和語義的解析,優 化器處理 SQL,生成執行計劃。整個過程我們稱之為硬解析。

8.1.2.2 軟解析 如果開啟了緩存執行計劃,數據庫在處理 sql 時會先查詢緩存中是否含有與當前 SQL 語句相同的執行計劃,如果有則直接執行該計劃。

8.2預編譯方式

開始數據庫的日志 showVARIABLESlike '%general_log%' setGLOBALgeneral_log=on setGLOBALlog_output='table'

8.2.1 依賴數據庫驅動完成預編譯

如果我們沒有開啟數據庫服務端編譯,那么默認的是使用數據庫驅動完成 SQL 的預編 譯處理。

8.2.2 依賴數據庫服務器完成預編譯

我們可以通過修改連接數據庫的 URL 信息,添加 useServerPrepStmts=true 信息開啟服 務端預編譯。

9 PreparedStatement 批處理操作

代碼

String sql = "insert into usertable values(default,?,?,?)";

ps = conn.prepareStatement(sql);

for (User user : list) {

ps.setInt(1, user.getAge());

ps.setString(2, user.getName());

ps.setString(3, user.getPassword());

ps.addBatch();

}

ps.executeBatch();//提交

10 JDBC 中的事務處理

在 JDBC 操作中數據庫事務默認為自動提交。如果事務需要修改為手動提交,那么我們 需要使用 Connection 對象中的 setAutoCommit 方法來關閉事務自動提交。然后通過 Connection 對象中的 commit 方法與 rollback 方法進行事務的提交與回滾。

代碼

String sql = "delete from usertable where name like ?";

conn.setAutoCommit(false);//將事務設置為手動提交,默認是自動提交

ps = conn.prepareStatement(sql);

ps.setString(1,"%"+name+"%");

ps.execute();

conn.commit();//提交事務

四、 JDBC 進階

1 動態查詢

動態刪除:根據用戶給定的條件來決定執行什么樣的查詢。

//動態刪除public void dynamicDelete(User user) {

Connection conn = null;

PreparedStatement ps = null;

conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?useSSL=false&+"useUnicode=true&characterEncoding=utf-8", "root", "root");String sql = connectSQL(user);try {conn.prepareStatement(sql);} catch (SQLException e) {e.printStackTrace();}}public String connectSQL(User user) {StringBuilder sb = new StringBuilder("delete from usertable where 1=1 ");if(user.getAge()>0) {sb.append(" and age = ").append(user.getAge());}if (user.getName()!=null) {sb.append(" add name = '").append(user.getName()).append("'");}if (user.getPassword()!=null) {sb.append(" and password = '").append(user.getPassword()).append("'");

}

return sb.toString();

}

總結

以上是生活随笔為你收集整理的mysql和jdbc的区别_JDBC详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。