JDBC(Java Data Base Connectivity,java数据库连接)
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
JDBC是一種用于執(zhí)行SQL語句的Java API,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成。
Java數(shù)據(jù)庫連接體系結(jié)構(gòu)是用于Java應(yīng)用程序連接數(shù)據(jù)庫的標(biāo)準(zhǔn)方法,JDBC對Java程序員而言是API,對實(shí)現(xiàn)與數(shù)據(jù)庫連接的服務(wù)提供商而言是接口模型。作為API,JDBC為程序開發(fā)提供標(biāo)準(zhǔn)的接口,并為數(shù)據(jù)庫廠商及第三方中間件廠商實(shí)現(xiàn)與數(shù)據(jù)庫的連接提供了標(biāo)準(zhǔn)方法。
通常一個(gè)數(shù)據(jù)庫廠商在推出自己的數(shù)據(jù)庫產(chǎn)品的時(shí)候都會提供一套訪問數(shù)據(jù)庫的API,這些API可以用各種語言的形式提供,客戶端應(yīng)用程序調(diào)用這些API來訪問數(shù)據(jù)庫。每一個(gè)廠商提供的API都不相同,導(dǎo)致了使用某一個(gè)特定的數(shù)據(jù)庫的程序不能移植到另一個(gè)數(shù)據(jù)庫上。JDBC以Java類庫來取代數(shù)據(jù)庫廠商的專有API,客戶端只需要調(diào)用JDBC API,由JDBC驅(qū)動(dòng)程序(第三方數(shù)據(jù)庫廠商實(shí)現(xiàn)Java JDBC標(biāo)準(zhǔn)而定義的特定于某一數(shù)據(jù)庫操作的API)去處理與數(shù)據(jù)庫的通信。
應(yīng)用:
使用某種數(shù)據(jù)庫持久化數(shù)據(jù)要導(dǎo)入相應(yīng)的數(shù)據(jù)庫驅(qū)動(dòng)包。
主要數(shù)據(jù)庫JDBC驅(qū)動(dòng)的類名:
SQL Server:com.microsoft.jdbc.sqlserver.SQLServerDriver
MySQL:com.mysql.jdbc.Driver
Oracle:oracle.jdbc.driver.OracleDriver
1、首先我們一般要加載并注冊數(shù)據(jù)庫驅(qū)動(dòng),有以下三種方式可以做到這一點(diǎn):
???? ①、Class.forName("JDBC驅(qū)動(dòng)類名") //通過反射機(jī)制加載注冊驅(qū)動(dòng),常用
???? ②、System.setProperty("jdbc.driver","JDBC驅(qū)動(dòng)類名");//設(shè)置系統(tǒng)屬性指定數(shù)據(jù)庫驅(qū)動(dòng)
???? ③、DriverManager.registerDriver(new com.mysql.jdbc.Driver());
???? 總結(jié):推薦①,和②兩種方式。
???? 原因:③在編譯時(shí)需要導(dǎo)入對應(yīng)的lib。①,②不需要。
???? 第②種方式的話,可以同時(shí)導(dǎo)入多個(gè)jdbc驅(qū)動(dòng),中間用冒號“:”分開
???? 比如System.setProperty("jdbc.drivers","XXXDriver:XXXDriver:XXXDriver");
???? 這樣就一次注冊了三個(gè)數(shù)據(jù)庫驅(qū)動(dòng)
???? 在調(diào)用Class.forName(“XXXDriver”)時(shí),完成了將具體的驅(qū)動(dòng)程序向JDBC API中驅(qū)動(dòng)管理器DriverManager
???? 的注冊,該 注冊方法在類構(gòu)造完成前完成,一般使用靜態(tài)語句塊,
???? 通過查看MySQL的驅(qū)動(dòng)實(shí)現(xiàn)com.mysql.jdbc.Driver類可以看到
???? 在調(diào)用DriverManager的getConnection方法時(shí),一般先在已注冊的驅(qū)動(dòng)中查找可以了解此URL的驅(qū)動(dòng),
???? 然后調(diào)用該驅(qū)動(dòng)的connect方法,從而建立連接,返回的連接都是一個(gè)實(shí)現(xiàn)java.sql.Connection接口的具體類。
???? JDBC標(biāo)準(zhǔn)中的Driver接口:
????
???? 它是任何數(shù)據(jù)庫提供商的驅(qū)動(dòng)類必須實(shí)現(xiàn)的接口,驅(qū)動(dòng)類必須實(shí)現(xiàn)該接口中的所有方法!
???? MySQL驅(qū)動(dòng)類Driver源碼:?
package com.mysql.jdbc;import java.sql.SQLException;/*** The Java SQL framework allows for multiple database drivers. Each driver* should supply a class that implements the Driver interface* * <p>* The DriverManager will try to load as many drivers as it can find and then* for any given connection request, it will ask each driver in turn to try to* connect to the target URL.* * <p>* It is strongly recommended that each Driver class should be small and* standalone so that the Driver class can be loaded and queried without* bringing in vast quantities of supporting code.* * <p>* When a Driver class is loaded, it should create an instance of itself and* register it with the DriverManager. This means that a user can load and* register a driver by doing Class.forName("foo.bah.Driver")*/ public class Driver extends NonRegisteringDriver implements java.sql.Driver {// ~ Static fields/initializers// ---------------------------------------------//// Register ourselves with the DriverManager//static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException E) {throw new RuntimeException("Can't register driver!");}}/*** Construct a new driver and register it with DriverManager*/public Driver() throws SQLException {// Required for Class.forName().newInstance()} }
2、從DriverManager中的到一個(gè)DBMS連接,DriverManager類是整個(gè)JDBC的起點(diǎn)!利用它可以創(chuàng)建連接,
???? 從而完成后續(xù)的操作。調(diào)用DriverManager類的getConnection(String url, String user, String pwd)建立到
???? 數(shù)據(jù)庫的連接,返回一個(gè)連接對象。
???? 常見的url:
???? SQL Server :jdbc:microsoft:sqlserver://localhost:1443;databasename=數(shù)據(jù)庫名
???? Oracle :jdbc:oracle:thin:@localhost:1521:ORCL(數(shù)據(jù)庫實(shí)例名)
???? MySQL :jdbc:mysql://localhost:3306:/databasename
???? Jdbc-odbc橋 :jdbc:odbc:test(test為odbc數(shù)據(jù)源名稱)
public class DBUtil {private static String url = "jdbc:mysql://localhost:3306/spring";private static String user = "root";private static String pwd = "mysql5";private static Connection conn = null;static {try {//使用Class.forName()加載并注冊JDBC驅(qū)動(dòng)程序Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConnection() {try {//加載 Driver 類并在 DriverManager 類中注冊后,它們即可用來與數(shù)據(jù)庫建立連接。//當(dāng)調(diào)用 DriverManager.getConnection 方法發(fā)出連接請求時(shí),//DriverManager 將檢查每個(gè)驅(qū)動(dòng)程序,查看它是否可以建立連接。conn = DriverManager.getConnection(url, user, pwd);} catch (SQLException e) {e.printStackTrace();} return conn;}public static void closeConn() {try {conn.close();} catch (SQLException e) {e.printStackTrace();}} }
3、訪問數(shù)據(jù)庫進(jìn)行CRUD操作,對數(shù)據(jù)庫操作的接口類一般都位于java.sql包和javax.sql包下。
???? 數(shù)據(jù)庫連接被用于向數(shù)據(jù)庫服務(wù)器發(fā)送命令和SQL語句。
常用的數(shù)據(jù)庫操作接口類:
DriverManager:
public class DriverManager extends Object管理一組 JDBC 驅(qū)動(dòng)程序的基本服務(wù)。
在調(diào)用 getConnection 方法時(shí),DriverManager 會試著從初始化時(shí)加載的那些驅(qū)動(dòng)程序以及使用與當(dāng)前 applet 或應(yīng)用程序相同的類加載器顯式加載的那些驅(qū)動(dòng)程序中查找合適的驅(qū)動(dòng)程序。
Connection:
public interface Connection extends Wrapper與特定數(shù)據(jù)庫的連接(會話)。在連接上下文中執(zhí)行 SQL 語句并返回結(jié)果。
注:在配置 Connection 時(shí),JDBC 應(yīng)用程序應(yīng)該使用適當(dāng)?shù)?Connection 方法,比如 setAutoCommit 或 setTransactionIsolation。在有可用的 JDBC 方法時(shí),應(yīng)用程序不能直接調(diào)用 SQL 命令更改連接的配置。默認(rèn)情況下,Connection 對象處于自動(dòng)提交模式下,這意味著它在執(zhí)行每個(gè)語句后都會自動(dòng)提交更改。如果禁用了自動(dòng)提交模式,那么要提交更改就必須顯式調(diào)用 commit 方法;否則無法保存數(shù)據(jù)庫更改。
Statement:
public interface Statement extends Wrapper
用于執(zhí)行靜態(tài) SQL 語句并返回它所生成結(jié)果的對象。
Statement 對象用來將 SQL 語句發(fā)送到數(shù)據(jù)庫。不帶參數(shù)的 SQL 語句通常使用 Statement 對象執(zhí)行。如果多次執(zhí)行相同的 SQL 語句,使用 PreparedStatement 對象可能更有效。
PreparedStatement:
public interface PreparedStatement extends Statement表示預(yù)編譯的 SQL 語句的對象。
SQL 語句被預(yù)編譯并存儲在 PreparedStatement 對象中。然后可以使用此對象多次高效地執(zhí)行該語句。因此多次執(zhí)行的 SQL 語句經(jīng)常創(chuàng)建為 PreparedStatement 對象,以提高效率。
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)
resultset rs = pstmt.executequery();
ResultSet:
public interface ResultSet extends Wrapper表示數(shù)據(jù)庫結(jié)果集的數(shù)據(jù)表,通常通過執(zhí)行查詢數(shù)據(jù)庫的語句生成。
ResultSet 對象具有指向其當(dāng)前數(shù)據(jù)行的光標(biāo)。最初,光標(biāo)被置于第一行之前。next 方法將光標(biāo)移動(dòng)到下一行;因?yàn)樵摲椒ㄔ?ResultSet 對象沒有下一行時(shí)返回 false,所以可以在 while 循環(huán)中使用它來迭代結(jié)果集。
轉(zhuǎn)載于:https://my.oschina.net/xiaomaoandhong/blog/60795
總結(jié)
以上是生活随笔為你收集整理的JDBC(Java Data Base Connectivity,java数据库连接)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调用WebService时加入身份验证,
- 下一篇: Java程序访问Mysql Cluste