Mysql(五) JDBC
一、JDBC
? ? JDBC(Java DataBase Connectivity) 是Java 數據庫連接API。
? ? JDBC完成三件事:?與一個數據庫連接 ? ? ? ? ?向數據庫發送SQL語句 ? ? ? ? ? ? ? ?處理數據庫返回的結果?
? ??Java.sql包提供了JDBC API,聲明了訪問數據庫的接口和類,?可以通過它編寫訪問數據庫的程序。?
? ??JDBC API只是定義了相關的規范(提供相應的接口),并不?能直接訪問數據庫,它依賴于數據庫廠商提供具體的實現。?
? ?
? ? ?1、相關實現
? ? ? ??
? ? 2、Java.sql包中的接口和類 :
? ? ? ?Driver接口和DriverManager類
? ? ? ?Connection接口
? ? ? ?Statement接口
? ? ? ?PreparedStatement接口
? ? ? ?ResultSet接口
? ? ? ?(1)Driver接口和DriverManager類
所有JDBC驅動程序都必須實現Driver接口, JDBC驅動程序由?數據庫廠商提供。
DriverManager用來建立和數據庫的連接已經管理JDBC驅動?程序。
getConnection(String url,String user,String pwd):建立和?數據庫的連接,返回Connection對象?
? ? ?(2)Connection接口
Connection接口代表Java程序和數據庫的連接, Connection接口常用方法:
? createStatement():創建并返回Statement對象
? prepareStatement(String sql):創建并返回?PreparedStatement對象?
? ? (3)Statement接口
Statement用來執行SQL語句。?
? 對于insert、 update和delete語句,可以調用?executeUpdate(String sql)方法,該方法返回一個int型數據,?表示受影響的記錄數。
? 對于select語句,可以調用executeQuery(String sql)方法,?該方法返回一個ResultSet對象(查詢結果集)?
? ? (4)PreparedStatement接口
PreparedStatement也用來執行SQL語句,不同的是,其可以使?用動態的參數(?)。
在訪問數據庫時,如果某條SQL語句被多次執行,但每次都參?數不同,在這種情況下,使用PreparedStatement比Statement?更方便,?PreparedStatement允許sql語句中包含參數。
? ? (5)ResultSet接口
ResultSet接口表示select語句查詢得到的記錄結果集合,ResultSet接口的記錄行號從1開始,一個Statement對象在同?一時刻只能打開一個ResultSet對象。
? 調用ResultSet的next()方法,可以進行順序查詢,可以使游?標定位到下一條記錄,該方法返回一個boolean型數據,當?游標移動到最后一行之后返回false。
? 調用ResultSet的getXXX()方法,可以獲取某個字段的值。?XXX為字段的類型。?
? ? 3、JDBC程序訪問數據庫的步驟
? ? 4、驅動類名
驅動類的名稱由數據庫廠商提供,不同的數據庫廠商類名也不?相同。?
MySQL驅動類: com.mysql.jdbc.Driver。
Oracle驅動類: oracle.jdbc.driver.OracleDriver
SqlServer驅動類: com.microsoft.sqlserver.jdbc.SQLServerDriver
? ?5、建立與數據庫的連接
Connection con =?DriverManager.getConnection(url,user,password);
url表示連接數據庫的地址,不同的數據庫, url也不相同。
user和password分別表示連接數據庫的用戶名和密碼。
url的一般形式為:
jdbc:drivertype:driversubtype://parameters
drivertype表示驅動程序的類型, driversubtype是子類型,?parameter通常用來設定數據庫服務器的IP地址、端口號和數據?庫的名稱
?
? 6、事務處理
在數據庫操作中,一項事務是指由一條或多條對數據庫更新?的SQL語句所組成的不可分割的工作單元。?
只有當事務中的所有操作都正常完成,整個事務才能被提交?到數據庫。如果有一項操作沒有完成,則必須撤銷整個事務。?
事務的原則:要么全部完成,要么什么都不做。
在Connection類中提供了3個控制事務的方法:
setAutoCommit(boolean autoCommit):設置是否自動提交事?務
commit():提交事務
rollback():撤銷事務
默認情況下,事務為自動提交。即每一條數據庫更新的SQL?語句代表一項事務,操作成功后,系統將自動調用commit()?來提交,否則將調用rollback()來撤銷事務。?
可以通過調用setAutoCommit(false)來禁止自動提交事務。?可以把多條更新數據庫的SQL語句作為一個事務,在所有操?作完成后,調用commit()來進行整體提交。若其中一項SQL操作失敗,就不會執行commit(),而是產生相應的SQLException,此時就可以在捕獲異常的代碼塊中調用rollback()方法撤銷事務。?
? ?7、數據庫連接池
之前的數據庫連接方式,是在需要時創建一個連接,當訪問?數據庫結束后,即將創建的連接銷毀。?
數據庫的連接池的基本思想:在數據源中為數據庫連接建立?多個連接,保存在連接池(connect pool)中;預先在連接池?中放入一定數量的連接,當Java程序訪問數據庫時,只需從?連接池中取出一個空閑狀態的數據庫連接。當程序訪問數據?庫結束,再將數據庫連接放回連接池。這樣就可以提高訪問
數據庫的效率,因為連接池只是將連接回收,而不是銷毀。?要清楚,數據庫連接的創建與銷毀是非常耗費資源的。?
二、
1、
/** 通過Java連接MySQL數據庫。*/ package day23;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;public class ConnectionTest {public static void main(String[] args) {Connection con = null;Statement st = null;try {// 可以創建驅動類的對象來令驅動類初始化,只是創建// 的對象是多余的(根本不使用該對象)// new com.mysql.jdbc.Driver();// 加載并初始化驅動類。Class.forName("com.mysql.jdbc.Driver");// 獲得數據庫的連接,返回Connection接口類型的對象。con = DriverManager.getConnection("jdbc:mysql://000.0.0.0:3306/test?useSSL=false", "root", "");// System.out.println(con);// 創建可執行的sql語句。st = con.createStatement();// 執行更新語句。返回受影響的記錄數。int count = st.executeUpdate("insert into student(id, name) values (8, '新增')");System.out.println(count);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {// 資源釋放的順序:// 先創建的后釋放,后創建的先釋放。if (st != null) {try {st.close();} catch (SQLException e) {e.printStackTrace();}}if (con != null) {try {con.close();} catch (SQLException e) {e.printStackTrace();}}}} }
2、TryWithResources:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class TryWithResources {public static void main(String[] args) {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}try (Connection con = DriverManager.getConnection("jdbc:mysql://***.0.0.1:3306/test?useSSL=false", "root", "");Statement st = con.createStatement();ResultSet rs = st.executeQuery("select id, name, age, sex from student");) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 判斷是否有下一條記錄,如果存在,返回true,同時
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 移動游標(指針),使其指向下一條記錄。如果不存在,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 返回false。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 根據字段的索引獲得當前記錄該字段的值。索引從1開始。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // int id = rs.getInt(1);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 根據字段的名字獲得當前記錄該字段的值。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int id = rs.getInt("id");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String name = rs.getString("name");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int age = rs.getInt("age");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?String sex = rs.getString("sex");
3、PreparedStatement
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class DBUtil {public static Connection getConnection() {Connection con = null;try {Class.forName("com.mysql.jdbc.Driver");con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useSSL=false", "root", "");} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return con;}public static void release(ResultSet rs, Statement st, Connection con) {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (st != null) {try {st.close();} catch (SQLException e) {e.printStackTrace();}}if (con != null) {try {con.close();} catch (SQLException e) {e.printStackTrace();}}} }import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement;public class PreparedTest {public static void main(String[] args) {}public void insert(int id, String name, int age, String sex) {try (Connection con = DBUtil.getConnection(); Statement st = con.createStatement();) {String sql = "insert into student(id, name, age, sex) values (" + id + ", '" + name + "'," + age + ",'"+ sex + "')";StringBuilder bu = new StringBuilder();bu.append("insert into student(id, name, age, sex) values (").append(id).append(",'").append(name).append("',").append(age).append(",'").append(sex).append("')");st.executeUpdate(sql);} catch (SQLException e) {e.printStackTrace();}}/** PreparedStatement與Statement* PreparedStatement是預處理的SQL語句對象,當重復* 執行時,PreparedStatement在性能上可能會好于* Statement(這要取決于底層數據庫是否支持預處理)。* PreparedStatement在程序的可讀性上,也好于* Statement,因此,我們應該總是有限的考慮使用* PreparedStatement。*/public void insert2(int id, String name, int age, String sex) {try (Connection con = DBUtil.getConnection();PreparedStatement ps = con.prepareStatement("insert into student(id, name, age, sex) values(?,?,?,?)")) {ps.setInt(1, id);ps.setString(2, name);ps.setInt(3, age);ps.setString(4, sex);ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();}}}
4、Transaction
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;public class Transaction {public static void main(String[] args) {Connection con = DBUtil.getConnection();try (PreparedStatement ps1 = con.prepareStatement("update account set money = money - 100 where id = 1");PreparedStatement ps2 = con.prepareStatement("updatedd account set money = money + 100 where id = 2");) {// 將自動提交設置為假。con.setAutoCommit(false);ps1.executeUpdate();ps2.executeUpdate();// 事務執行完畢,沒有異常,提交。con.commit();con.setAutoCommit(true);} catch (SQLException e) {try {// 失敗,進行回滾操作。恢復到事務執行之前的// 狀態。con.rollback();con.setAutoCommit(true);} catch (SQLException e1) {e1.printStackTrace();}e.printStackTrace();}}}
?
轉載于:https://www.cnblogs.com/liuwei6/p/7280399.html
總結
以上是生活随笔為你收集整理的Mysql(五) JDBC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷歌火狐浏览器限制的端口
- 下一篇: 一、CSS实现横列布局的方法总结