1. 程式人生 > >JSP + MySQL 實現部落格系統筆記

JSP + MySQL 實現部落格系統筆記

剛剛學了 JSP 和 MySQL,興致勃勃的做了一個部落格系統,現將實現要點總結如下:

一、編寫資料庫管理類,實現資料庫操作安全、便捷

如果沒有資料庫管理類,我們就需要在每個 JSP 檔案中使用多行程式碼重複的連線資料庫,繁瑣,而且不易改動,也不符合 JAVA 的封裝特性。於是,我寫了一個數據庫工具類,管理資料庫操作,程式碼如下:

   1:  package com.mzule.db;
   2:   
   3:  import java.sql.Connection;
   4:  import java.sql.DriverManager;
   5:  
import java.sql.ResultSet;
   6:  import java.sql.SQLException;
   7:   
   8:  public class DB {
   9:      private Connection cnn;
  10:   
  11:      /**
  12:       * 獲得資料庫連線
  13:       * 
  14:       */
  15:      private void getConnection() {
  16:          try {
  17:              Class.forName("com.mysql.jdbc.Driver");
  18:              cnn = DriverManager
  19:                      .getConnection("jdbc:mysql://localhost:3306/myblog?user=root&password=nevertellyou");
  20:          } catch (ClassNotFoundException e) {
  21:              e.printStackTrace();
  22:          } catch (SQLException e) {
  23:              e.printStackTrace();
  24:          }
  25:      }
  26:   
  27:      /**
  28:       * 斷開連線
  29:       * 
  30:       */
  31:      private void close() {
  32:          if (cnn != null) {
  33:              try {
  34:                  cnn.close();
  35:              } catch (SQLException e) {
  36:                  e.printStackTrace();
  37:              }
  38:          }
  39:      }
  40:   
  41:      /**
  42:       * 執行資料庫查詢
  43:       * 
  44:       * @param sql
  45:       * @return ResultSet
  46:       */
  47:      public static ResultSet executeQuery(String sql) {
  48:          DB db = new DB();
  49:          if (db.cnn == null) {
  50:              db.getConnection();
  51:          }
  52:          try {
  53:              return db.cnn.createStatement().executeQuery(sql);
  54:          } catch (SQLException e) {
  55:              e.printStackTrace();
  56:              return null;
  57:          } finally {
  58:              db.close();
  59:              db.cnn = null;
  60:          }
  61:      }
  62:   
  63:      /**
  64:       * 執行資料庫更新
  65:       * 
  66:       * @param sql
  67:       * @return -1 代表更新失敗
  68:       */
  69:      public static int executeUpdate(String sql) {
  70:          DB db = new DB();
  71:          if (db.cnn == null) {
  72:              db.getConnection();
  73:          }
  74:          try {
  75:              return db.cnn.createStatement().executeUpdate(sql);
  76:          } catch (SQLException e) {
  77:              e.printStackTrace();
  78:              return -1;
  79:          } finally {
  80:              db.close();
  81:              db.cnn = null;
  82:          }
  83:      }
  84:  }

此類中只有兩個對外公開的方法:executeQuery(String) 和 executeUpdate(String),這兩個方法都是靜態的,方便呼叫。以前是把整個類的所有方法和屬性都設定為靜態的,後來想想,這樣不妥,要不又很多個客戶訪問頁面就會共用一個 connection ,就會引發杯具。

二、設定 request.setCharacterEncoding("GBK"); 避免頁面亂碼

這個亂碼問題困擾了我很久,就是在每次釋出中文部落格得到的都是亂碼,當時以為是資料庫安裝的時候沒有設定好編碼造成的,還專門寫了一個轉碼方法:

   1:  /**轉碼,由 UTF-8 轉到 GBK
   2:   * @param str
   3:   * @return String encoding with GBK
   4:   */
   5:  public static String toGBK(String str){
   6:      try {
   7:          return new String(str.getBytes("UTF-8"),"GBK");
   8:      } catch (UnsupportedEncodingException e) {
   9:          e.printStackTrace();
  10:          return null;
  11:      }
  12:  }

後來發現在資料庫中就是可以插入中文的,自己鬱悶的好久。想起來在 Servlet 中的那句 request.setCharacterEncoding("GBK");,興奮的試試,結果還是不行,崩潰。其實這裡是我的犯低階錯誤了。 request.setCharacterEncoding("GBK"); 應該寫在第一個 request.getParameter() 的前面,我沒看到我的第一個 request.getParameter() 語句竟然在 if() 語句中,耽誤了好久。

三、MySQL 的 auto_increment

資料庫中的表一般都要求要有主鍵,方便管理,一般都選擇一個不斷增長的 id 作為主鍵,在 MySQL  中可以設定自動遞增的,就是 auto_increment ,程式碼參考如下:

   1:  CREATE TABLE mytable (
   2:  id INT PRIMARY KEY AUTO_INCREMENT,
   3:  --code omitted here
   4:  )

為了各個資料庫系統之間的相容性,我們還可以使用 JAVA 程式碼實現遞增,就是得到 id 的最大值,再加 1。或者使用靜態域,使用靜態域貌似還得固化資料。

四、避免在 URL 上面傳遞中文

網頁中經常會用這樣的情形,首先是一個文章標題為名的超級連結,點選這個超級連結會得到文章的全部內容,是使用下面類似的程式碼實現的:

   1:  <a href=<%="blogview.jsp?id=" + rs.getString("id")%>><%=rs.getString("title")%>a>

頁面傳遞的是 id  ,不是文章標題,因為 id 是主鍵,主鍵不可能重複,所以永遠只會找出一篇文章,但是如果以 title 作為引數傳遞,則可能會搜尋出所有同名文章。(⊙o⊙)…尷尬。

避免在 URL 上面傳遞中文,也是避免亂碼的一種有效方式。

五、準備好錯誤頁面

因為各種各樣的錯誤和 bugs,我們得備好錯誤頁面。因 executeUpdate() 返回 -1 的錯誤頁面則應該單獨設計。