六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

如何直接在瀏覽器內(nèi)運(yùn)行SQL命令

[摘要]本文示范了如何用一個(gè)Java Servlet、一個(gè)JSP頁(yè)面和一個(gè)靜態(tài)Java類構(gòu)造出一個(gè)SQL網(wǎng)關(guān)應(yīng)用。利用這個(gè)應(yīng)用,你可以直接在瀏覽器內(nèi)執(zhí)行SQL命令,瀏覽器將把SQL命令提交給遠(yuǎn)程服務(wù)器上的數(shù)據(jù)庫(kù)系統(tǒng),然后返回結(jié)果。   如果你正在使用ISP(Internet Service Provide...
  本文示范了如何用一個(gè)Java Servlet、一個(gè)JSP頁(yè)面和一個(gè)靜態(tài)Java類構(gòu)造出一個(gè)SQL網(wǎng)關(guān)應(yīng)用。利用這個(gè)應(yīng)用,你可以直接在瀏覽器內(nèi)執(zhí)行SQL命令,瀏覽器將把SQL命令提交給遠(yuǎn)程服務(wù)器上的數(shù)據(jù)庫(kù)系統(tǒng),然后返回結(jié)果。

  如果你正在使用ISP(Internet Service Provider)提供的數(shù)據(jù)庫(kù),可能已經(jīng)熟悉SQL網(wǎng)關(guān)應(yīng)用的概念了。有的ISP會(huì)提供一個(gè)操作數(shù)據(jù)庫(kù)的HTML頁(yè)面,就象本文提供的網(wǎng)關(guān)應(yīng)用一樣。如果ISP沒(méi)有提供這樣的界面,你可以把本文的程序上載到服務(wù)器,以后要訪問(wèn)ISP服務(wù)器上的數(shù)據(jù)庫(kù)就很方便了。

  SQL網(wǎng)關(guān)應(yīng)用不僅可以用于開(kāi)發(fā)過(guò)程,而且還可以直接提供給比較熟悉系統(tǒng)的最終用戶使用。當(dāng)然,允許最終用戶直接在數(shù)據(jù)庫(kù)上運(yùn)行SQL命令會(huì)帶來(lái)一些安全隱患,應(yīng)當(dāng)慎重考慮。

  本文要求讀者具備一定的Java、Servlet、JSP和數(shù)據(jù)庫(kù)的基礎(chǔ)知識(shí),如果要運(yùn)行本文的程序,還要有一個(gè)Servlet/JSP服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器。在下面的說(shuō)明中,我們要使用的是Tomcat 4.0和MySQL,但它應(yīng)該也能在其他JSP/Servlet容器中運(yùn)行;如果你要改用MySQL之外的其他數(shù)據(jù)庫(kù),只要提供一個(gè)適當(dāng)?shù)尿?qū)動(dòng)程序,然后修改數(shù)據(jù)庫(kù)連接字符串就可以了。

  一、用戶界面

  圖1就是本文SQL網(wǎng)關(guān)的用戶界面。在這個(gè)界面中,SQL網(wǎng)關(guān)已經(jīng)執(zhí)行了一條SQL命令并返回了結(jié)果。



圖1:SQL網(wǎng)關(guān)的用戶界面


  從圖1可以看出,頁(yè)面底部的一條信息顯示出最近執(zhí)行的SQL命令影響的行數(shù)。如果SQL命令是一個(gè)SELECT語(yǔ)句,當(dāng)SELECT語(yǔ)句執(zhí)行成功,頁(yè)面底部將用HTML表格顯示出查詢結(jié)果,如圖二所示。



圖2:HTML表格顯示出查詢結(jié)果集


  當(dāng)然,如果SQL命令執(zhí)行失敗,SQL網(wǎng)關(guān)將返回異常信息。

  二、設(shè)計(jì)JSP頁(yè)面

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

<!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 = ";%>


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

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

<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="執(zhí)行"></form>


  表單中的文本區(qū)域用來(lái)輸入SQL命令。我們將sqlStatement變量的值作為文本區(qū)域的默認(rèn)內(nèi)容,文本區(qū)域的大小是寬60字符、高8行。當(dāng)JSP頁(yè)面第一次運(yùn)行時(shí),這個(gè)文本區(qū)域的內(nèi)容為空。如果用戶點(diǎn)擊文本區(qū)域下面的“執(zhí)行”按鈕,JSP頁(yè)面把表單內(nèi)容提交給SQLGatewayServlet(稍后再詳細(xì)介紹)。

  JSP頁(yè)面底部的表格顯示出message字符串的內(nèi)容。如前所述,message的內(nèi)容是運(yùn)行SQL命令的結(jié)果。

