本文示范了如何用一个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对象提取两个属性: <% 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)和一个“执行”按钮。 表单中的文本区域用来输入SQL命令。我们将sqlStatement变量的值作为文本区域的默认内容,文本区域的大小是宽60字符、高8行。当JSP页面第一次运行时,这个文本区域的内容为空。如果用户点击文本区域下面的“执行”按钮,JSP页面把表单内容提交给SQLGatewayServlet(稍后再详细介绍)。 JSP页面底部的表格显示出message字符串的内容。如前所述,message的内容是运行SQL命令的结果。 SQL命令执行结果: 三、编写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 = " |
" + "命令执行成功." + " |
" + "SQL命令执行成功。 " + "已更改" + i + " 行。" + " |
执行SQL命令时遇到错误: " + e.getMessage() + " |
" + metaData.getColumnName(i) + " | ");
" + results.getString(i) + " | ");
|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )
GMT+8, 2024-9-29 13:28 , Processed in 0.215320 second(s), 12 queries , Gzip On, MemCache On.
Powered by Discuz! X3.5
© 2001-2023 Discuz! Team.