日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

JDBC总复习上

發(fā)布時間:2025/3/15 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDBC总复习上 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

一.JDBC概述

1.1數(shù)據(jù)持久化

?1.2對JDBC的理解

二.數(shù)據(jù)庫的連接(重點)

三.Statement與PreparedStatement

3.1Statement的弊端:

?3.2PreparedStatement的使用

3.2.1實現(xiàn)通用的增刪改操作

3.2.2通用的查詢操作

3.2.3操作Blob類型的變量

3.2.4實現(xiàn)批量插入

3.2.5小總結


漸漸的喜歡上了現(xiàn)在的自己,車會開,飯會做,錢能掙,不攀比,不較真,受得起敷衍?經得起謊言,在繁華中自律,在落魄中自愈。其實,奮斗不一定全是為了錢,還有骨子里的那份自信、淡定與從容。買的起自己喜歡的東西,去得了想去的地方,能承擔起自己應有的責任,努力把生活過成自己想要的樣子。

一.JDBC概述

1.1數(shù)據(jù)持久化

持久化(persistence):把數(shù)據(jù)保存到可掉電式存儲設備中以供之后使用。大多數(shù)情況下,特別是企業(yè)級應用,數(shù)據(jù)持久化意味著將內存中的數(shù)據(jù)保存到硬盤上加以”固化”,而持久化的實現(xiàn)過程大多通過各種關系數(shù)據(jù)庫來完成

持久化的主要應用是將內存中的數(shù)據(jù)存儲在關系型數(shù)據(jù)庫中,當然也可以存儲在磁盤文件、XML數(shù)據(jù)文件中。

?1.2對JDBC的理解

JDBC(Java Database Connectivity)是一個獨立于特定數(shù)據(jù)庫管理系統(tǒng)、通用的SQL數(shù)據(jù)庫存取和操作的公共接口(一組API)。簡單理解:是SUN公司提供的一套API,使用這套API可以實現(xiàn)對具體數(shù)據(jù)庫的操作(獲取連接,關閉連接,DML,DDL,DCL)。圖形理解:

?好處:

  • 面向應用的API:Java API,抽象接口,供應用程序開發(fā)人員使用(連接數(shù)據(jù)庫,執(zhí)行SQL語句,獲得結果)。

  • 面向數(shù)據(jù)庫的API:Java Driver API,供開發(fā)商開發(fā)數(shù)據(jù)庫驅動程序用。

java程序員:只需要面向這套接口編程即可。

不同的數(shù)據(jù)庫廠商:需要針對這套接口,提供不同實現(xiàn)。不同的實現(xiàn)的集合,即為不同數(shù)據(jù)庫的驅動。

二.數(shù)據(jù)庫的連接(重點)

public class ConnectionTest {@Testpublic void testConnection5() throws Exception{//1.加載配置文件到集合InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");Properties Pro = new Properties();pros.load(is);/*將配置文件的數(shù)據(jù)讀取到Properties集合中: 配置文件聲明在工程的src目錄下: user=root password=abc123 url=jdbc:mysql://localhost:3306/test driverClass=com.mysql.jdbc.Driver*///2.讀取配置文件String user=pro.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driverClass = pros.getProperty("driverClass");//3.加載驅動Class.forName(driverClass);//4.獲取連接Connection conn = DriverManager.getConnection(url,user,password);System.out.println(conn);}}

三.Statement與PreparedStatement

3.1Statement的弊端:

