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详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个好听的炫舞名字。
- 下一篇: springboot @cacheabl