JDBC
1.連接數(shù)據(jù)庫的方式
? ? 常見有兩種: ODBC和JDBC,分屬兩個不同的陣營。
? ? 其中JDBC是java版本的ODBC
? ? ODBC(Open Database Connectivity)開放的數(shù)據(jù)庫連接,由微軟開發(fā)出來。是一套公共的接口(標準),用來連接數(shù)據(jù)庫。
? ? JDBC是一套標準(接口),用來連接【關(guān)系型數(shù)據(jù)庫】。各個數(shù)據(jù)庫廠商去實現(xiàn)具體的功能,用戶使用時使用相同一套標準即可。但是在使用時得導(dǎo)入不同公司提供的包(里面包含了具體實現(xiàn))。
2.JDBC概念
JDBC(Java DataBase Connectivity,java數(shù)據(jù)庫連接)是一種用于執(zhí)行SQL語句的Java API ,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準,據(jù)此可以構(gòu)建更高級的工具和接口,使數(shù)據(jù)庫開發(fā)人員能夠編寫數(shù)據(jù)庫應(yīng)用程序。
? ? JDBC API是什么?
Sun公司提供的一套標準的數(shù)據(jù)訪問接口,用來訪問關(guān)系型數(shù)據(jù)庫。另外,它包含了一部分類和接口,屬于Java語言的一部分。
? ? JDBC可以做什么:
連接數(shù)據(jù)庫
發(fā)送sql語句到數(shù)據(jù)庫
處理結(jié)果集
? ? JDBC API包含兩部分內(nèi)容:
Java應(yīng)用程序開發(fā)接口(提供給用戶)
Java驅(qū)動開發(fā)接口(實現(xiàn)公共接口功能,各大數(shù)據(jù)庫廠商做)
3.JDBC驅(qū)動
? ? 其實就是一組類和接口的集合,實現(xiàn)了JDBC相關(guān)的功能。
? ? java.sql.Driver 這個驅(qū)動接口很重要,我們借助這個類實現(xiàn)了數(shù)據(jù)庫的連接。
? ? JDBC【驅(qū)動提供了特定廠商對JDBC API接口類的實現(xiàn)】,驅(qū)動必須要提供java.sql包下面這些類的實現(xiàn):Connection,Statement,PreparedStatement,CallableStatement,ResultSet和Driver.
******************************
4.JDBC驅(qū)動類型
? ? Java中的JDBC驅(qū)動可以分為【四種類型】,包括【JDBC-ODBC橋、本地API驅(qū)動、網(wǎng)絡(luò)協(xié)議驅(qū)動和本地協(xié)議驅(qū)動】。
5.JDBC-ODBC橋
? ? JDBC-ODBC 橋 是sun公司提供的,是jdk提供的的標準API.【底層是借助ODBC】實現(xiàn)功能,缺陷是效率較低,還得必須安裝ODBC驅(qū)動。
****以下內(nèi)容了解即可****
? ? 這種類型的驅(qū)動實際是把所有 JDBC的調(diào)用傳遞給ODBC ,再由ODBC調(diào)用本地數(shù)據(jù)庫驅(qū)動代碼.( 本地數(shù)據(jù)庫驅(qū)動代碼是指 由數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫操作二進制代碼庫,例如在oracle for windows中就是oci dll 文 件)
? ? 只要本地機裝有相關(guān)的ODBC驅(qū)動那么采用JDBC-ODBC橋幾乎可以訪問所有的數(shù)據(jù)庫,JDBC- ODBC方法對于客戶端已經(jīng)具備ODBC driver的應(yīng)用還是可行的.
但是,由于JDBC-ODBC先調(diào)用 ODBC再由ODBC去調(diào)用本地數(shù)據(jù)庫接口訪問數(shù)據(jù)庫.所以,執(zhí)行效率比較低,對于那些大數(shù)據(jù)量 存取的應(yīng)用是不適合的.而且,這種方法要求客戶端必須安裝ODBC 驅(qū)動,所以對于基于 internet ,intranet的應(yīng)用也是不合適的.因為,你不可能要求所有客戶都能找到ODBC driver.
6.本地API驅(qū)動
? ? 本地API驅(qū)動直接【把JDBC調(diào)用】轉(zhuǎn)變?yōu)椤緮?shù)據(jù)庫的標準調(diào)用】再去訪問數(shù)據(jù)庫.效率比第一種高,但得【需要額外的數(shù)據(jù)庫工具】。
這種方法需要本地 數(shù)據(jù)庫驅(qū)動代碼、本地API驅(qū)動、廠商DB代碼。這種驅(qū)動比起JDBC-ODBC橋執(zhí)行效率大大提高了.但是,它仍然需要在客戶端加載數(shù)據(jù)庫廠商 提供的代碼庫.這樣就不適合基于internet的應(yīng)用.并且,他的執(zhí)行效率比起其他的JDBC驅(qū)動 還是不夠高.
7.網(wǎng)絡(luò)協(xié)議驅(qū)動
? ? 這種驅(qū)動實際上是根據(jù)我們熟悉的三層結(jié)構(gòu)建立的.
? ? JDBC先把對數(shù)局庫的訪問請求傳遞給網(wǎng)絡(luò)上的【中間件服務(wù)器】. 中間服務(wù)器再把請求【翻譯為符合數(shù)據(jù)庫規(guī)范的調(diào)用】,再把這種調(diào)用 【傳給數(shù)據(jù)庫服務(wù)器】.
? ? 如果中間服務(wù)器也是用java開發(fā)的,那么在在中間層也可以使用上面說的那倆種驅(qū)動類型 JDBC驅(qū)動程序作為訪問數(shù)據(jù)庫的方法. 網(wǎng)絡(luò)協(xié)議驅(qū)動---------中間服務(wù)器------------數(shù)據(jù)庫Server
? ? 由于這種驅(qū)動是基于server的.所以,它不需要在客戶端加載數(shù)據(jù)庫廠商提供的代碼庫.而且 他在執(zhí)行效率和可升級性方面是比較好的.因為大部分功能實現(xiàn)都在server端,所以這種驅(qū)動 可以設(shè)計的很小,可以非??焖俚募虞d到內(nèi)存中.
? ? 但是,這種驅(qū)動在中間件層仍然需要有配置 其它數(shù)據(jù)庫驅(qū)動程序,并且由于多了一個中間層傳遞數(shù)據(jù),它的執(zhí)行效率還不是最好.
8.本地協(xié)議驅(qū)動
? ? 我們【當前使用的JDBC驅(qū)動】一般都是這種類型。
? ? 這種類型的驅(qū)動【完全由java實現(xiàn)】,實現(xiàn)了平臺獨立性。
它可以直接把JDBC調(diào)用轉(zhuǎn)換為符合相關(guān)數(shù)據(jù)庫系統(tǒng)規(guī)范的請求.這種驅(qū)動寫的應(yīng)用可以直接和數(shù)據(jù)庫服務(wù)器通訊。
本地協(xié)議驅(qū)動【效率非常高】,因為它不需要先把JDBC的調(diào)用傳給ODBC或本地數(shù)據(jù)庫接口或者是中間層服務(wù)器。
而且,它不需要在客戶端或服務(wù)器端裝載任何的軟件或驅(qū)動, 這種驅(qū)動程序可以動態(tài)的被下載。
但是對于不同的數(shù)據(jù)庫【需要下載不同的驅(qū)動程序】(驅(qū)動實現(xiàn)jar包)。
*******************************
9.JDBC數(shù)據(jù)庫操作相關(guān)類和接口
? ? Driver驅(qū)動接口
? ? DriverManager驅(qū)動管理器【類】
? ? Connection數(shù)據(jù)庫連接
? ? Statement操作語句
PreparedStatement
CallableStatement
? ? ResultSet結(jié)果集
? ? DatabaseMetadata數(shù)據(jù)庫信息(包含數(shù)據(jù)庫有哪些表,視圖,列,類型等信息,由表反向生成類)
? ? ResultSetMetadata結(jié)果集信息
? ? Types類型【類】(數(shù)據(jù)庫表類型與java代碼中類型String,int,double等的對應(yīng))
jdbc開發(fā)接口,存在于兩個包下,其中【java.sql包】下實現(xiàn)了基本功能;剩余部分存在于【javax.sql包】中,實現(xiàn)擴展功能。
10.JDBC操作流程
? ? 用戶如何通過Java代碼連接到 指定的數(shù)據(jù)庫服務(wù)器,然后進行操作。
? ? 有6個固定的步驟,按照步驟操作即可。
1).注冊驅(qū)動(驅(qū)動:具體功能實現(xiàn))
2).建立數(shù)據(jù)庫連接
3).創(chuàng)建Statement對象(可以進行sql與執(zhí)行)
4).執(zhí)行SQL語句(增刪改查)
5).處理結(jié)果集
6).關(guān)閉相應(yīng)資源
11.注冊驅(qū)動
【注冊驅(qū)動】的過程,可以理解成【安裝驅(qū)動】。想一下生活中安裝好系統(tǒng),usb外接鼠標不能用,安裝個驅(qū)動就可以用了。此處注冊好了驅(qū)動,數(shù)據(jù)庫連接就可以使用了。
? ? 注冊驅(qū)動的三種方案:
使用類加載器
實例化一個驅(qū)動對象,使用new的方式
使用property
ojdbc5.jar Oracle11g配套推出的
ojdbc6.jar 11g配套推出
ojdbc14.jar Oracle10g發(fā)布時配套推出的
? ? 14、5、6與JDK的版本有關(guān)系,14是1.4版本以上,ojdbc5.jar得jdk5,ojdbc6.jar得用jdk6及其以上版本。
查看自己jdk版本命令: java -version
? ? 此后學習過程中,不僅僅要注意代碼,還要關(guān)注環(huán)境是否配置正常。(防火墻、殺毒軟件等都可能會影響最后的結(jié)果)
12.JDBC連接類型
JDBC的連接類型有兩種,分別是oci 和 thin
? ? 1)、JDBC OCI
oci是oracle call interface的縮寫,此驅(qū)動類似于傳統(tǒng)的ODBC 驅(qū)動。
因為它需要Oracle Call Interface and Net8,所以它【需要】在運行使用此驅(qū)動的JAVA程序的機器上安裝【客戶端軟件】,其實主要是用到orcale客戶端里以dll方式提供的oci和服務(wù)器配置。
? ? 2)、JDBC Thin
thin是for thin client的意思,這種驅(qū)動一般用在運行在WEB瀏覽器中的JAVA程序。
它不是通過OCI or Net8,而是通過Java sockets進行通信,是純java實現(xiàn)的驅(qū)動,因此【不需要】在使用JDBC Thin的客戶端機器上安裝orcale【客戶端軟件】,所以有很好的移植性,通常用在web開發(fā)中。
我們更多的【選擇thin】這種方式進行服務(wù)器連接。
13.JDBC四要素
? ? 1).String driver = "jar包Driver類全包名";
告訴我們具體數(shù)據(jù)庫驅(qū)動在哪里,方便后期注冊。
String dirver = "oracle.jdbc.driver.OracleDriver";
? ? 2).URL 確定連接到那個具體的數(shù)據(jù)庫
jdbc:oracle:oci:@<SID>? oci連接方式
jdbc:oracle:thin:@<SID> thin連接方式
String url = "jdbc:oracle:thin:@127.0.0.1:1521:XE";
? ? 3).String user = "用戶名";
? ? 4).String password = "密碼";
14.注冊driver和連接數(shù)據(jù)庫
14.1 注冊driver有三種方式
? ? a.使用類加載器
String driverName = "oracle.jdbc.driver.OracleDriver";
Class.forName(driverName);
? ? b.實例化一個驅(qū)動對象
實例化驅(qū)動對象
Driver driver = new oracle.jdbc.driver.OracleDriver();
注冊驅(qū)動
DriverManager.registerDriver(driver);
? ? c.使用property
System.setProperty("jdbc.drivers", "oracle.jdbc.driver.OracleDriver");
使用【系統(tǒng)配置】進行驅(qū)動注冊,其中【第一個參數(shù)值固定】,第二個參數(shù)為驅(qū)動類的全包名。
? ? 補充: 也可以運行虛擬機時,設(shè)置運行參數(shù)。
這種方式也是通過系統(tǒng)配置進行驅(qū)動注冊。
-Djdbc.drivers=oracle.jdbc.driver.OracleDriver
14.2 數(shù)據(jù)庫連接的方式有兩種:
第一種是利用DriverManager.getConnection(url, user, passwd);
第二種是利用Driver類直接連接(其實第一種底層也是通過Driver建立的連接)。
Driver driver = new oracle.jdbc.driver.OracDriver();
Properties info = new Properties();
info.setProperty("user","");
info.setProperty("password","");
conn = driver.connect(url,info);
關(guān)于DriverManager和Driver的關(guān)系
一個DriverManager可以管理多個Driver,在具體進行數(shù)據(jù)庫連接時,管理類借助Driver里面的connect方法建立連接。
****************
數(shù)據(jù)庫連接不成功解決方案
反復(fù)檢查四要素是否寫錯
數(shù)據(jù)庫未啟動
防火墻影響
換個jar包試試
如果按照oracle出現(xiàn)中文路徑,不行
如果按照成功后修改計算機用戶名,也行
重裝oracle
****************
15.Statement語句
? ? Statement stmt = conn.createStatement();
String sql = "";
? ? stmt.execute(sql);
? ? stmt.executeQuery(sql);
? ? stmt.executeUpdate(sql);
? ? 一共有三種執(zhí)行方式,他們都可以正常執(zhí)行select insert update delete語句,區(qū)別在于返回值類型。
? ? execute(sql)返回boolean,執(zhí)行【返回結(jié)果集則true】,否則false;
? ? executeUpdate(sql)【返回int】,執(zhí)行影響了多少條數(shù)據(jù);
? ? executeQuery(sql)返回結(jié)果集ResultSet。
16.java.util.Date和java.sql.Date
? ? java.util.Date是java.sql.Date的父類;
? ? 一般情況下表示時間,用util.Date,在操作sql語句時才使用sql.Date
? ? 通過【時間戳】值進行轉(zhuǎn)換
? ? 例如: new java.sql.Date(utilDate.getTime());
17.事務(wù)提交
DML語句
? ? 設(shè)置事務(wù)自動提交 關(guān)閉,【默認是開啟】的
? ? conn.setAutoCommit(false);
? ? ...創(chuàng)建stmt對象
? ? ...執(zhí)行sql語句
? ? conn.commit();手動提交事務(wù)
? ? conn.rollback();回滾事務(wù)
? ? 注意: 【conn.close();事務(wù)會自動提交】。
create table student(
id number primary key,
name varchar2(20) not null,
birthday date,
score number
);
同構(gòu):sql語句結(jié)構(gòu)相同
插入100條數(shù)據(jù)
insert into student(id,name,birthday,score)
values(?,?,?,?);
PrepareStatement處理同構(gòu)的sql語句
異構(gòu): 結(jié)構(gòu)不同
insert into ;
delete;
update;
Statement來處理異構(gòu)的sql語句。
//同構(gòu)? ps執(zhí)行原理
//1.構(gòu)建ps對象的同時,先將sql語句發(fā)送到DB服務(wù)器
//2.將具體的值設(shè)置給ps
//3.ps執(zhí)行,傳遞數(shù)據(jù)給DB服務(wù)器
//4.DB服務(wù)器接收數(shù)據(jù),結(jié)合sql框架,完成功能
//5.返回數(shù)據(jù)給當前應(yīng)用程序
//1.將sql語句發(fā)送到 DB數(shù)據(jù)庫,
//2.DB數(shù)據(jù)庫執(zhí)行sql語句
//3.將結(jié)果返回給當前應(yīng)用程序
18.同構(gòu)和異構(gòu)
? ? 【異構(gòu)】sql語句,結(jié)構(gòu)不同的語句。
Statement語句執(zhí)行,每次執(zhí)行sql語句,都會把sql語句通過網(wǎng)絡(luò)發(fā)送到服務(wù)器,然后讓服務(wù)器實現(xiàn)功能。
? ? 同構(gòu) 【結(jié)構(gòu)相同】的sql語句
insert into student(id,name,age,birthday)
values(x,y,z,m);
insert into student(id,name,age,birthday)
values(x,y,z,m);
? ? 在實際使用時,可以提前將Sql語句發(fā)送給數(shù)據(jù)庫進行【預(yù)編譯】,然后每次只需要傳輸值即可,這樣子可以提高效率。
String sql = "insert into student(id,name,age,birthday)
values(?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setInt(1,7);
ps.setString(2, "王五");
ps.setInt(3, 21);
注意,【將 util.Date轉(zhuǎn)換為sql.Date】? 通過時間戳值進行
java.util.Date utilDate = new java.util.Date();
ps.setDate(4, new java.sql.Date(utilDate.getTime()));
注意,ps執(zhí)行sql語句時,沒有必要也不能傳sql語句,因為sql語句已經(jīng)提前發(fā)送到服務(wù)器了
ps.execute();
create table student(
id number primary key,
name varchar2(20) not null,
birthday date,
score number
);
19.通過PrepareStatement進行其他操作
PrepareStatement可以預(yù)編譯sql語句。
使用PrepareStatement語句進行增刪改查。
使用PrepareStatement的好處,除了效率高,還有就是 【省去了字符串的拼接】。
在select時,將數(shù)據(jù)導(dǎo)入到Student對象中,然后添加到list集合中,最后統(tǒng)一遍歷。
**************************
注意:如果同時在終端和代碼里面操作sql語句,操作后一定要提交事務(wù),否則會造成線程阻塞,代碼一直運行不成功。
驅(qū)動注冊的 4種方式
1.Class.forName();
2.OracleDriver od = new OracleDriver();
DriverManager.registerDriver(od);
3.系統(tǒng)配置
System.setProperty("jdbc.drivers","");
4.配置虛擬機運行時參數(shù)
-Djdbc.drivers=...;
數(shù)據(jù)連接的 2種方式
1.DriverManager.getConnection(url,user,passwd);
2.od.connect(url,info);
inof = new Properties();
事務(wù)的操作
終端? delete from student;(開啟事務(wù))
? commit;
源碼? insert into ;(開啟事務(wù))
線程阻塞,由事務(wù)未提交引起的。
java.util.Date和java.sql.Date
sql下的Date 是 util的子類
時間戳 long值? 毫秒
PrepareStatement和Statement
同構(gòu) 異構(gòu)
第二天課程
1.批處理測試
獲取當前時間System.currentTimeMillis();
批處理:
? ? 并不是逐條語句進行處理,而是時機成熟后,批量執(zhí)行成功。
//添加到批處理
? ? stmt.addBatch(sql);
//執(zhí)行批處理
? ? stmt.executeBatch();
模擬四種情況
? ? 事務(wù)手動提交,不使用批處理,使用Statement
? ? 事務(wù)手動提交,不使用批處理,PrepareStatement
? ? 事務(wù)手動提交,使用批處理,Statement
? ? 事務(wù)手動提交,使用批處理,PrepareStatement(實際應(yīng)用最多,效果最明顯)
? ? 測試,不同方式插入上千條數(shù)據(jù),計算實際使用時間。
? ? java.util.Date start = System.currentTimeMillis();
? ? java.util.Date end = System.currentTimeMillis();
syso("運行時間: "+(end-start));
2.Statement和PrepareStatement對比
? ? ? ? ? ? Statement? PrepareStatement
? ? sql在哪里創(chuàng)建? ? ? 客戶端 客戶端
? ? sql代碼存儲到哪? ? 客戶端? ? 服務(wù)器(預(yù)處理預(yù)編譯)
? ? 什么技術(shù)編寫代碼? sql語句? sql
? ? 配置性 ? ? ? 很高 第一次高,以后固定
? ? 可移植性 ? ? ? ? 高? ? ? 高,數(shù)據(jù)庫得支持預(yù)編譯
? ? 效率 ? ? ? 低 高
客戶端: 項目源碼部分
服務(wù)器: 數(shù)據(jù)庫服務(wù)器
student表
id? name? score? birthday
1 zs 78 09-9月-17
2 ls 78 09-9月-17
3.DatabaseMetaData數(shù)據(jù)庫元對象
MetaData元數(shù)據(jù),描述數(shù)據(jù)的數(shù)據(jù)。
? ? 可以用來獲得數(shù)據(jù)庫的相關(guān)信息
? ? 獲得數(shù)據(jù)庫對象(表、視圖、索引)的相關(guān)信息
? ? 獲得數(shù)據(jù)庫中列的信息
? ? 獲得RusultSet中包含的列信息
4.獲得數(shù)據(jù)庫相關(guān)信息
? ? metaData.getDatabaseProductName();
數(shù)據(jù)庫名字
? ? metaData.getDatabaseProductName();
數(shù)據(jù)庫版本詳細信息
? ? metaData.getDatabaseProductName();
產(chǎn)品的主版本
? ? metaData.getDatabaseProductName();
產(chǎn)品的次版本
//獲取數(shù)據(jù)庫 里面? 對象信息
ResultSet getTables(
String catalog, //null
String schema, //用戶名
? ? String tableName,
String types[]) throws SQLException;
5.獲得數(shù)據(jù)庫中表相關(guān)信息
? ? catalog:
? ? schema:
? ? tableName: 表名
? ? types: 具體類型,表、視圖、索引、同義詞
? ? metaData.getTables(catalog,schema,tableName,types);
? ? catalog,schema:在SQL環(huán)境下這兩個都屬于抽象概念,用來解決命名沖突問題。
從概念上說,一個數(shù)據(jù)庫系統(tǒng)包含多個Catalog,每個Catalog包含多個Schema,而每個Schema又包含多個數(shù)據(jù)庫對象(表、視圖、索引)。
也可以說一個數(shù)據(jù)庫對象必然屬于一個schema,而schema又屬于一個catalog。
常用實現(xiàn)方式是使用【數(shù)據(jù)庫名作為Catalog名】,使用【用戶名作為Schema名】。
數(shù)據(jù)庫 Catalog Schema
Oracle 不支持 用戶名
MySql 不支持 數(shù)據(jù)庫名
具體應(yīng)用:
? ? rs = metaData.getTables(null,"TEST",null,new String[]{"TABLE"});
? ? while(rs.next()) {
String tName = rs.getString("TABLE_NAME");
String tType = rs.getString("TABLE_TYPE");
? ? }
通過數(shù)據(jù)字典可以實現(xiàn)相同功能:
select table_name from user_tables;
查詢出來的BIN$開頭的屬于數(shù)據(jù)庫回收站里面的殘留信息。
purge recyclebin; 可以【清空回收站】
6.獲取數(shù)據(jù)庫中列信息
? ? metaData.getColumns(catalog,schema,tableName,columnName);
? ? rs = metaData.getColumns(null,"TEST","STUDENT",null);
? ? while(rs.next()){
String colName = rs.getString("COLUMN_NAME");
String colType = rs.getString("TYPE_NAME");
? ? }
7.獲取ResultSet中包含的列信息
? ? 包含多少列
? ? 每列都是什么數(shù)據(jù)類型
? ? ResultSetMetaData metaData = rs.getMetaData();
? ? //獲取列數(shù)
? ? int columnNum = metaData.getColumnCount();
? ? for(int i = 1;i <= columnNum;i++){
//獲取每一列名稱
syso(metaData.getColumnName(i));
//獲取每一列類型
syso(metaData.getColumnTypeName(i));
? ? }
同構(gòu)和異構(gòu)
同構(gòu): sql語句結(jié)構(gòu)相同
String sql = "?,?,?";
PrepareStatement ps = conn.prepareStatement(sql);
ps.setXXX(1,*);
ps.setXXX(2,*);
...
ps.execute();
異構(gòu): sql語句結(jié)構(gòu)不同
Statement
引入: 驅(qū)動注冊 4種? Class.forName();
new OracleDriver();
System.setProperty("jdbc.drivers",OracleDriver全包名);
-Djdbc.drivers=oracle.jdbc.driver.OracleDriver
數(shù)據(jù)庫連接的兩種方式
DriverManager.getConnection(url,user,password);
Driver dr = new ;
dr.connect(url,info);? info(user,password);
批處理
stmt|ps.addBatch();
...
stmt|ps.executeBatch();
結(jié)論: ps 和 批處理結(jié)合使用,會大大提高效率。
事務(wù)控制
conn.setAutoCommit(false);
conn.commit();
conn.rollback();
理解: 為什么封裝,封裝的好處,具體研發(fā)中,誰來進行封裝。
程序員使用起來更簡單
架構(gòu)組的人員|業(yè)務(wù)組長|主要編程? 公共代碼
自己
8.封裝jdbc操作過程
? ? a.創(chuàng)建一個工廠類,生成數(shù)據(jù)庫連接對象
? ? ? 將數(shù)據(jù)庫連接四要素,放入配置文件
properties文件? xml文件兩種情況
? ? b.封裝關(guān)閉方法
? ? c.封裝sql語句的執(zhí)行
9.進一步封裝
? ? 在上述基礎(chǔ)上,將具體的功能實現(xiàn),封裝到一個接口內(nèi)部,用戶在具體實現(xiàn)功能時,匿名內(nèi)部類操作即可。
MyBatis 對JDBC的封裝。
封裝注意事項:
代碼相同的,直接封裝成公共代碼
代碼不同的,留給用戶來實現(xiàn)