摘要:同時也有一些兒高級的處理,比如批處理更新事務隔離和可滾動結果集等。連接對象表示通信上下文,即,與數據庫中的所有的通信是通過此唯一的連接對象。因為是針對類的關系而言,所以一個對象對應多個類的實例化。返回表示查詢返回表示其它操作。
JDBC是什么?
JDBC是一個Java API,用中文可以通俗的解釋為,使用Java語言訪問訪問數據庫的一套接口集合。這是調用者(程序員)和實行者(數據庫廠商)之間的協議,可以訪問任何類型表列數據,特別是存儲在關系數據庫中的數據。JDBC(java database connection)
既然JDBC也是由Java類和接口組成,那么首先要學習的是,它屬于哪個包下面。
在JDBC中包含了兩個包:java.sql和javax.sql
java.sql:基本功能,這個包中的類和接口主要針對基本的數據庫編程服務,如生成連接、執行語句以及準備語句和運行批處理查詢等。同時也有一些兒高級的處理,比如批處理更新、事務隔離和可滾動結果集等。
javax.sql:擴展功能。它主要為數據庫方面的高級操作提供了接口和類。如為連接管理、分布式事務和舊有的連接提供了更好的抽象,它引入了容器管理的連接池、分布式事務和行集等。
JDBC結構概述可以看出JDBC在圖中的位置,前文說過是程序員與數據庫廠商之間的協議。首先Java提拱了JDBC的接口,服務器廠商提供了JDBC的驅動,這樣我們通過JDBC Driver Manager來進行管理數據庫。
主要接口和類DriverManager: 這個類管理數據庫驅動程序的列表。 確定內容是否符合從Java應用程序使用的通信子協議正確的數據庫驅動程序的連接請求。 識別JDBC在一定子協議的第一個驅動器將被用來建立數據庫連接。 Driver: 此接口處理與數據庫服務器通信。 很少直接直接使用驅動程序(Driver)對象,一般使用DriverManager中的對象, 它用于管理此類型的對象。它也抽象與驅動程序對象工作相關的詳細信息 Connection : 此接口與接觸數據庫的所有方法。 連接對象表示通信上下文,即,與數據庫中的所有的通信是通過此唯一的連接對象。 Statement : 可以使用這個接口創建的對象的SQL語句提交到數據庫。 一些派生的接口接受除執行存儲過程的參數。 ResultSet: 這些對象保存從數據庫后,執行使用Statement對象的SQL查詢中檢索數據。 它作為一個迭代器,可以通過移動它來檢索下一個數據。 SQLException: 這個類用于處理發生在數據庫應用程序中的任何錯誤。JDBC編程(以mysql為例) 注冊驅動(有三種方式)
①Class.forName("com.mysql.jdbc.Driver"); Java規范中明確規定,所有的驅動程序必須在靜態初始代碼塊中將驅動注冊到驅動程序的管理器中,
static{ try{ Class.forName(driver); } catch(Exception ex){ ex.printStackTrace(); } }
這樣做的好處是,再類被加載到工程時就被執行了,而且之執行一次,數據庫驅動只要加載一次就可以了。
【知識點】 Class類
在這里面我們看到了,這個里面有一個Class類,它調用了一個forName()方法,那么這個Class類是個什么東西呢?
Class類是在java.lang包下的,所以不用手動的導入。
看一下Class的構造方法[1]
private Class(ClassLoader loader){ classLoader = loader; }
不用去管什么ClassLoader,看了一眼private關鍵字,應該就知道了,當private修飾構造方法的時候,說明該類是不能在類的外面進行實例化的。所以Class類不能像普通的類一樣,以new Xxx()的形式進行創建對象,它的對象只能由JVM創建。[2]
Class類到底是什么呢?不妨我們通俗的說一下,Java程序在運行的時候,我們會讓它創建一些對象,系統通過RTTI對所有的對象進行運行時類型表示。
【知識點】RTTI
RTTI(runtime type Identification),通過運行時類型信息程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。
我們把它叫成運行時類型信息,或許更加的好理解。這個是Java語言中很強大的機制。
首先要知道的運行時都會存在哪些類型信息呢?如果一個類繼承自另一個類,在創建子類的對象時,需要RTTI存儲這些關系,他會有typeid操作符,返回指針和引用所指的實際類型,typeid函數等等,我們簡要的理解為Java的RTTI里面就是記錄著各種類型的信息。
以下是一些常用的方式。
A = (A)b;向下轉型
我們可以針對于基類來編程,從而降低程序的耦合度,以Java來說常常通過繼承的方式,來達到這種效果。
public class Demo { public static void main(String[] args) { Animal [] animals = new Animal[2]; animals[0] = new Tiger(); animals[1] = new fish(); for (Animal animal : animals) { animal.breath(); } } } abstract class Animal { abstract void breath(); } class Tiger extends Animal{ @Override void breath() { // TODO Auto-generated method stub } } class fish extends Animal{ @Override void breath() { // TODO Auto-generated method stub } }
像這種繼承關系,之所以能夠編譯通過,是因為Tiger和FIsh都會向上轉為基類,他們自身的類型信息會丟失,但是程序運行的時候,當我們調用animal.breath();它們卻能準確的找到所屬類型的方法進行調用,這是為什么呢?這就是運行時綁定(動態綁定)機制。
進一步分析,RTTI里面就是存儲著程序運行時類型的方法列表,繼承結構等等信息。
load class(類的裝載過程)
類從被加載到卸載,他的生命周期包括:加載 驗證 準備 解析 初始化 使用 和卸載七個階段
而類的加載階段有:加載 驗證 準備 解析 初始化。
重點說一下加載階段:類只有在要運行的時候才會被加載進JVM,編譯后的class文件現在還沒有加載到jvm,當我們命令行輸入java xxx.class,這個時候類才開始加載到虛擬機,一般來說一個class只會被加載一次,下一次就會從Jvm的class緩存中獲取,不會再去文件系統中獲取了。具體的過程是:java這個命令是java.exe進行的,java.exe找到jre,再找到JRE中的jvm.dll,這個就是Java 虛擬機,這個時候虛擬機啟動,它首先就加載了第一個類加載器--Bootstrap Loader,這個BootstrapLoader又加載了第二個類加載器ExtClassLoader,設定parent為null(本質上是bootstraploader,但是它是由C++編寫的,無法找到這個實例)這個BootstrapLoader又加載了最后一個類加載器APPClassLoader,設定它的parent為ExtClassLoader。
類的類class of classes
Class類原理:當各類被實例化后,JVM會自動創建該類的Class對象,或者通過類加載器defineClass()方法生成。
所有的類都繼承自Object類,Object類有一個getClass()方法,這個方法可以獲取某個對象的Class引用,這個引用就是指向的是Class類的對象。
因為是針對類的關系而言,所以一個Class對象對應多個類的實例化。
獲取Class對象:
通過類名來獲取:
public class Hello{} Class hello = Class.forName("Hello");
通過對象來獲取。
public class Hello{} Hello h = new Hello(); Class hello = h.getClass();
通過類字面量來獲取
public class Hello{} Class hello = Hello.class;
【注】使用第三種方法來獲取Class對象,Jvm不會加載類,也就不會初始化,而其他兩種方法,會自動加載并初始化類。
回到正題。第二種注冊數據庫驅動的方法是。
②
Driver drv = new oracle.jdbc.driver.OracleDriver(); DriverManager.registerDriver(drv);
③ 編譯時在虛擬機中加載驅動
java -D jdbc.drivers = 驅動全名 類名 例如: javac -D jdbc.drivers = oracle.jdbc.driver.OracleDrvier xxx.java
【問題】以下是知乎的問題
JDBC注冊數據庫驅動,啥意思?
Class.forName("com.mysql.jdbc.Driver")不是反射么,得到這個類的信息,和注冊數據庫驅動有啥關系?
答:
作者:木女孩
鏈接:https://www.zhihu.com/questio...
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
創建一個Connection對象,建立物理連接
static final String USER = "XXX"; static final String PASSWORD = "xxx"; System.out.println("database is connecting"); Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.23:1521:tarena",USER,PASSWORD);
回想之前的結構圖,我們可以知道,通過DriverManager可以操作數據庫的驅動,從而進行數據庫的相關操作。
這里Connection連接就是通過DriverManager的靜態方法getCOnnection()來得到的,這個方法的實質是把參數傳到實際的Driver中的connect()方法來忽的數據庫的連接的。
下面是一些格式的補充:
Oracle URL的格式:jdbc:oracle:thin:(協議)@XXX.XXX.X.XXX:XXXX(IP地址及端口號):XXXXXX(所使用的庫名)
MySql URL:jdbc:mysql://192.168.8.21:3306/test
SQLServer URL 的寫法 jdbc:microsoft:sqlserver://192.168.8.21:1433
通過Connection對象createStatement()來創建Statement對象
Statement stm = conn.createStatement();執行SQL語句
通過Statement來執行
stm.excuteQuery(Sring sql); //返回一個查詢結果集 stm.excuteUpdate(String sql); //返回值為 int 型,表示影響記錄的條數。 stm.excute(String sql);//返回 true,表示查詢;返回 false,表示其它操作。處理結果集ResultSet
通過excuteQuery(String sql)可以使用select語句進行查詢,并且返回一個結果集ResultSet。ResultSet的next()方法會操作一個游標從第一條記錄的前面開始讀取,直到最后一條記錄。
【注】只有執行select語句才有結果集返回。
while(rs.next()){ System.out.println(rs.getInt("id)); System.out.println(rs.getString("name")); }關閉數據庫連接(釋放資源)
rs.close(); stm.close(); conn.close()
應該順序關閉,如果先關閉Connetction后面可能還需要其他的Statement連接。
參考資料[1] 淺談Java中的Class類
[2] Java中Class類及用法
[3] RTTI
[4] 深入Java類型信息:RTTI
[5] 類加載的全過程
[6] java類加載過程
[7] 深入理解java類加載起ClassLoader
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68817.html
摘要:寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。這個階段學習的時候,要學會使用開發工具,比如或者來學習。這個階段需要自己對自己有很強的自律去學習,不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。也給想要學習 ...
摘要:寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。這個階段學習的時候,要學會使用開發工具,比如或者來學習。這個階段需要自己對自己有很強的自律去學習,不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。也給想要學習 ...
摘要:寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。這個階段學習的時候,要學會使用開發工具,比如或者來學習。這個階段需要自己對自己有很強的自律去學習,不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。也給想要學習 ...
閱讀 3054·2023-04-26 00:40
閱讀 2391·2021-09-27 13:47
閱讀 4197·2021-09-07 10:22
閱讀 2966·2021-09-06 15:02
閱讀 3307·2021-09-04 16:45
閱讀 2484·2021-08-11 10:23
閱讀 3599·2021-07-26 23:38
閱讀 2900·2019-08-30 15:54