25、jdbc操作数据库(2)
說一下使用jdbc時涉及到的一些基本的接口和類
java.sql.Driver
是數據庫驅動接口,com.mysql.jdbc.Driver是mysql對應的驅動,由數據庫供應商實現,用于提供驅動,實現了java.sql.Driver接口。
java.sql.DriverManager
管理驅動的類,可以使用DriverManager通過驅動來獲取數據庫連接。
java.sql.Connection
對數據庫連接進行管理的接口,一個Connection就相當于一個通往對應數據庫的通道。
對以上幾個做一個詳細介紹,直接看源碼:
//com.mysql.jdbc.Driver 實現了 java.sql.Driver接口 public class Driver extends NonRegisteringDriver implements java.sql.Driver {//向驅動管理器注冊自己static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException E) {throw new RuntimeException("Can't register driver!");}}//構造一個 com.mysql.jdbc.Driver 用于注冊public Driver() throws SQLException {// Required for Class.forName().newInstance()} }// 驅動管理器類中,看一下如何注冊驅動、獲取數據庫連接的 public class DriverManager {//注冊驅動最終調用的方法public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) throws SQLException {//如果驅動程序還沒有添加到列表 registeredDrivers 中,請注冊它if(driver != null) {registeredDrivers.addIfAbsent(new DriverInfo(driver, da));} else {throw new NullPointerException();}}//獲取連接最終調用的方法private static Connection getConnection( String url, java.util.Properties info, Class<?> caller) throws SQLException {//當callerCl為null時,我們應該檢查應用程序(它間接調用這個類)的類加載器,//這樣就可以從這里加載rt.jar外部的JDBC驅動程序類。ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;synchronized(DriverManager.class) {if (callerCL == null) {callerCL = Thread.currentThread().getContextClassLoader();}}// 遍歷試圖建立連接的已加載的 registeredDrivers。 for(DriverInfo aDriver : registeredDrivers) {// 如果調用方沒有加載驅動程序的權限,那么跳過它。if(isDriverAllowed(aDriver.driver, callerCL)) {Connection con = aDriver.driver.connect(url, info);if (con != null) { return (con);}}} } }java.sql.Statement
對數據庫操作的一個接口,可以發送sql、執行sql,它是先組裝sql,然后發送sql查詢結果,因此存在缺陷,其缺陷在于它發送的sql是將參數拼接完之后再進行編譯的,所以容易發生sql注入攻擊的危險,一般不用,這里不做詳細介紹。
何為sql注入攻擊,例如:發送的如下SQL
"SELECT * FROM USER WHERE USER_NAME = "+ USER_NAME +"AND PWD = "+PWD;
這時我這樣設置:USER_NAME = user | PWD = 111 or 1=1,則SQL就會變成
SELECT * FROM USER WHERE USER_NAME = user AND PWD = 111 or 1=1
這樣就直接規避掉了用戶名和密碼的校驗。
java.sql.PreparedStatement
對數據庫操作的一個接口,可以發送sql、執行sql,在獲取PreparedStatement對象時,就已經將sql發送出去編譯成了可執行的sql語句,也就是常說的預編譯,SQL中使用占位符的方式來表示參數,占位符的地方只是參數,不能所作sql中固定的語法
例如:發送的sql="SELECT * FROM USER WHERE USER_NAME = ? AND PWD = ?";
然后再另外使用方法的方式去設置 ? 占位符處的參數,防止了sql注入的風險,通過Connection接口的connection.prepareStatement(sql)方法獲取PreparedStatement,具體實現調用的是? com.mysql.jdbc.ConnectionImpl 中的方法。
java.sql.CallableStatement
和 PreparedStatement 功能大致相同,只是CallableStatement對象可以用于執行存儲過程,而PreparedStatement只可以執行基本的SQL語句。
java.sql.ResultSet
用于存儲查詢返回的結果集,對于mysql來說,最終是通過com.mysql.jdbc.PreparedStatement中的方法獲取的ResultSet對象。
java.sql.DatabaseMetaData
此對象用于獲取數據庫的整體綜合信息,可以使用Connection對象的connection.getMetaData()方法直接獲取。
java.sql.ResultSetMetaData
用于獲取關于ResultSet對象中列的類型和屬性信息,通過ResultSet對象的resultSet.getMetaData()方法直接獲取。
java.sql.Types
這個類中定義了用于標識SQL類型的常量,稱為JDBC類型。
這里總結一下:開發者使用jdbc操作數據庫時,添加驅動時需要添加對應數據庫廠商提供的驅動包中的Driver,而后具體操作時,直接調用 java.sql.* 包中接口的方法即可,最終底層調用的是對應數據庫廠商提供的com.*.jdbc.*包中的實現類中的方法,數據庫廠商提供的驅動包實現了java.sql.*包中接口的方法,這就是代碼層面上的jdbc。java提供一組接口,數據庫廠商實現這些接口,根據自身的特點編寫不同的實現,而程序員只需使用java中的接口即可,利用了多態的方式。
總結
以上是生活随笔為你收集整理的25、jdbc操作数据库(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 戴尔 U2424H / HE 显示器开卖
- 下一篇: 市场监管总局:我国基本构建适老家电产品国