  • 問題一:存在拼串操作,繁瑣
  • 問題二:存在SQL注入問題? ?
    SQL 注入是利用某些系統(tǒng)沒有對用戶輸入的數(shù)據(jù)進行充分的檢查,而在用戶輸入數(shù)據(jù)中注入非法的 SQL 語句段或命令(如:SELECT user, password FROM user_table WHERE user='a' OR 1 = ' AND password = ' OR '1' = '1') ,從而利用系統(tǒng)的 SQL 引擎完成惡意行為的做法。
  • 他沒辦法操作Blob類型的變量
  • 實現(xiàn)批量插入時效率低

對于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(從Statement擴展而來,statement的子接口) 取代 Statement 就可以了。

?3.2PreparedStatement的使用

3.2.1實現(xiàn)通用的增刪改操作

//通用的增、刪、改操作(體現(xiàn)一:增、刪、改 ; 體現(xiàn)二:針對于不同的表)public void update(String sql,Object ... args){Connection conn = null;PreparedStatement ps = null;try {//1.獲取數(shù)據(jù)庫的連接conn = JDBCUtils.getConnection();//2.獲取PreparedStatement的實例 (或:預編譯sql語句)ps = conn.prepareStatement(sql);//3.填充占位符for(int i = 0;i < args.length;i++){ps.setObject(i + 1, args[i]);}//4.執(zhí)行sql語句ps.execute();} catch (Exception e) {e.printStackTrace();}finally{//5.關閉資源JDBCUtils.closeResource(conn, ps);}}

3.2.2通用的查詢操作

// 通用的針對于不同表的查詢:返回一個對象 (version 1.0)public <T> T getInstance(Class<T> clazz, String sql, Object... args) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {// 1.獲取數(shù)據(jù)庫連接conn = JDBCUtils.getConnection();// 2.預編譯sql語句,得到PreparedStatement對象ps = conn.prepareStatement(sql);// 3.填充占位符for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}// 4.執(zhí)行executeQuery(),得到結果集:ResultSetrs = ps.executeQuery();// 5.得到結果集的元數(shù)據(jù):ResultSetMetaDataResultSetMetaData rsmd = rs.getMetaData();// 6.1通過ResultSetMetaData得到columnCount,columnLabel;通過ResultSet得到列值int columnCount = rsmd.getColumnCount();if (rs.next()) {T t = clazz.newInstance();for (int i = 0; i < columnCount; i++) {// 遍歷每一個列// 獲取列值Object columnVal = rs.getObject(i + 1);// 獲取列的別名:列的別名,使用類的屬性名充當String columnLabel = rsmd.getColumnLabel(i + 1);// 6.2使用反射,給對象的相應屬性賦值Field field = clazz.getDeclaredField(columnLabel);field.setAccessible(true);field.set(t, columnVal);}return t;}} catch (Exception e) {e.printStackTrace();} finally {// 7.關閉資源JDBCUtils.closeResource(conn, ps, rs);}return null;}

3.2.3操作Blob類型的變量

寫入操作的方法:setBlob(InputStream in)

讀取操作的方法:Blob b=new Blob()

? ? ? ? ? ? ? ? ? ? ? ? ?InputStream is = b.getBinaryStream()? ??

具體演示:

//插入圖片//獲取連接 Connection conn = JDBCUtils.getConnection();String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql);// 填充占位符 ps.setString(1, "徐海強"); ps.setString(2, "xhq@126.com"); ps.setDate(3, new Date(new java.util.Date().getTime())); // 操作Blob類型的變量 FileInputStream fis = new FileInputStream("xhq.png"); ps.setBlob(4, fis); //執(zhí)行 ps.execute();fis.close(); JDBCUtils.closeResource(conn, ps);//============================================================================String sql = "SELECT id, name, email, birth, photo FROM customer WHERE id = ?"; conn = getConnection(); ps = conn.prepareStatement(sql); ps.setInt(1, 8); rs = ps.executeQuery(); if(rs.next()){Integer id = rs.getInt(1);String name = rs.getString(2);String email = rs.getString(3);Date birth = rs.getDate(4);Customer cust = new Customer(id, name, email, birth);System.out.println(cust); //讀取Blob類型的字段Blob photo = rs.getBlob(5);InputStream is = photo.getBinaryStream();OutputStream os = new FileOutputStream("c.jpg");byte [] buffer = new byte[1024];int len = 0;while((len = is.read(buffer)) != -1){os.write(buffer, 0, len);}JDBCUtils.closeResource(conn, ps, rs);if(is != null){is.close();}if(os != null){os.close();}}

注意:

如果在指定了相關的Blob類型以后,還報錯:xxx too large,那么在mysql的安裝目錄下,找my.ini文件加上如下的配置參數(shù): max_allowed_packet=16M。同時注意:修改了my.ini文件之后,需要重新啟動mysql服務。

?

3.2.4實現(xiàn)批量插入

/* * 層次四:在層次三的基礎上操作 * 使用Connection 的 setAutoCommit(false) / commit() */ @Test public void testInsert2() throws Exception{long start = System.currentTimeMillis();Connection conn = JDBCUtils.getConnection();//1.設置為不自動提交數(shù)據(jù)conn.setAutoCommit(false);String sql = "insert into goods(name)values(?)";PreparedStatement ps = conn.prepareStatement(sql);for(int i = 1;i <= 1000000;i++){ps.setString(1, "name_" + i);//1.“攢”sqlps.addBatch();if(i % 500 == 0){//2.執(zhí)行ps.executeBatch();//3.清空ps.clearBatch();}}//2.提交數(shù)據(jù)conn.commit();long end = System.currentTimeMillis();System.out.println("花費的時間為:" + (end - start));//1000000條:4978 JDBCUtils.closeResource(conn, ps); }

3.2.5小總結

兩種思想:面向接口編程的思想ORM思想(object relational mapping):一個數(shù)據(jù)表對應一個java類,表中的一條記錄對應java類的一個對象,表中的一個字段對應java類的一個屬性

兩種技術:JDBC結果集的元數(shù)據(jù):ResultSetMetaData,獲取列數(shù):getColumnCount(),獲取列的別名:getColumnLabel()。通過反射,創(chuàng)建指定類的對象,獲取指定的屬性并賦值

  • PreparedStatement 能最大可能提高性能:

    • DBServer會對預編譯語句提供性能優(yōu)化。因為預編譯語句有可能被重復調用,所以語句在被DBServer的編譯器編譯后的執(zhí)行代碼被緩存下來,那么下次調用時只要是相同的預編譯語句就不需要編譯,只要將參數(shù)直接傳入編譯過的語句執(zhí)行代碼中就會得到執(zhí)行。

    • 在statement語句中,即使是相同操作但因為數(shù)據(jù)內容不一樣,所以整個語句本身不能匹配,沒有緩存語句的意義.事實是沒有數(shù)據(jù)庫會對普通語句編譯后的執(zhí)行代碼緩存。這樣每執(zhí)行一次都要對傳入的語句編譯一次。

    • (語法檢查,語義檢查,翻譯成二進制命令,緩存)

  • PreparedStatement 可以防止 SQL 注入

總結

以上是生活随笔為你收集整理的JDBC总复习上的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。