posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          好快,已經(jīng)是12月份了,11月5日開的班。就快學習一個月了,總學習時間是四個月。過年休息9天,這樣到明年3月14日課程就結(jié)束了。好好學習,回去找個好工作!

          今日是JDBC的第一天,JDBC的基礎(chǔ)應(yīng)用。以后在WEB開發(fā)中的使用方式。課程中,方老師上午在講解JDBC基礎(chǔ)的同時做了一個JDBC練習程序,對JDBC的基礎(chǔ)應(yīng)用。下午,方老師做了一個使用數(shù)據(jù)庫的WEB應(yīng)用,用戶注冊、登錄、用戶信息修改。

          先讓我們來了解一下JDBC(Java Data Base Connectivity)基礎(chǔ)吧!

          我們都知道數(shù)據(jù)庫都提供一些接口,用戶使用這些接口操作數(shù)據(jù)庫。這就是數(shù)據(jù)庫驅(qū)動!常見的數(shù)據(jù)庫有MySQL、Oracle、SQLServer、DB2等,這些數(shù)據(jù)庫提供的接口都不一樣,難道開發(fā)人員使用不同的數(shù)據(jù)庫就要學習不同的驅(qū)動接口嗎?JDBC正是為統(tǒng)一數(shù)據(jù)庫訪問接口而實現(xiàn)的,SUN公司提出了這一接口。數(shù)據(jù)庫公司都去實現(xiàn)這一接口。大大方便了,編程人員對數(shù)據(jù)庫的操作:

          clip_image002

          在工程中使用JDBC,必須導入相應(yīng)的JAR包。比如使用MySQL數(shù)據(jù)庫,必須導入MySQL實現(xiàn)的JDBC jar包。可以到http://dev.mysql.com/downloads/下載。

          使用JDCB進行數(shù)據(jù)訪問的基本流程,見代碼:

          隱藏行號 復(fù)制代碼 這是一段程序代碼。
          1. import java.sql.Connection;
                
          2. import java.sql.DriverManager;
                
          3. import java.sql.ResultSet;
                
          4. import java.sql.SQLException;
                
          5. import java.sql.Statement;
                
          6. 
                
          7. public class JDBCTemp {
                
          8. 
                
          9.     public static void main(String[] main) throws Exception {
                
          10.         // 1.裝
                
          11.         DriverManager.registerDriver(new com.mysql.jdbc.Driver());
                
          12.         /*
                
          13.          * 因om.mysql.jdbc.Driver在
                
          14.          * 上om.mysql.jdbc.Driver,
                
          15.          * 所
                
          16.          */
                
          17.         Class.forName("com.mysql.jdbc.Driver");
                
          18.         // 2.連
                
          19.         Connection conn = DriverManager.getConnection(
                
          20.                 "jdbc:mysql://localhost:3306/databasename", "username",
                
          21.                 "password");
                
          22.         // 3.創(chuàng)QL語tatement對
                
          23.         Statement sta = conn.createStatement();
                
          24.         // 4.執(zhí)QL語
                
          25.         boolean ok = sta.execute("select * from user;");
                
          26.     
          27.         // 5.遍
                
          28.         ResultSet rs = null;
                
          29.         if(ok){
                
          30.             rs = sta.getResultSet();
                
          31.             while(rs.next()){
                
          32.                 rs.getInt(1);
                
          33.                 //...
                
          34.             }
                
          35.         }
                
          36.     
          37.         // 6.釋esultSet、tatement、onnection這
                
          38.         // 必
                
          39.         // 下
                
          40.         if(rs != null){
                
          41.             try {
                
          42.                 rs.close();
                
          43.             } catch (SQLException e) {
                
          44.                 e.printStackTrace();
                
          45.             }
                
          46.             rs = null;
                
          47.         }
                
          48.     
          49.         if(sta != null){
                
          50.             try {
                
          51.                 sta.close();
                
          52.             } catch (SQLException e) {
                
          53.                 e.printStackTrace();
                
          54.             }
                
          55.             sta = null;
                
          56.         }
                
          57.     
          58.         if(conn != null){
                
          59.             try {
                
          60.                 conn.close();
                
          61.             } catch (SQLException e) {
                
          62.                 e.printStackTrace();
                
          63.             }
                
          64.             conn = null;
                
          65.         }
                
          66.     }
                
          67. }
                
          68. 
                

           

          上面的代碼只為演示,繼續(xù)向下學習就會發(fā)現(xiàn)其中的一些問題。

          其中

          DriverManager.getConnection("jdbc:mysql://localhost:3306/databasename", "username","password");

          GetConnection的第一個參數(shù)“jdbc:mysql://localhost:3306/databasename

          ”,它的各段含義如下:

          Jdbc:協(xié)議

          Mysql:子協(xié)議

          localhost:主機

          3306:端口

          databasename:數(shù)據(jù)庫名

          常見的URL如下:

          Oracle :jdbc:oracle:thin:@localhost:1521:sid

          SQLServer:jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid

          MYSQL:jdbc:mysql://localhost:3306/sid

          如果把上面的代碼用于用戶登錄或查詢數(shù)據(jù)時,會造成一個嚴重的安全漏洞——SQL注入!

          例,根據(jù)提交的用戶名查找用戶:

          "select id,name,password from user where name='"+name+"'";

          如果用戶提交的用戶名是:“’ or 1=1 or 1=‘”,會發(fā)生什么問題?因為在where過濾時使用了or邏輯,其有的1=1返回真,結(jié)果可以正常通過驗證。這是一個十分嚴重的安全漏洞!

          為此Java為我們提供了PreparedStatement接口,表示預(yù)編譯的 SQL 語句的對象。SQL 語句被預(yù)編譯并存儲在 PreparedStatement 對象中,然后可以使用此對象多次高效地執(zhí)行該語句。PreparedStatement的使用:

          PreparedStatement ps = conn.prepareStatement("select id,name,password form user where name=? and passowrd=?");

          ps.setString(1, name);

          ps.setString(2, password);

          這樣就可以解決SQL注入的漏洞,同時也可以高效的執(zhí)行SQL語句。上面的使用方法一眼就看出來了,一個“?”對應(yīng)下邊的ps.setXXX方法,按照“?”先后,對應(yīng)ps.setXXX第一個參數(shù)的索引!

          我們使用Statement. execute執(zhí)行了查詢語句,Statement還有其他以execute開頭的方法,具體針對查詢和增加、刪除、修改的方法,在此就不一一說明了。JDK手冊里邊有詳細說明。

          查詢成功后,在Statement對象中,可以獲得記錄集對象ResultSet,查詢的結(jié)果全都保存在ResultSet中嗎?仔細想想,好像是。如果有1億條記錄符合查詢條件,同時有1000個用戶調(diào)用同一查詢,那服務(wù)器不燒了嗎!所以查詢的結(jié)果并未保存在ResultSet中,而是保存在數(shù)據(jù)庫中,ResultSet指向數(shù)據(jù)庫的引用。這樣很方便也很快捷!那數(shù)據(jù)庫會不會被充爆了?當然不會,數(shù)據(jù)本身就保存在數(shù)據(jù)庫中,數(shù)據(jù)庫的查詢結(jié)果頂多就保存的指向數(shù)據(jù)的“指針”。

          ResultSet對象內(nèi)部有一個游標,游標初始位置是第一條記錄前。必須調(diào)用它的next()方法,才會到第一條記錄,依次向下。如果不存在記錄,或者已經(jīng)到記錄尾,則返回false。存在記錄返回true。然后我們可以通過調(diào)用它的getObject、getInt、getString…方法調(diào)用相應(yīng)的值,如果只使用getObject獲取記錄值,必須使用強轉(zhuǎn)將它轉(zhuǎn)換為我們需要的類型。

          下面是常用數(shù)據(jù)類型轉(zhuǎn)換表(老方整理的,嘿嘿):

          SQL類型

          Jdbc對應(yīng)方法

          返回類型

          BIT

          getBoolean()

          Boolean

          TINYINT

          getByte()

          Byte

          SMALLINT

          getShort()

          Short

          int

          getInt()

          Int

          BIGINT

          getLong()

          Long

          CHAR,VARCHAR,LONGVARCHAR

          getString()

          String

          Text Blob

          getColb() getBlob()

          Clob blob

          DATE

          getDate()

          Java.sql.Date

          TIME

          getTime()

          Java.sql.Time

          TIMESTAMP

          getTimestamp()

          Java.sql.Timestamp

          關(guān)于使用JDBC進行CURD的操作比較簡單,因為昨天已經(jīng)學習了在控制臺有使用這些操作,在此就不多進行復(fù)習了。但一定要記住每次使用完數(shù)據(jù)庫連接時,一定要釋放。一是因為數(shù)據(jù)庫有同時連接數(shù)量限制,二是因為數(shù)據(jù)連接會占用服務(wù)器資源。安全釋放這些連接,參看上邊的釋放代碼。常規(guī)的項目開發(fā)中,會將對數(shù)據(jù)庫的操作封裝到一個類中,這樣方便使用。

          在常規(guī)項目開發(fā)中,我們需要編寫操作數(shù)據(jù)的DAO類。因為對數(shù)據(jù)庫的一些操作需要處理異常,為了查錯直觀一些。我們在環(huán)繞這些異常時,將它們包裝一下再拋出。如何包裝異常?JAVA的包裝類很多,我們的包裝也是通過這個方法實現(xiàn)的。編寫一個繼承處Exception類的子類,然后將接收的異常存到父親類中,我們也可以在自定義類中添加些自己的提示信息。這樣當程序運行時拋出的異常,可以直觀的定位到錯誤類。這是一個十分好的方法,用在其他地方。也有相當?shù)墓πВ?

          最后一個問題,數(shù)據(jù)庫中的中文亂碼問題。其實并不是數(shù)據(jù)庫的原因 ,因為我們在創(chuàng)建數(shù)據(jù)庫時可以指定它的編碼為utf8、gb2312或gbk等支持中文的編碼。WEB應(yīng)用讀寫數(shù)據(jù)庫時造成的亂碼,主要是由于WEB應(yīng)用使用的編碼與數(shù)據(jù)庫使用的編碼不統(tǒng)一。統(tǒng)一一下,就可以解決了!

          老方有給大家留作業(yè),今天的作業(yè)內(nèi)容較多。主要是為了練習數(shù)據(jù)庫的操作和數(shù)據(jù)庫與WEB的組合應(yīng)用。之前都是使用XML或配置文件做為偽數(shù)據(jù)庫與WEB組合練習的,從今天起用上數(shù)據(jù)庫了。雖然并不是十分興奮,但離框架和項目練習越來越近了,這讓我感覺很好!

          以前并未使用JAVA開發(fā)過項目,雖然學習JAVA對我已經(jīng)沒什么難度。但上課這些天來,有時用到IO和集合,還是讓我卡了一下。因為我并未系統(tǒng)的學習過它們,我應(yīng)該系統(tǒng)的學習一下它們了。越是學習應(yīng)該越是快樂,越學習應(yīng)該越是簡單。沒有學習基礎(chǔ)那么枯燥,就圍繞那基礎(chǔ)搞來搞去,用起來了才舒服。因為基礎(chǔ)學習好了,所以感覺應(yīng)用就簡單的。其實應(yīng)用并不簡單,即使不說基礎(chǔ),應(yīng)用中的模式與框架是相當重要的,有使用過程語言開發(fā)的同志,我想對此有很大的感想!

          我要學好項目的架構(gòu),文檔的編寫與項目管理,這在以后工作中是相當重要的。


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 甘泉县| 柞水县| 红安县| 泰和县| 马龙县| 聊城市| 庄河市| 拉孜县| 巨野县| 华池县| 渑池县| 巴林左旗| 贵州省| 余姚市| 灵川县| 苍溪县| 房产| 枣强县| 资讯 | 阿勒泰市| 长武县| 麦盖提县| 故城县| 高雄市| 乌鲁木齐市| 驻马店市| 齐河县| 布拖县| 扬州市| 施甸县| 桦川县| 山丹县| 高淳县| 定结县| 乌审旗| 礼泉县| 报价| 富锦市| 万载县| 邵东县| 比如县|