商丘做網(wǎng)站哪個(gè)好怎么在百度上注冊(cè)店鋪
提示:文章寫完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
JDBC回顧
- 前言
- 一、JDBC
- 1.JDBC是什么?
- 2.如何使用?
- (1)注冊(cè)驅(qū)動(dòng)
- (2)獲取連接
- (3)操作數(shù)據(jù)表
- 3、ResultSet與ResultSetMetaData
- (1)ResultSet
- (2)ResultSetMetaData
前言
前段時(shí)間看到有關(guān)JDBC的一篇文章,頗有感觸,閑來(lái)無(wú)事回顧總結(jié)一下有關(guān)JDBC的知識(shí)點(diǎn)。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、JDBC
1.JDBC是什么?
我們?cè)谖词褂肑DBC之前,連接不同的數(shù)據(jù)庫(kù),就像如下圖例一樣,使用那個(gè)數(shù)據(jù)庫(kù)就使用對(duì)應(yīng)的連接方法,數(shù)據(jù)庫(kù)一多,不同的連接方法就顯得雜亂,不整齊,無(wú)規(guī)矩。
有了 JDBC之后:
總結(jié)來(lái)說(shuō):
- JDBC是一個(gè)獨(dú)立于特定數(shù)據(jù)庫(kù)管理系統(tǒng)、通用的SQL數(shù)據(jù)庫(kù)存取和操作的公共接口(一組API),定義了用來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)Java類庫(kù),(java.sql,javax.sql)使用這些類庫(kù)可以以一種標(biāo)準(zhǔn)的方法、方便地訪問(wèn)數(shù)據(jù)庫(kù)資源。
- JDBC為訪問(wèn)不同的數(shù)據(jù)庫(kù)提供了一種統(tǒng)一的途徑,為開(kāi)發(fā)者屏蔽了一些細(xì)節(jié)問(wèn)題。
- JDBC的目標(biāo)是使Java程序員使用JDBC可以連接任何提供了JDBC驅(qū)動(dòng)程序的數(shù)據(jù)庫(kù)系統(tǒng),這樣就使得程序員無(wú)需對(duì)特定的數(shù)據(jù)庫(kù)系統(tǒng)的特點(diǎn)有過(guò)多的了解,從而大大簡(jiǎn)化和加快了開(kāi)發(fā)過(guò)程。
2.如何使用?
使用JDBC主要從以下入手:
1、注冊(cè)驅(qū)動(dòng)
2、獲取連接
3、創(chuàng)建statement對(duì)象
4、發(fā)送SQL語(yǔ)句
5、結(jié)果集解析
6、關(guān)閉資源 【先開(kāi)后關(guān)】
舉例:
public static void main(String[] args) throws SQLException {//1.注冊(cè)驅(qū)動(dòng)/*** TODO: 注意* Driver ->5.8及其以上 com.mysql.cj.jdbc.Driver* 5.8以下 com.mysql.jdbc.Driver*/DriverManager.registerDriver(new Driver());//2.獲取連接/*** TODO: 注意* 面向接口編程* java.sql 接口 = 實(shí)現(xiàn)類* connection 使用java.sql.Connection接口接收*/Connection connection = DriverManager.getConnection("jdbc:mysql://192.168.31.19:3306/atguigu", "root", "root");//3.創(chuàng)建小車Statement statement = connection.createStatement();//4.發(fā)送SQL語(yǔ)句String sql = "select id,account,password,nickname from t_user ;";ResultSet resultSet = statement.executeQuery(sql);//5.結(jié)果集解析while (resultSet.next()){int id = resultSet.getInt("id");String account = resultSet.getString("account");String password = resultSet.getString("password");String nickname = resultSet.getString("nickname");System.out.println(id+"::"+account+"::"+password+"::"+nickname);}//6.關(guān)閉資源 【先開(kāi)后關(guān)】resultSet.close();statement.close();connection.close();}
(1)注冊(cè)驅(qū)動(dòng)
①
/**
*加載 JDBC 驅(qū)動(dòng)需調(diào)用 Class 類的靜態(tài)方法 forName(),向其傳
*遞要加載的 JDBC 驅(qū)動(dòng)的類名
*/
Class.forName(“com.mysql.jdbc.Driver”);
②
//1.加載配置文件InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");Properties pros = new Properties();pros.load(is);//2.讀取配置信息String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driverClass = pros.getProperty("driverClass");//3.加載驅(qū)動(dòng)Class.forName(driverClass);
其中,配置文件聲明在工程的src目錄下:【jdbc.properties】
user=root
password=abc123
url=jdbc:mysql://localhost:3306/test
driverClass=com.mysql.jdbc.Driver
說(shuō)明:使用配置文件的方式保存配置信息,在代碼中加載配置文件
使用配置文件的好處:
①實(shí)現(xiàn)了代碼和數(shù)據(jù)的分離,如果需要修改配置信息,直接在配置文件中修改,不需要深入代碼
②如果修改了配置信息,省去重新編譯的過(guò)程。
(2)獲取連接
可以調(diào)用 DriverManager 類的 getConnection() 方法建立到數(shù)據(jù)庫(kù)的連接
? User,password可以用“屬性名=屬性值”方式告訴數(shù)據(jù)庫(kù);
? JDBC URL 用于標(biāo)識(shí)一個(gè)被注冊(cè)的驅(qū)動(dòng)程序,驅(qū)動(dòng)程序管理器通過(guò)這個(gè) URL 選擇正確的
驅(qū)動(dòng)程序,從而建立到數(shù)據(jù)庫(kù)的連接。
(3)操作數(shù)據(jù)表
①使用Statement操作數(shù)據(jù)表
- 通過(guò)調(diào)用 Connection 對(duì)象的 createStatement() 方法創(chuàng)建該對(duì)象。該對(duì)象用于執(zhí)行靜態(tài)的 SQL 語(yǔ)句,并且返回執(zhí)行結(jié)果。
- Statement 接口中定義了下列方法用于執(zhí)行 SQL 語(yǔ)句:
/*** SQL分類:DDL(容器創(chuàng)建、修改、刪除) DML(插入、修改、刪除) DQL(查詢) TPL(事務(wù)控制語(yǔ)言)* 方式一:* int i = statement.executeUpdate(sql);* 參數(shù):sql 非DQL* 返回: int* 情況1:DML 返回影響行數(shù),例如刪除了三條數(shù)據(jù) return 3; 插入了兩條 return 2* 情況2: 非DML return 0;* 方式二:* ResultSet resultSet = statement.executeQuery(sql);* 參數(shù):sql DQL* 返回: resultSet 結(jié)果封裝對(duì)象**/
int excuteUpdate(String sql):執(zhí)行更新操作INSERT、UPDATE、DELETE
ResultSet executeQuery(String sql):執(zhí)行查詢操作SELECT
-
但是使用Statement操作數(shù)據(jù)表存在弊端:
- 問(wèn)題一:存在拼串操作,繁瑣
- 問(wèn)題二:存在SQL注入問(wèn)題
-
SQL 注入是利用某些系統(tǒng)沒(méi)有對(duì)用戶輸入的數(shù)據(jù)進(jìn)行充分的檢查,而在用戶輸入數(shù)據(jù)中注入非法的 SQL 語(yǔ)句段或命令(如:SELECT user, password FROM user_table WHERE user=‘a(chǎn)’ OR 1 = ’ AND password = ’ OR ‘1’ = ‘1’) ,從而利用系統(tǒng)的 SQL 引擎完成惡意行為的做法。
-
對(duì)于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(從Statement擴(kuò)展而來(lái)) 取代 Statement 就可以了。
②PreparedStatement
可以通過(guò)調(diào)用 Connection 對(duì)象的 preparedStatement() 方法獲取
PreparedStatement 對(duì)象
?PreparedStatement 接口是 Statement 的子接口,它表示一條預(yù)編譯過(guò)的
SQL 語(yǔ)句
?PreparedStatement 對(duì)象所代表的 SQL 語(yǔ)句中的參數(shù)用問(wèn)號(hào)(?)來(lái)表示,調(diào)
用 PreparedStatement 對(duì)象的 setXxx() 方法來(lái)設(shè)置這些參數(shù). setXxx() 方
法有兩個(gè)參數(shù),第一個(gè)參數(shù)是要設(shè)置的 SQL 語(yǔ)句中的參數(shù)的索引(從 1 開(kāi)
始),第二個(gè)是設(shè)置的 SQL 語(yǔ)句中的參數(shù)的值
舉例:
@Testpublic void test() throws ClassNotFoundException, SQLException {Class.forName("com.mysql.cj.jdbc.Driver");Connection connection = DriverManager.getConnection(URL, USER, PS);String sql = "insert into t_user(account,password,nickname) values (?,?,?);";PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,"test");preparedStatement.setString(2,"1243");preparedStatement.setString(3,"user");int i = preparedStatement.executeUpdate();System.out.println(i);preparedStatement.close();connection.close();
}
3、ResultSet與ResultSetMetaData
(1)ResultSet
-
查詢需要調(diào)用PreparedStatement 的 executeQuery() 方法,查詢結(jié)果是一個(gè)ResultSet 對(duì)象
-
ResultSet 對(duì)象以邏輯表格的形式封裝了執(zhí)行數(shù)據(jù)庫(kù)操作的結(jié)果集,ResultSet 接口由數(shù)據(jù)庫(kù)廠商提供實(shí)現(xiàn)
-
ResultSet 返回的實(shí)際上就是一張數(shù)據(jù)表。有一個(gè)指針指向數(shù)據(jù)表的第一條記錄的前面。
-
ResultSet 對(duì)象維護(hù)了一個(gè)指向當(dāng)前數(shù)據(jù)行的游標(biāo),初始的時(shí)候,游標(biāo)在第一行之前,可以通過(guò) ResultSet 對(duì)象的 next() 方法移動(dòng)到下一行。調(diào)用 next()方法檢測(cè)下一行是否有效。若有效,該方法返回 true,且指針下移。相當(dāng)于Iterator對(duì)象的 hasNext() 和 next() 方法的結(jié)合體。
-
當(dāng)指針指向一行時(shí), 可以通過(guò)調(diào)用 getXxx(int index) 或 getXxx(int columnName) 獲取每一列的值。
- 例如: getInt(1), getString(“name”)
- 注意:Java與數(shù)據(jù)庫(kù)交互涉及到的相關(guān)Java API中的索引都從1開(kāi)始。
-
ResultSet 接口的常用方法:
- boolean next()
- getString()
- …
(2)ResultSetMetaData
-
可用于獲取關(guān)于 ResultSet 對(duì)象中列的類型和屬性信息的對(duì)象
-
ResultSetMetaData meta = rs.getMetaData();
- getColumnName(int column):獲取指定列的名稱
- getColumnLabel(int column):獲取指定列的別名
- getColumnCount():返回當(dāng)前 ResultSet 對(duì)象中的列數(shù)。
- getColumnTypeName(int column):檢索指定列的數(shù)據(jù)庫(kù)特定的類型名稱。
- getColumnDisplaySize(int column):指示指定列的最大標(biāo)準(zhǔn)寬度,以字符為單位。
- isNullable(int column):指示指定列中的值是否可以為 null。
- isAutoIncrement(int column):指示是否自動(dòng)為指定列進(jìn)行編號(hào),這樣這些列仍然是只讀的。
關(guān)于ResultSetMetaData**
- 如何獲取 ResultSetMetaData: 調(diào)用 ResultSet 的 getMetaData() 方法即可
- 獲取 ResultSet 中有多少列:調(diào)用 ResultSetMetaData 的 getColumnCount() 方法
- 獲取 ResultSet 每一列的列的別名是什么:調(diào)用 ResultSetMetaData 的getColumnLabel() 方法