<b>SQL命令執(zhí)行結(jié)果:</b><br><table cellpadding="5" border="1"><%=message%></table>


  三、編寫(xiě)Servlet

  SQLGatewayServlet首先導(dǎo)入java.sql包以便使用JDBC類。另外,它還要聲明一個(gè)Connection對(duì)象,以便Servlet之內(nèi)的所有方法都可以使用數(shù)據(jù)庫(kù)連接。

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


  當(dāng)Servlet引擎開(kāi)始運(yùn)行這個(gè)Servlet,Servlet的init方法就打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接:

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("找不到數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序.");    }    catch(SQLException e){        System.out.println("不能打開(kāi)數(shù)據(jù)庫(kù)連接: "                           + e.getMessage());    }}


  在這個(gè)例子中,Servlet利用一個(gè)MysQL數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序打開(kāi)murach數(shù)據(jù)庫(kù)的連接,數(shù)據(jù)庫(kù)和Servlet運(yùn)行在同一個(gè)服務(wù)器上。此外,Servlet使用MySQL的默認(rèn)用戶名字root,密碼為空。不過(guò),你可以修改這里的代碼,只要有適當(dāng)?shù)尿?qū)動(dòng)程序,就可以讓Servlet連接到任何服務(wù)器上的任何數(shù)據(jù)庫(kù)(有關(guān)MySQL數(shù)據(jù)庫(kù)的更多信息,請(qǐng)參見(jiàn)www.mysql.com)。

  Servlet引擎關(guān)閉Servlet之前,調(diào)用destroy方法關(guān)閉數(shù)據(jù)庫(kù)連接,釋放連接資源:

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


  前面介紹的JSP頁(yè)面要調(diào)用Servlet的doPost方法,doPost方法調(diào)用doGet方法:

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


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

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


  然后,在try塊之內(nèi),第一個(gè)語(yǔ)句利用Connection對(duì)象創(chuàng)建Statement對(duì)象,接下來(lái)的兩個(gè)語(yǔ)句利用String對(duì)象的trim方法和substring方法返回用戶輸入的SQL命令的前六個(gè)字符。

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


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

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


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

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


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

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


  在catch塊之后,接下來(lái)的三個(gè)語(yǔ)句獲得session對(duì)象,把sqlStatement和message變量設(shè)置為session的屬性:

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


  接下來(lái),最后兩個(gè)語(yǔ)句創(chuàng)建一個(gè)RequestDispatcher,并轉(zhuǎn)發(fā)request和response對(duì)象給前文介紹的JSP頁(yè)面:

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


  四、編寫(xiě)工具類

  下面來(lái)看看工具類SQLUtil的代碼:

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


  SQLUtil類包含一個(gè)getHtmlRows靜態(tài)方法,前面的Servlet正是通過(guò)調(diào)用該方法將結(jié)果集格式化成HTML表格。getHtmlRows的輸入?yún)?shù)是一個(gè)ResultSet對(duì)象,其返回值是一個(gè)String對(duì)象,這個(gè)String對(duì)象的內(nèi)容是記錄集的所有列表題和行的HTML代碼。為了構(gòu)造出這樣一個(gè)String對(duì)象,getHtmlRows聲明了一個(gè)名為htmlRows的StringBuffer對(duì)象,然后在方法執(zhí)行過(guò)程中向這個(gè)StringBuffer對(duì)象追加數(shù)據(jù)。在getHtmlRows方法的末尾,我們用toString方法將StringBuffer的內(nèi)容轉(zhuǎn)換成String,最后將這個(gè)String返回給Servlet:

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


  為了獲得記錄集對(duì)象的列標(biāo)題,getHtmlRows方法利用ResultSet的getMetaData方法來(lái)創(chuàng)建一個(gè)ResultSetMetaData對(duì)象,ResultSetMetaData對(duì)象包含了有關(guān)記錄集的描述信息,例如列的數(shù)量、列的名稱可以分別調(diào)用ResultSetMetaData的getColumnCount和getColumnName方法獲得。

  為了提取記錄集的數(shù)據(jù),getHtmlRows方法利用一個(gè)嵌套的循環(huán),即while循環(huán)里面嵌套的for循環(huán),來(lái)提取每一個(gè)行里面每一個(gè)列的值。在循環(huán)之內(nèi),我們用記錄集的getString方法來(lái)獲取各個(gè)字段的值,不管字段值原來(lái)的類型是什么,getString方法都會(huì)將它轉(zhuǎn)換成String。

  請(qǐng)注意這個(gè)方法的聲明中帶有synchronized關(guān)鍵詞,這是為了避免兩個(gè)或兩個(gè)以上的Servlet線程同時(shí)執(zhí)行該方法。

  下載本文的代碼:SqlGateway_code.zip。



主站蜘蛛池模板: 香蕉大成网人站在线 | 五月天天 | 在线观看午夜视频 | 日本不卡视频在线视频观看 | 欧美视频一区在线 | 香蕉app在线观看免费版 | 最新精品亚洲成a人在线观看 | 色伊人影院 | 亚洲 欧美 偷自乱 图片 | 色噜噜在线 | 亚洲国产精品久久婷婷 | 一二三四视频免费观看影视 | 视频在线观看91 | 日韩免费福利视频 | 欧美亚洲日本国产 | 亚洲国产精品线播放 | 日韩福利影院 | 天天综合天天影视色香欲俱全 | 一级女人18毛片免费 | 日韩经典视频 | 五月婷婷六月婷婷 | 亚洲欧洲一区二区三区在线观看 | 亚洲人成网站在线观看播放 | 三级在线免费观看 | 天堂网色| 色噜噜噜噜噜在线观看网站 | 在线播放精品视频 | 日韩免费高清 | 欧美在线观看黄色 | 色伊人影院 | 日韩精品一 | 亚洲三级欧美 | 五月天丁香婷婷综合 | 色婷婷伊人 | 日本porno动漫| 青草青在线视频 | 欧美视频中文字幕 | 亚洲a人 | 日本在线视频网站www色下载 | 日韩欧美国产三级 | 四虎永久在线精品影院 |