<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    JDBC Connection

    Java通過java.sql.DriverManager來管理所有數據庫的驅動注冊,所以如果想要建立數據庫連接需要先在java.sql.DriverManager中注冊對應的驅動類,然后調用getConnection方法才能連接上數據庫。

    JDBC定義了一個叫java.sql.Driver的接口類負責實現對數據庫的連接,所有的數據庫驅動包都必須實現這個接口才能夠完成數據庫的連接操作。java.sql.DriverManager.getConnection(xx)其實就是間接的調用了java.sql.Driver類的connect方法實現數據庫連接的。數據庫連接成功后會返回一個叫做java.sql.Connection的數據庫連接對象,一切對數據庫的查詢操作都將依賴于這個Connection對象。

    JDBC連接數據庫的一般步驟:

    1. 注冊驅動,Class.forName("數據庫驅動的類名")
    2. 獲取連接,DriverManager.getConnection(xxx)

    JDBC連接數據庫示例代碼如下:

    String CLASS_NAME = "com.mysql.jdbc.Driver";
    String URL = "jdbc:mysql://localhost:3306/mysql"
    String USERNAME = "root";
    String PASSWORD = "root";
    
    Class.forName(CLASS_NAME);// 注冊JDBC驅動類
    Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
    

    數據庫配置信息

    傳統的Web應用的數據庫配置信息一般都是存放在WEB-INF目錄下的*.properties*.yml*.xml中的,如果是Spring Boot項目的話一般都會存儲在jar包中的src/main/resources/目錄下。常見的存儲數據庫配置信息的文件路徑如:WEB-INF/applicationContext.xmlWEB-INF/hibernate.cfg.xmlWEB-INF/jdbc/jdbc.properties,一般情況下使用find命令加關鍵字可以輕松的找出來,如查找Mysql配置信息: find 路徑 -type f |xargs grep "com.mysql.jdbc.Driver"

    為什么需要Class.forName?

    很多人不理解為什么第一步必須是Class.forName(CLASS_NAME);// 注冊JDBC驅動類,因為他們永遠不會跟進驅動包去一探究竟。

    實際上這一步是利用了Java反射+類加載機制往DriverManager中注冊了驅動包!

    image-20191208225820692

    Class.forName("com.mysql.jdbc.Driver")實際上會觸發類加載,com.mysql.jdbc.Driver類將會被初始化,所以static靜態語句塊中的代碼也將會被執行,所以看似毫無必要的Class.forName其實也是暗藏玄機的。如果反射某個類又不想初始化類方法有兩種途徑:

    1. 使用Class.forName("xxxx", false, loader)方法,將第二個參數傳入false。
    2. ClassLoader.load(“xxxx”);

    Class.forName可以省去嗎?

    連接數據庫就必須Class.forName(xxx)幾乎已經成為了絕大部分人認為的既定事實而不可改變,但是某些人會發現刪除Class.forName一樣可以連接數據庫這又作何解釋?

    實際上這里又利用了Java的一大特性:Java SPI(Service Provider Interface),因為DriverManager在初始化的時候會調用java.util.ServiceLoader類提供的SPI機制,Java會自動掃描jar包中的META-INF/services目錄下的文件,并且還會自動的Class.forName(文件中定義的類),這也就解釋了為什么不需要Class.forName也能夠成功連接數據庫的原因了。

    Mysql驅動包示例:

    JDBC數據庫連接總結

    使用JDBC連接數據相對于PHP直接使用mysql_connect/mysqli_connect函數就可以完成數據庫連接來說的確難了很多,但是其中也暗藏了很多Java的特性需要我們去深入理解。

    或許您會有所疑問我們為什么非要搞明白Class.forName這個問題?這個問題和Java安全有必然的聯系嗎?其實這里只是想讓大家明白Java反射類加載機制、和SPI機制以及養成閱讀JDK或者第三方庫代碼的習慣,也希望不明白上述機制的朋友深入去理解思考下。

    學習完本節后希望您能去思考如下問題:

    1. SPI機制是否有安全性問題?
    2. Java反射有那些安全問題?
    3. Java類加載機制是什么?
    4. 數據庫連接時密碼安全問題?
    5. 使用JDBC如何寫一個通用的數據庫密碼爆破模塊?

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类