<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    konhon

    忘掉過去,展望未來。找回自我,超越自我。
    逃避不一定躲的過, 面對不一定最難過, 孤單不一定不快樂, 得到不一定能長久, 失去不一定不再擁有, 可能因為某個理由而傷心難過, 但我卻能找個理由讓自己快樂.

    Google

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      203 Posts :: 0 Stories :: 61 Comments :: 0 Trackbacks
    本文示范了如何用一個Java Servlet、一個JSP頁面和一個靜態Java類構造出一個SQL網關應用。利用這個應用,你可以直接在瀏覽器內執行SQL命令,瀏覽器將把SQL命令提交給遠程服務器上的數據庫系統,然后返回結果。

      如果你正在使用ISP(Internet Service Provider)提供的數據庫,可能已經熟悉SQL網關應用的概念了。有的ISP會提供一個操作數據庫的HTML頁面,就象本文提供的網關應用一樣。如果ISP沒有提供這樣的界面,你可以把本文的程序上載到服務器,以后要訪問ISP服務器上的數據庫就很方便了。

      SQL網關應用不僅可以用于開發過程,而且還可以直接提供給比較熟悉系統的最終用戶使用。當然,允許最終用戶直接在數據庫上運行SQL命令會帶來一些安全隱患,應當慎重考慮。

      本文要求讀者具備一定的Java、Servlet、JSP和數據庫的基礎知識,如果要運行本文的程序,還要有一個Servlet/JSP服務器和數據庫服務器。在下面的說明中,我們要使用的是Tomcat 4.0和MySQL,但它應該也能在其他JSP/Servlet容器中運行;如果你要改用MySQL之外的其他數據庫,只要提供一個適當的驅動程序,然后修改數據庫連接字符串就可以了。

      一、用戶界面

      圖1就是本文SQL網關的用戶界面。在這個界面中,SQL網關已經執行了一條SQL命令并返回了結果。



    圖1:SQL網關的用戶界面


      從圖1可以看出,頁面底部的一條信息顯示出最近執行的SQL命令影響的行數。如果SQL命令是一個SELECT語句,當SELECT語句執行成功,頁面底部將用HTML表格顯示出查詢結果,如圖二所示。



    圖2:HTML表格顯示出查詢結果集


      當然,如果SQL命令執行失敗,SQL網關將返回異常信息。

      二、設計JSP頁面

      在JSP頁面中,我們首先放入一個Scriptlet,它的功能是從session對象提取兩個屬性:

    <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
    <% 
       String sqlStatement=(String)session.getAttribute("sqlStatement");
       if (sqlStatement == null)    sqlStatement = "";
       String message =  (String) session.getAttribute("message");
       if (message == null)  message = "";
    %>


      第一個屬性sqlStatement 表示SQL命令字符串,第二個屬性message 是包含結果信息的字符串。如果這兩個屬性的值是null,則表示它們尚未被設置,我們把sqlStatement和message變量設置成空字符串。

      JSP頁面還有一個HTML表單,HTML表單包含一個文本區域(TEXTAREA)和一個“執行”按鈕。

    <form action="../servlet/test.SQLGatewayServlet" method="post">
    <b>SQL命令:</b><br>
    <textarea name="sqlStatement" cols=60 rows=8>
    <%=sqlStatement%></textarea><br>
    <br>
    <input type="submit" value="執行">
    </form>


      表單中的文本區域用來輸入SQL命令。我們將sqlStatement變量的值作為文本區域的默認內容,文本區域的大小是寬60字符、高8行。當JSP頁面第一次運行時,這個文本區域的內容為空。如果用戶點擊文本區域下面的“執行”按鈕,JSP頁面把表單內容提交給SQLGatewayServlet(稍后再詳細介紹)。

      JSP頁面底部的表格顯示出message字符串的內容。如前所述,message的內容是運行SQL命令的結果。

    <b>SQL命令執行結果:</b><br>
    <table cellpadding="5" border="1">
    <%=message%>
    </table>


      三、編寫Servlet

      SQLGatewayServlet首先導入java.sql包以便使用JDBC類。另外,它還要聲明一個Connection對象,以便Servlet之內的所有方法都可以使用數據庫連接。

    package test;
    
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.sql.*;
    
    public class SQLGatewayServlet extends HttpServlet{
    
        private Connection connection;


      當Servlet引擎開始運行這個Servlet,Servlet的init方法就打開一個數據庫連接:

    public void init() throws ServletException{
        try{
            Class.forName("org.gjt.mm.mysql.Driver");
            String dbURL = "jdbc:mysql://localhost/murach";
            String username = "root";
            String password = "";
            connection = DriverManager.getConnection
    	(dbURL, username, password);
        }
        catch(ClassNotFoundException e){
            System.out.println("找不到數據庫驅動程序.");
        }
        catch(SQLException e){
            System.out.println("不能打開數據庫連接: "
                               + e.getMessage());
        }
    }


      在這個例子中,Servlet利用一個MysQL數據庫的驅動程序打開murach數據庫的連接,數據庫和Servlet運行在同一個服務器上。此外,Servlet使用MySQL的默認用戶名字root,密碼為空。不過,你可以修改這里的代碼,只要有適當的驅動程序,就可以讓Servlet連接到任何服務器上的任何數據庫(有關MySQL數據庫的更多信息,請參見www.mysql.com)。

      Servlet引擎關閉Servlet之前,調用destroy方法關閉數據庫連接,釋放連接資源:

    public void destroy() {
        try{
            connection.close();
        }
        catch(SQLException e){
            System.out.println("不能關閉數據庫連接: " + e.getMessage());
        }
    }


      前面介紹的JSP頁面要調用Servlet的doPost方法,doPost方法調用doGet方法:

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
                       throws IOException, ServletException{
         doGet(request, response);
     }


      在doGet方法之中,第一個語句首先獲取用戶在JSP頁面中輸入的SQL命令,第二個語句聲明message變量:

    public void doGet(HttpServletRequest request,
                       HttpServletResponse response)
                       throws IOException, ServletException{
    
         String sqlStatement = request.getParameter("sqlStatement");
         String message = "";


      然后,在try塊之內,第一個語句利用Connection對象創建Statement對象,接下來的兩個語句利用String對象的trim方法和substring方法返回用戶輸入的SQL命令的前六個字符。

    try{
         Statement statement = connection.createStatement();
         sqlStatement = sqlStatement.trim();
         String sqlType = sqlStatement.substring(0, 6);


      如果SQL命令的前六個字符是“select”,則利用Statement的executeQuery方法執行SQL語句,獲得一個ResultSet對象,把這個對象傳遞給SQLUtil類(稍后詳細說明)的getHtmlRows方法,getHtmlRows方法將把記錄集中的記錄格式化成HTML表格并返回。

    if  (sqlType.equalsIgnoreCase("select")){
         ResultSet resultSet = statement.executeQuery(sqlStatement);
         // 構造一個String,其中包含HTML表格形式的結果集數據
         message = SQLUtil.getHtmlRows(resultSet);
     }


      如果SQL語句的前六個字符不是“select”,則我們調用Statement對象的executeUpdate方法,executeUpdate方法返回當前操作影響的行數——如果這個數字是0,則該SQL命令是一個DDL命令,例如DROP TABLE或CREATE TABLE等;否則,則表明SQL命令可能是DML命令,如INSERT、UPDATE或DELETE命令。無論是哪一種SQL命令,我們都把message變量設置成相應的消息。

    else
         {
             int i = statement.executeUpdate(sqlStatement);
             if (i == 0) // 這是一個DDL命令
               message =
                 "<tr><td>" +
                   "命令執行成功." +
                 "</td></tr>";
             else // 這是一個INSERT、UPDATE或DELETE命令
                 message =
                   "<tr><td>" +
                     "SQL命令執行成功。<br>" +
                     "已更改" + i + " 行。" +
                    "</td></tr>";
         }
         statement.close();
     }


      如果try塊里面的任何一個語句拋出一個SQLException,catch塊就設置message變量,使其包含有關該SQLException的信息。例如,如果在表單中輸入的SQL命令語法錯誤,下面設置的message變量值將幫助你排解錯誤。

    catch(SQLException e){
        message = "<tr><td>執行SQL命令時遇到錯誤:<br>"
                + e.getMessage() + "</tr></td>";
    }


      在catch塊之后,接下來的三個語句獲得session對象,把sqlStatement和message變量設置為session的屬性:

    HttpSession session = request.getSession();
     session.setAttribute("message", message);
     session.setAttribute("sqlStatement", sqlStatement);


      接下來,最后兩個語句創建一個RequestDispatcher,并轉發request和response對象給前文介紹的JSP頁面:

    RequestDispatcher dispatcher =
         getServletContext().getRequestDispatcher(
             "/sql/sql_gateway.jsp");
     dispatcher.forward(request, response);


      四、編寫工具類

      下面來看看工具類SQLUtil的代碼:

    package test;
    import java.sql.*;
    public class SQLUtil{


      SQLUtil類包含一個getHtmlRows靜態方法,前面的Servlet正是通過調用該方法將結果集格式化成HTML表格。getHtmlRows的輸入參數是一個ResultSet對象,其返回值是一個String對象,這個String對象的內容是記錄集的所有列表題和行的HTML代碼。為了構造出這樣一個String對象,getHtmlRows聲明了一個名為htmlRows的StringBuffer對象,然后在方法執行過程中向這個StringBuffer對象追加數據。在getHtmlRows方法的末尾,我們用toString方法將StringBuffer的內容轉換成String,最后將這個String返回給Servlet:

    public static synchronized String getHtmlRows(ResultSet results)
    throws SQLException{
        StringBuffer htmlRows = new StringBuffer();
        ResultSetMetaData metaData = results.getMetaData();
        int columnCount = metaData.getColumnCount();
        // 將記錄集中列的名稱作為HTML表格列的標題
        htmlRows.append("<tr>");
        for (int i = 1; i <= columnCount; i++)
            htmlRows.append("<td><b>" + metaData.getColumnName(i) + "</td>");
        htmlRows.append("</tr>");
        // 對于結果集中的每一行...
        while (results.next()){
            htmlRows.append("<tr>");
            // 將該行中的每一個列轉換成一個表格單元
            for (int i = 1; i <= columnCount; i++)
                htmlRows.append("<td>" + results.getString(i) + "</td>");
        }
        htmlRows.append("</tr>");
        return htmlRows.toString();
    }


      為了獲得記錄集對象的列標題,getHtmlRows方法利用ResultSet的getMetaData方法來創建一個ResultSetMetaData對象,ResultSetMetaData對象包含了有關記錄集的描述信息,例如列的數量、列的名稱可以分別調用ResultSetMetaData的getColumnCount和getColumnName方法獲得。

      為了提取記錄集的數據,getHtmlRows方法利用一個嵌套的循環,即while循環里面嵌套的for循環,來提取每一個行里面每一個列的值。在循環之內,我們用記錄集的getString方法來獲取各個字段的值,不管字段值原來的類型是什么,getString方法都會將它轉換成String。

      請注意這個方法的聲明中帶有synchronized關鍵詞,這是為了避免兩個或兩個以上的Servlet線程同時執行該方法。
    posted on 2006-03-13 02:30 konhon 優華 閱讀(634) 評論(0)  編輯  收藏 所屬分類: JSP/Servlet
    主站蜘蛛池模板: 久久亚洲精品国产亚洲老地址| 国产亚洲精久久久久久无码| 亚洲熟女综合一区二区三区| 亚洲成a人片在线观看久| 国产99在线|亚洲| 成年美女黄网站18禁免费| 亚洲日产2021三区| 黄色a级免费网站| 亚洲精品麻豆av| 99久久精品毛片免费播放| 久久精品网站免费观看| 激情亚洲一区国产精品| 免费无码肉片在线观看| 18禁亚洲深夜福利人口| 亚洲综合久久夜AV | 国产午夜精品理论片免费观看| 国产亚洲av片在线观看播放| 国产va在线观看免费| 亚洲人成电影在线观看网| 四虎永久在线精品免费网址 | 中文字幕免费在线看线人 | 成人免费乱码大片A毛片| 亚洲不卡av不卡一区二区| 色猫咪免费人成网站在线观看| 亚洲毛片无码专区亚洲乱| 中文字幕在线免费播放| 国产亚洲精品xxx| 国产又大又粗又长免费视频 | 国产av无码专区亚洲av果冻传媒| 亚洲人成网站日本片| 在线观看免费宅男视频| 成年大片免费视频播放一级| 午夜亚洲国产理论秋霞| 成人影片麻豆国产影片免费观看| 狼色精品人妻在线视频免费| 亚洲成色在线综合网站| 免费的涩涩视频在线播放| 精品人妻系列无码人妻免费视频| 亚洲精品无码久久久久久久| 国产精品深夜福利免费观看| 中文在线观看国语高清免费|