前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JSP 五讲

JSP 五讲

作者头像
Hongten
发布2018-09-18 10:28:37
9490
发布2018-09-18 10:28:37
举报
文章被收录于专栏:Hongten

基    本    内    容

第 5 章 JSP 中使用数据库

教学目的与要求:通过本章的学习让学生了解数据源的设置过程;理解JDBC-ODBC 桥接器的工作原理,连接数据库的其他方式,查询 Excel 电子表格;掌握查询记录,更新记录,添加记录,删除记录的操作方法;并能实现分页显示记录,使用同步连接。

教学内容: 5.1 数据源                      5.2 JDBC-ODBC 桥接器 5.3 查询记录                    5.4 更新记录 5.5 添加记录                    5.6 删除记录 5.7 分页显示记录                5.8 连接数据库的其他方式 5.9 查询 Excel 电子表格         5.10 使用同步连接

教学基本要求: 了解:数据源的设置 理解:JDBC-ODBC 桥接器,连接数据库的其他方式,查询 Excel 电子表格 掌握:查询记录,更新记录,添加记录,删除记录 应用:分页显示记录,使用同步连接

教学重点教学难点: JDBC-ODBC 桥接器,查询记录,更新记录,添加记录,删除记录,分页显示记录,使用同步连接

教学方法: 教学手段:多媒体教学和计算机程序演示

教学小结: (见教学进程)

作业与思考:见课后习题

课后记载:

第5章  JSP中使用数据库 在JSP中可以使用Java的JDBC技术,实现对数据库中表记录的查询、修改和删除等操作。JDBC技术在JSP开发中占有很重要的地位。 JDBC(Java DataBase Connectivity)是Java数据库连接API。简单地说,JDBC能完成三件事: (1)  与一个数据库建立连接, (2)  向数据库发送SQL语句, (3)  处理数据库返回的结果。 JDBC在设计上和ODBC很相似。JDBC和数据库建立连接的一种常见方式是建立起一个JDBC─ODBC桥接器。由于ODBC驱动程序被广泛的使用,建立这种桥接器后,使得JDBC有能力访问几乎所有类型的数据库。JDBC也可以直接加载数据库驱动程序访问数据库,我们将在2.8节讨论。 如果使用JDBC─ODBC桥接器访问数据库,事先必须设置数据源。 5.1 数据源 假设要访问SQL Server服务器上的pubs数据库,该库有一个表students,如图5.1、5.2所示。 为连接一个SQL-Server数据库,我们需设置一个数据源。在控制面板选择ODBC数据源,如图5.3所示。 双击ODBC数据源图标。出现如图5.4所示界面,图5.4中显示了用户已有的数据源的名称。 选择“用户DSN”,点击add按钮,增加新的数据源。如图5.5所示: 为新增的数据源选择驱动程序,因为要访问SQL Server数据库,选择SQL Server,点击完成按钮(为数据源选择了驱动程序),出现设置数据源具体项目的对话框,如图5.6所示。在名称栏里为数据源起一个你自己喜欢的名字,这里我们起的名字是sun(当然,如果你喜欢的话,可以把名字叫做moon.)。这个数据源就是指某个数据库(将来随着计算机的进步,我们也可能有能力把数据源设成是一个卫星上来的信号)。在“你想连接哪个SQL Server?”栏中选择或输入一个数据库服务器,这里我们选择了网络上的另一台机器:Ping。       单击“下一步”出现图5.7画面,选择连接SQL Server 的ID。 在图5.7的对话框中,选择“使用用户输入登录标识号和密码的SQL Server验证”选项,在这里我们选择用户名为sa (不需要密码),单击“下一步”出现如图5.8所示的选择数据库的对话框。 选中“改变默认的数据库为”复选框,在下拉菜单里,我们选择用户sa有权限操作的数据库pubs。单击“下一步”出现完成数据源设置的对话框如图5.9。   在图5.9中,单击“完成”出现你所配置的数据源的信息窗口,如图5.10所示。 点击“测试数据源”按钮,如果正常就会出现数据源设置成功的窗口,如图5.11所示。               5.2 JDBC-ODBC桥接器 现在你可以这样的直观理解:我们有了一个数据源,这个数据源就是一个数据库。为了要连接到这个数据库,需要建立一个JDBC─ODBC桥接器,即加载桥接器驱动程序。   Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");   这里,Class是包java.lang中的一个类,该类通过调用它的静态方法forName就可以建立JDBC-ODBC桥接器。建立桥接器时可能发生异常,所以建立桥接器的标准是:   try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");      } catch(ClassNotFoundException e)     {} 5.3 查询记录 要查询数据库中的记录,必须和数据库建立连接,由于使用的是JDBC-ODBC方式访问数据库,那么就要与数据源建立连接。 (1)连接到数据库 首先使用包java.sql中的Connection类声明一个对象,然后再使用类DriverManager调用它的静态方法getConnection创建这个连接对象:   Connection con = DriverManager.getConnection("jdbc:odbc:数据源名字","login name", "password ");   假如您没有为数据源设置login name 和password,那么连接形式是:   Connection  con = DriverManager. getConnection("jdbc:odbc:数据源名字", "",  "");   与数据库pubs(它就是数据源sun)建立连接,格式如下:   try{ Connection  con = DriverManager. getConnection("jdbc:odbc:sun", "sa", "");    } catch(SQLException e)    {}   这样就建立了到数据库pubs的连接。 (2)向数据库发送SQL语句。 首先使用Statement声明一个SQL语句对象,然后通过刚才创建的连接数据库的对象con调用方法createStatment()创建这个SQL语句对象。   try {Statement   sql=con.createStatement();} catch(SQLException e ){}   (3)处理查询结果 有了SQL语句对象后,这个对象就可以调用相应的方法实现对数据库中表的查询和修改。并将查询结果存放在一个ResultSet类声明的对象中,也就是说SQL语句对数据库的查询操作将返回一个ResultSet对象:   ResultSet  rs=sql.executeQuery("SELECT * FROM  成绩表");   ResultSet对象是以统一形式的列组织的数据行组成。ResultSet对象一次只能看到一个数据行,使用next()方法走到下一数据行,获得一行数据后,ResultSet对象可以使用getxxxx方法获得字段值,将位置索引(第一列使用1,第二列使用2等等)或字段名传递给getxxxx方法的参数即可。 ResultSet类的若干方法 l  boolean    next() l  byte      getByte(int columnIndex) l  Date      getDate(int columnIndex) l  double    getDouble(int columnIndex) l  float     getFloat(int columnIndex) l  int       getInt(int columnIndex) l  long      getLong(int columnIndex) l  String    getString(int columnIndex) l  byte      getByte(String columnName) l  Date      getDate(String columnName) l  double    getDouble(String columnName) l  float     getFloat(String columnName) l  int       getInt(String columnName) l  long      getLong(String columnName) l  String    getString(String columnName) 5.3.1 顺序查询 使用结果集Result的next()方法,可以顺序的查询。一个结果集将游标最初定位在第一行的前面,第一次调用next()方法使游标移动到第一行。next()方法返回一个boolean型数据,当游标移动到最后一行之后返回false。 在下面的例子1中,我们查询数据库pubs(数据源sun)中students表里的包含全部字段的记录。   例子1(效果如图5.12所示) Example5_1.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <% Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try {  con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql=con.createStatement();          rs=sql.executeQuery("SELECT * FROM students");%>         <Table Border>         <TR>             <TH width=100>学号             <TH width=100姓名             <TH width=50>数学成绩            <TH width=50>英语成绩             <TH width=50>物理成绩          </TR>       <% while(rs.next())        { out.print("<TR>");              out.print("<TD >"+rs.getString(1)+"</TD>");              out.print("<TD >"+rs.getString(2)+"</TD>");              out.print("<TD >"+rs.getInt("数学成绩")+"</TD>");              out.print("<TD >"+rs.getInt("英语成绩")+"</TD>");              out.print("<TD >"+rs.getInt("物理成绩")+"</TD>");           out.print("</TR>") ;         }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {}  %> </BODY> </HTML> 在下面的例子2中查询“英语成绩”字段值大于80的记录,但只显示“姓名”字段(第2个字段)和“英语成绩”字段。 例子2(效果如图5.13所示) Example5_2.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <% Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try { con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql=con.createStatement();          rs=sql.executeQuery("SELECT * FROM students WHERE 英语成绩 >= 80 ");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"英语成绩");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");              out.print("<TD >"+rs.getString(2)+"</TD>");              out.print("<TD >"+rs.getInt("英语成绩")+"</TD>");          out.print("</TR>") ;         }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {}  %> </BODY> </HTML>   5.3.2 游动查询 前面我们学习了使用Result的next()方法顺序地查询数据,但有时候我们需要在结果集中前后移动、或显示结果集指定的一条记录等等。这时,我们必须要返回一个可滚动的结果集。为了得到一个可滚动的结果集,和上一节不同的是,我们必须使用下述方法先获得一个Statement对象:   Statement stmt=con.createStatement(ResultSet.TYPE_FORWORD_ONLY ,int concurrency);   然后,根据参数的type、concurrency的取值情况,stmt返回相应类型的结果集:   ResultSet  re=stmt.executeQuery(SQL语句);   type的取值决定滚动方式,取值可以是: l  ResultSet.TYPE_FORWORD_ONLY :结果集的游标只能向下滚动。 l  ResultSet.TYPE_SCROLL_INSENSITIVE :结果集的游标可以上下移动,当数据库变化时,当前结果集不变。 l  ResultSet.TYPE_SCROLL_SENSITIVE :返回可滚动的结果集,当数据库变化时,当前结果集同步改变。 Concurrency 取值决定是否可以用结果集更新数据库,Concurrency取值: l  ResultSet.CONCUR_READ_ONLY:不能用结果集更新数据库中的表。 l  ResultSet.CONCUR_UPDATETABLE:能用结果集更新数据库中的表。 滚动查询经常用到ResultSet的下述方法: l   public boolean previous():将游标向上移动,该方法返回boolean型数据,当移到结果集第一行之前时返回false. l   public void beforeFirst:将游标移动到结果集的初始位置,即在第一行之前。 l   public void afterLast():将游标移到结果集最后一行之后。 l   public void first():将游标移到结果集的第一行。 l   public void last():将游标移到结果集的最后一行。 l   public boolean isAfterLast():判断游标是否在最后一行之后。 l   public boolean isBeforeFirst():判断游标是否在第一行之前 l   public boolean ifFirst():判断游标是否指向结果集的第一行。 l   public boolean isLast():判断游标是否指向结果集的最后一行。 l   public int getRow():得到当前游标所指行的行号,行号从1开始,如果结果集没有行,返回0 l   public boolean absolute(int row):将游标移到参数row指定的行号。 注意,如果row取负值,就是倒数的行数,absolute(-1)表示移到最后一行,absolute(-2)表示移到倒数第2行。当移动到第一行前面或最后一行的后面时,该方法返回false。 在下面的例子中,首先将游标移动到最后一行,然后再获取行号,这样就获得表中的记录数目。然后我们倒序输出结果集中的记录,即首先输出最后一行。最后单独输出第5条记录。 例子3(效果如图5.14所示) Example5_3.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <% String name,number;     int math,physics,english;     Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try{ con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql= con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);         //返回可滚动的结果集:          rs=sql.executeQuery("SELECT * FROM students");         //将游标移动到最后一行:             rs.last();         //获取最后一行的行号:           int lownumber=rs.getRow();          out.print("该表共有"+lownumber+"条记录");          out.print("<BR>现在逆序输出记录:");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");        out.print("</TR>");        //为了逆序输出记录,需将游标移动到最后一行之后:         rs.afterLast();         while(rs.previous())         { out.print("<TR>");              number=rs.getString(1);              out.print("<TD >"+number+"</TD>");              name=rs.getString(2);              out.print("<TD >"+name+"</TD>");              math=rs.getInt("数学成绩");              out.print("<TD >"+math+"</TD>");              english=rs.getInt("英语成绩");              out.print("<TD >"+english+"</TD>");              physics=rs.getInt("物理成绩");              out.print("<TD >"+physics+"</TD>");            out.print("</TR>") ;                   }        out.print("</Table>");        out.print("单独输出第5条记录<BR>");         rs.absolute(5);              number=rs.getString(1);              out.print(number+",");              name=rs.getString(2);              out.print(name+",");              math=rs.getInt("数学成绩");              out.print(math+",");              english=rs.getInt("英语成绩");              out.print(english+",");              physics=rs.getInt("物理成绩");              out.print(physics+"。");         con.close();      }    catch(SQLException e1) {}  %> </BODY> </HTML> 5.3.3 随机查询 在下面的例子中,我们随机从结果集中取出4条记录,并计算4条记录的数学成绩的平均值。用Math类的静态方法random()可以产生一个大于0小于1的随机数,再用下述公式:   int i=(int)(Math.random()*number+1);   产生一个1到number之间的随机数,根据这个随机数将游标移动到相应的行,并输出该行,算法的进一步细节可见下述例子4。   例子4(效果如图5.15所示) Example5_4.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <% String xuehao,name;     int math;     Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try { con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql= con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);         //返回可滚动的结果集:          rs=sql.executeQuery("SELECT * FROM students");          out.print("<Table Border>");          out.print("<TR>");              out.print("<TH width=100>"+"学号");              out.print("<TH width=100>"+"姓名");              out.print("<TH width=50>"+"数学成绩");          out.print("</TR>");         //将游标移动到最后一行:             rs.last();         //获取最后一行的行号:           int lownumber=rs.getRow();         //获取记录数:         int number=lownumber;         double sum=0;         int 抽取数目=4;         int old_i[]={0,0,0,0};         int k=抽取数目;         int j=0;            while(抽取数目>0)                 {int i=(int)(Math.random()*number+1);//随机获取一个1到number之间的数。                  boolean boo=false;                  for(int m=0;m<old_i.length;m++)   //查找该行是否已被取出。                       {if(i==old_i[m])                        boo=true;                       }                  if(boo)  continue;   //假如该行已被取出,结束本次循环,继续产生随机数。                  rs.absolute(i);                   //游标移到这一行。                  out.print("<TR>");                  xuehao=rs.getString(1);           //获取该行学号字段的值。                  out.print("<TD >"+xuehao+"</TD>");                  name=rs.getString(2);              //获取该行姓名字段的值。                  out.print("<TD >"+name+"</TD>");                  math=rs.getInt("数学成绩");        //获取改行数学成绩字段的值。                  out.print("<TD >"+math+"</TD>");                  out.print("</TR>") ;                  sum=sum+math;                                   抽取数目--;                  old_i[j]=i;        //记录已取出的行号。                  j++;                      }          out.print("</Table>");          out.print("平均成绩是:"+sum/k);          con.close();      }    catch(SQLException e1) {}  %> </BODY> </HTML> 5.3.4 参数查询 在下面的例子中,客户通过Example5_5.jsp页面输入查询条件,如按姓名查询成绩或按分数段查询学生成绩等等。输入姓名提交给byname.jsp页面,输入分数段提交给byscore.jsp页面。   例子5(效果如图5.16、5.17、5.18所示) Example5_5.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <Font size=1> <FORM action="byname.jsp" Method="post">  <P>成绩查询  <P>输入姓名:   <Input type=text name="name">   <Input type=submit name="g" value="提交"> </Form> <FORM action="byscore.jsp" Method="post" >  <P>根据分数查询名单:<BR>  英语分数在 <Input type=text name="englishmin" value=0>   和  <Input type=text name="englishmax" value=100>   之间  <BR> 数学分数在 <Input type=text name="mathmin" value=0>   和  <Input type=text name="mathmax" value=100>   之间   <BR>  <Input type=submit  value="提交"> </Form> </BODY> </HTML>   bynename.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>   <% //获取提交的姓名:     String name=request.getParameter("name");           if(name==null)             {name="";             }      byte b[]=name.getBytes("ISO-8859-1");      name=new String(b);     Connection con=null;     Statement sql=null;     ResultSet rs=null;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");           }        catch(ClassNotFoundException e){}        try { con=DriverManager.getConnection("jdbc:odbc:sun","sa","");              sql=con.createStatement();              String condition="SELECT * FROM students WHERE 姓名 = "+"'"+name+"'";              rs=sql.executeQuery(condition);          out.print("<Table Border>");               out.print("<TR>");               out.print("<TH width=100>"+"学号");               out.print("<TH width=100>"+"姓名");               out.print("<TH width=50>"+"数学成绩");               out.print("<TH width=50>"+"英语成绩");               out.print("<TH width=50>"+"物理成绩");               out.print("</TR>");               while(rs.next())                    { out.print("<TR>");                      out.print("<TD >"+rs.getString(1)+"</TD>");                      out.print("<TD >"+rs.getString(2)+"</TD>");                      out.print("<TD >"+rs.getInt("数学成绩")+"</TD>");                      out.print("<TD >"+rs.getInt("英语成绩")+"</TD>");                      out.print("<TD >"+rs.getInt("物理成绩")+"</TD>");                        out.print("</TR>") ;                      }               out.print("</Table>");               con.close();            }     catch(SQLException e)            {  } %> </BODY> </HTML>   byscore.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>   <% //获取提交的分数的最大值和最小值:     String englishmax=request.getParameter("englishmax");           if(englishmax==null)             {englishmax="100";             }     String englishmin=request.getParameter("englishmin");           if(englishmin==null)             {englishmin="0";             }     String mathmax=request.getParameter("mathmax");           if(mathmax==null)             {mathmax="100";             }     String mathmin=request.getParameter("mathmin");           if(mathmin==null)             {mathmin="0";             }     Connection con=null;     Statement sql=null;     ResultSet rs=null;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");           }        catch(ClassNotFoundException e){}        try       {    con=DriverManager.getConnection("jdbc:odbc:sun","sa","");            sql=con.createStatement();            String eCondition="英语成绩 <= "+englishmax+" AND "+"英语成绩 >= "+englishmin;            String mCondition="数学成绩 <= "+mathmax+" AND "+"数学成绩 >= "+mathmin;            String condition="SELECT * FROM students WHERE "+mCondition+" and "+eCondition;            rs=sql.executeQuery(condition);        out.print("<Table Border>");             out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");             out.print("</TR>");        while(rs.next())            { out.print("<TR>");              out.print("<TD >"+rs.getString(1)+"</TD>");              out.print("<TD >"+rs.getString(2)+"</TD>");              out.print("<TD >"+rs.getInt("数学成绩")+"</TD>");              out.print("<TD >"+rs.getInt("英语成绩")+"</TD>");              out.print("<TD >"+rs.getInt("物理成绩")+"</TD>");                out.print("</TR>") ;                      }        out.print("</Table>");       con.close();      }    catch(SQLException e)           {} %> </BODY> </HTML> 5.3.5 排序查询 可以在SQL语句中使用ORDER BY子语句,对记录排序。在下面的例子中,使用SQL语句的ORDER BY子语句查询所同学的成绩,可以选择按3科的总分从低到高排列记录、按姓氏拼音排序或英语成绩排序。 例如,按总成绩排序查询的SQL语句:   SELECT * FROM student ORDER BY 数学成绩+英语成绩+物理成绩。 例子6(效果如图5.19、5.20所示) Example5_6: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P>查询成绩: <Font size=1> <FORM action="byname1.jsp" method=post name=form>        <INPUT type="radio" name="R" value="姓名">按姓氏排序        <INPUT type="radio" name="R" value="数学成绩+英语成绩+物理成绩">按总分排序        <INPUT type="radio" name="R" value="英语成绩">按英语排序 <BR>  <Input type=submit name="g" value="提交"> </Form> </BODY> </HTML>   byname1.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>   <% //获取提交的排序方式:     String name=request.getParameter("R");           if(name==null)             {name="";}      byte b[]=name.getBytes("ISO-8859-1");      name=new String(b);     String number,xingming;     Connection con=null;     Statement sql=null;     ResultSet rs=null;     int math,english,physics;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");           }        catch(ClassNotFoundException e){}      try { con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql=con.createStatement();          String condition="SELECT * FROM students ORDER BY "+name;          rs=sql.executeQuery(condition);          out.print("<Table Border>");             out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");             out.print("<TH width=50>"+"总成绩");             out.print("</TR>");            while(rs.next())              { out.print("<TR>");                number=rs.getString(1);                out.print("<TD >"+number+"</TD>");                xingming=rs.getString(2);                out.print("<TD >"+xingming+"</TD>");                math=rs.getInt("数学成绩");                out.print("<TD >"+math+"</TD>");                english=rs.getInt("英语成绩");                out.print("<TD >"+english+"</TD>");                physics=rs.getInt("物理成绩");                out.print("<TD >"+physics+"</TD>");                int total=math+english+physics;                out.print("<TH >"+total+"</TH>");                out.print("</TR>") ;               }          out.print("</Table>");         con.close();        }     catch(SQLException e)        {  }  %> </BODY> </HTML> 5.3.6 分析结果集查询 通过分析结果集来输出记录。在下面的例子中查询所有姓王的同学的成绩,首先判断结果集中,姓氏字段的值是否是某个姓氏,然后输出全部该姓氏的同学的成绩。   例子7(效果如图5.21所示) Example5_7.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P>查询成绩: <Font size=1> <P>输入学生的姓氏: <BR> <FORM action="byname2.jsp" method=post name=form>        <INPUT type="text" name="name" value="王"> <BR>  <Input type=submit name="g" value="提交"> </Form> </BODY> </HTML> byname2.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>   <% //获取提交的姓氏:     String name=request.getParameter("name");           if(name==null)             {name="";             }      byte b[]=name.getBytes("ISO-8859-1");      name=new String(b);     String number,xingming;     Connection con=null;     Statement sql=null;     ResultSet rs=null;     int math,english,physics;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");           }        catch(ClassNotFoundException e){}        try{ con=DriverManager.getConnection("jdbc:odbc:sun","sa","");            sql=con.createStatement();            String condition="SELECT * FROM students" ;            rs=sql.executeQuery(condition);        out.print("<Table Border>");             out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");             out.print("</TR>");        while(rs.next())            { number=rs.getString(1);              xingming=rs.getString(2);              if(xingming.startsWith("王"))                { out.print("<TR>");                  out.print("<TD >"+number+"</TD>");                  out.print("<TD >"+xingming+"</TD>");                  math=rs.getInt("数学成绩");                  out.print("<TD >"+math+"</TD>");                  english=rs.getInt("英语成绩");                  out.print("<TD >"+english+"</TD>");                  physics=rs.getInt("物理成绩");                  out.print("<TD >"+physics+"</TD>");                  out.print("</TR>") ;                 }             }        out.print("</Table>");       con.close();      }     catch(SQLException e)      {  } %> </BODY> </HTML> 5.3.7 使用统配符查询 可以用SQL语句操作符LIKE进行模式般配,使用“%”代替一个或多个字符,用一个下划线“_”代替一个字符。比如,下述语句查询姓氏是“王”的记录:   rs=sql.executeQuery("SELECT * FROM students WHERE 姓名  LIKE  '王%'  ");   请将上面的例子7改为通配符查询,查询所有姓氏是王的记录。 5.4 更新记录 我们可以使用SQL语句更新记录中字段的值 Statement对象调用方法:   public int executeUpdate(String sqlStatement);   通过参数sqlStatement指定的方式实现对数据库表中记录的字段值的更新,例如,下述语句将表students中王名同学的数学字段的值更新88:   executeUpdate("UPDATE students SET 数学成绩 =  88 WHERE 姓名='王名'");   注:你可以使用一个Statement对象进行更新和查询操作,但需要注意的是,当查询语句返回结果集后,没有立即输出结果集的记录,而接着执行了更新语句,那么结果集就不能输出记录了。要想输出记录就必须重新返回结果集。   在下面的例子8中,可以更新学生的各科的成绩。在Example5_8.jsp页面提交学生的姓名以及这个学生新的成绩到newResult.jsp页面,该页面负责更新记录的字段值。   例子8(效果如图5.22、5.23所示) Example5_8.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY bgcolor=pink > <Font size=1> <FORM action="newResult.jsp" method=post> 输入要修改成绩的同学的姓名:<BR> <Input type="text" name="name"> <BR>输入新的数学成绩: <Input type="text" name="math"> <BR>输入新的英语成绩: <Input type="text" name="english"> <BR>输入新的物理成绩: <Input type="text" name="physics"> <BR><Input type="submit" name="b" value="提交更新"> <P>数据库更新前的数据记录是:  <% String name,number;     int math,physics,english;     Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try{ con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql=con.createStatement();          rs=sql.executeQuery("SELECT * FROM students");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");              number=rs.getString(1);              out.print("<TD >"+number+"</TD>");              name=rs.getString(2);              out.print("<TD >"+name+"</TD>");              math=rs.getInt("数学成绩");              out.print("<TD >"+math+"</TD>");              english=rs.getInt("英语成绩");              out.print("<TD >"+english+"</TD>");              physics=rs.getInt("物理成绩");              out.print("<TD >"+physics+"</TD>");           out.print("</TR>") ;         }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {}  %> </Font> </BODY> </HTML>     newResult.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY bgcolor=pink ><Font size=1>   <% //获取提交的姓名:     String name=request.getParameter("name");           if(name==null)             {name="";             }      byte b[]=name.getBytes("ISO-8859-1");      name=new String(b);      //获取提交的新的数学成绩:     String newMath=request.getParameter("math");           if(newMath==null)             {newMath="-100";             }     //获取提交的新的英语成绩:     String newEnglish=request.getParameter("english");           if(newEnglish==null)             {newEnglish="-100";             }      //获取提交的新的物理成绩:      String newPhysics=request.getParameter("physics");           if(newPhysics==null)             {newPhysics="-100";             }     Connection con=null;     Statement sql=null;     ResultSet rs=null;     String number,xingming;     int math,english,physics;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");           }        catch(ClassNotFoundException e){}        try {con=DriverManager.getConnection("jdbc:odbc:sun","sa","");        sql=con.createStatement();        String condition1=               "UPDATE students SET 数学成绩 = "+newMath+" WHERE 姓名="+"'"+name+"'" ,               condition2=               "UPDATE students SET 英语成绩 = "+newEnglish+" WHERE 姓名="+"'"+name+"'" ,               condition3=               "UPDATE students SET 物理成绩 = "+newPhysics+" WHERE 姓名="+"'"+name+"'" ;        //执行更新操作:        sql.executeUpdate(condition1);        sql.executeUpdate(condition2);        sql.executeUpdate(condition3);        //显示更新后的表中的记录:      %>      <P>更新后的表的记录:      <%        rs=sql.executeQuery("SELECT * FROM students");        out.print("<Table Border>");             out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");             out.print("</TR>");        while(rs.next())            {              out.print("<TR>");                  number=rs.getString(1);                  out.print("<TD >"+number+"</TD>");                  xingming=rs.getString(2);                  out.print("<TD >"+xingming+"</TD>");                  math=rs.getInt("数学成绩");                  out.print("<TD >"+math+"</TD>");                  english=rs.getInt("英语成绩");                  out.print("<TD >"+english+"</TD>");                  physics=rs.getInt("物理成绩");                  out.print("<TD >"+physics+"</TD>");             out.print("</TR>") ;            }        out.print("</Table>");       con.close();      }     catch(SQLException e)      { }  %> </FONT> </BODY> </HTML> 5.5 添加记录 我们可以使用SQL语句添加新的记录,Statement对象调用方法:   public int executeUpdate(String sqlStatement);   通过参数sqlStatement指定的方式实现向数据库表中添加新记录,例如,下述语句将向表students中添加一条新的记录:(’199911’,’美丽家’,100,99,98)。   executeUpdate("INSERT INTO students VALUES (’199911’,’美丽家’,100,99,98)");   在下面的例子9中,可以添加新的记录。在Example5_9.jsp页面提交新的记录到newDatabase.jsp页面,该页面负责添加新的记录。 注:你可以使用一个Statement对象进行添加和查询操作,但需要注意的是,当查询语句返回结果集后,没有立即输出结果集的记录,而接着执行了添加语句,那么结果集就不能输出记录了。要想输出记录就必须重新返回结果集。   例子9(效果如图5.24、5.25所示) Example5_9.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY bgcolor=pink > <Font size=1> <P>添加新的记录到数据库: <FORM action="newDatabase.jsp" method=post> 同学学号: <Input type="text" name="number"> <BR>同学姓名: <Input type="text" name="name"> <BR>数学成绩: <Input type="text" name="math"> <BR>英语成绩: <Input type="text" name="english"> <BR>物理成绩: <Input type="text" name="physics"> <BR><Input type="submit" name="b" value="提交添加"> <P>数据库添加记录前的数据记录是:  <% String name,number;     int math,physics,english;     Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try { con=DriverManager.getConnection("jdbc:odbc:moon","sa","");          sql=con.createStatement();          rs=sql.executeQuery("SELECT * FROM students");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");              number=rs.getString(1);              out.print("<TD >"+number+"</TD>");              name=rs.getString(2);              out.print("<TD >"+name+"</TD>");              math=rs.getInt("数学成绩");              out.print("<TD >"+math+"</TD>");              english=rs.getInt("英语成绩");              out.print("<TD >"+english+"</TD>");              physics=rs.getInt("物理成绩");              out.print("<TD >"+physics+"</TD>");           out.print("</TR>") ;         }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {}  %> </Font> </BODY> </HTML>   newDatabase.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY bgcolor=pink ><Font size=1>   <% //获取提交的学号:     String number=request.getParameter("number");           if(number==null)             {number="";             }      byte b[]=number.getBytes("ISO-8859-1");      number=new String(b);     //获取提交的姓名:     String name=request.getParameter("name");           if(name==null)             {name="";             }      byte c[]=name.getBytes("ISO-8859-1");      name=new String(c);      //获取提交的新的数学成绩:     String m=request.getParameter("math");           if(m==null)             {m="-100"; }     //获取提交的新的英语成绩:     String e=request.getParameter("english");           if(e==null)             {e="-100"; }      //获取提交的新的物理成绩:      String p=request.getParameter("physics");           if(p==null)             {p="-100"; }     Connection con=null;     Statement sql=null;     ResultSet rs=null;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }        catch(ClassNotFoundException event){}    try {con=DriverManager.getConnection("jdbc:odbc:moon","sa","");        sql=con.createStatement();        String condition=        "INSERT INTO students VALUES"+"("+"'"+number+"','"+name+"',"+m+","+e+","+p+")";        sql.executeUpdate(condition); //执行添加操作:        //显示添加新记录后表中的记录:      %>      <P>添加新记录后的表:      <%        rs=sql.executeQuery("SELECT * FROM students ORDER BY 学号 ");        out.print("<Table Border>");             out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");             out.print("</TR>");        while(rs.next())            {    out.print("<TR>");                 String n=rs.getString(1);                  out.print("<TD >"+n+"</TD>");                 String xingming=rs.getString(2);                  out.print("<TD >"+xingming+"</TD>");                 int  math=rs.getInt("数学成绩");                  out.print("<TD >"+math+"</TD>");                 int english=rs.getInt("英语成绩");                  out.print("<TD >"+english+"</TD>");                 int physics=rs.getInt("物理成绩");                  out.print("<TD >"+physics+"</TD>");             out.print("</TR>") ;           }        out.print("</Table>");       con.close();      }     catch(SQLException event)      { }  %> </FONT> </BODY> </HTML>   5.6 删除记录 我们可以使用SQL语句删除记录,Statement对象调用方法:   public int executeUpdate(String sqlStatement);   通过参数sqlStatement指定的方式删除数据库表中的记录,例如,下述语句将删除学号是199904的记录:   executeUpdate("DELETE  FROM students WHERE 学号 = ‘199904’ ");   在下面的例子10中,可以删除已有的记录。在Example5_10.jsp页面提交要被删除的记录的字段值到delete.jsp页面,delete.jsp页面负责删除相应的记录。   注:你可以使用一个Statement对象进行删除和查询操作,但需要注意的是,当查询语句返回结果集后,没有立即输出结果集的记录,而接着执行了删除语句,那么结果集就不能输出记录了。要想输出记录就必须重新返回结果集。 例子10(效果如图5.26、5.27所示) Example5_10.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY bgcolor=pink > <Font size=1> <P>删除记录: <FORM action="delete.jsp" method=post> 输入被删除记录的学号: <Input type="text" name="number"> <BR> <BR><Input type="submit" name="b" value="提交删除"> </FORM> <P>数据库删除前的数据记录是:  <% String name,number;     int math,physics,english;     Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try { con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql=con.createStatement();          rs=sql.executeQuery("SELECT * FROM students");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");              number=rs.getString(1);              out.print("<TD >"+number+"</TD>");              name=rs.getString(2);              out.print("<TD >"+name+"</TD>");              math=rs.getInt("数学成绩");              out.print("<TD >"+math+"</TD>");              english=rs.getInt("英语成绩");              out.print("<TD >"+english+"</TD>");              physics=rs.getInt("物理成绩");              out.print("<TD >"+physics+"</TD>");           out.print("</TR>") ;         }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {}  %> </Font> </BODY> </HTML>   delete.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY bgcolor=pink ><Font size=1>   <% //获取提交的学号:     String number=request.getParameter("number");           if(number==null)             {number="";             }      byte b[]=number.getBytes("ISO-8859-1");      number=new String(b);     Connection con=null;     Statement sql=null;     ResultSet rs=null;        try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");           }        catch(ClassNotFoundException event){}        try {con=DriverManager.getConnection("jdbc:odbc:sun","sa","");        sql=con.createStatement();        //删除操作:        String deleteAll="DELETE  FROM students WHERE 学号"+" = "+"'"+number+"'";        sql.executeUpdate(deleteAll);       %>      <P>删除记录后的表:      <%        rs=sql.executeQuery("SELECT * FROM students ORDER BY 学号 ");        out.print("<Table Border>");             out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");             out.print("</TR>");        while(rs.next())            {    out.print("<TR>");                 String n=rs.getString(1);                  out.print("<TD >"+n+"</TD>");                 String xingming=rs.getString(2);                  out.print("<TD >"+xingming+"</TD>");                 int  math=rs.getInt("数学成绩");                  out.print("<TD >"+math+"</TD>");                 int english=rs.getInt("英语成绩");                  out.print("<TD >"+english+"</TD>");                 int physics=rs.getInt("物理成绩");                  out.print("<TD >"+physics+"</TD>");             out.print("</TR>") ;           }        out.print("</Table>");       con.close();      }     catch(SQLException event)           {out.print(""+event);           }  %> </FONT> </BODY> </HTML> 5.7 分页显示记录 我们简单地实现数据库表中记录的分页显示。 假设总记录数为m,每页显示数量是n,那么总页数的计算公式是: (1)    如果m除以n的余数大于0,总页数等于m除以n的商加1; (2)    如果m除以n的余数等于0,总页数等于m除以n的商。 即   总页数=(m%n)==0?(m/n):(m/n+1);   如果准备显示第p页的内容,应当把游标移动到第(p-1)*n+1条记录处。   showByPage.jsp:(效果如图5.28所示) <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <%! int pageSize=3; //每页显示的记录数。      int pageCount=0; //分页后的总页数。  %> <%-- 客户通过表单提交欲要显示的页码数--%> <FORM action="" method=get >  输入页码数<Input Type=text name=showPage size=4 >    <Input Type=submit name=g value=提交>  </FORM> <%  Connection con;     Statement sql;     ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");        }     catch(ClassNotFoundException e){}     try { con=DriverManager.getConnection("jdbc:odbc:sun","sa","");          sql= con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);         //返回可滚动的结果集:          rs=sql.executeQuery("SELECT * FROM students");         //将游标移动到最后一行:             rs.last();         //获取最后一行的行号:          int lastRow=rs.getRow();         //计算分页后的总页数:         pageCount=(lastRow%pageSize==0)?(lastRow/pageSize):(lastRow/pageSize+1);         //当前显示的初始页数:         int showPage=1;         //告知客户总页数:       %>         <P> 共有<%=pageCount%>页         <BR>每页显示<%=pageSize%>条记录.       <% //获取客户想要显示的页数:           String integer=request.getParameter("showPage");                if(integer==null)                   { integer="1";                   }            try {showPage=Integer.parseInt(integer);                 }            catch(NumberFormatException e)                {showPage=1;                }           if(showPage<=1)              {showPage=1;              }           if(showPage>=pageCount)              {showPage=pageCount;              }       %>         <BR>目前显示第<%=showPage%>页        <% //如果要显示第showPage页,那么游标应移到posion的值是:          int posion=(showPage-1)*pageSize+1;           rs.absolute(posion); // 设置游标的位置           out.print("<Table Border>");           out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");           out.print("</TR>");        for (int i=1;i<=pageSize;i++)         { out.print("<TR>");              out.print("<TD >"+rs.getString(1)+"</TD>");              out.print("<TD >"+rs.getString(2)+"</TD>");              out.print("<TD >"+rs.getInt("数学成绩")+"</TD>");              out.print("<TD >"+rs.getInt("英语成绩")+"</TD>");             out.print("<TD >"+rs.getInt("物理成绩")+"</TD>");            out.print("</TR>") ;           rs.next();           }        out.print("</Table>");       con.close();      }    catch(SQLException e1) {}  %> </BODY> </HTML>     5.8 连接数据库的其它方式 5.8.1 连接Oracle数据库 我们也可以通过JDBC-ODBC桥接器和Oracle数据库建立连接,但这种连接的质量依赖于ODBC。下面介绍通过直接加载Oracle数据库驱动程序来连接数据库的方法。 安装Oracle后,找到目录:Oracle/ora81/jdbc中的文件:classes12.zip;将该文件拷贝到你的JDK的如下目录中: f:/jdk1.3/jre/lib/ext 并将classes.zip重新命名为classes.jre或classes.jar。 通过如下的两个步骤和一个Oracle数据库建立连接: (1)加载驱动程序:   Class.forName("oracle.jdbc.driver.OracleDriver");   (2)建立连接:   Connection conn= DriverManager.getConnection( “jdbc:oracle:thin:@主机host:端口号:数据库名”, “用户名”, “密码”); 例子11(效果如图5.29所示) Example5_11.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <% Connection con=null;     Statement sql=null;     ResultSet rs=null;     try{Class.forName("oracle.jdbc.driver.OracleDriver");        }     catch(ClassNotFoundException e){}     try       {  con= DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.35:1521:Lea","scott","tiger");          sql=con.createStatement();          rs=sql.executeQuery("select * from emp");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"EMPNO");             out.print("<TH width=50>"+"Ename");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");              int n=rs.getInt(1);              out.print("<TD >"+n+"</TD>");             String e=rs.getString(2);              out.print("<TD >"+e+"</TD>");          out.print("</TR>") ;          }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {out.print(""+e1);}  %> </BODY> </HTML> 注:如果出现无法找到OracleDriver异常,请首先检查JDK的目录:jdk/jre/lib/ext中是否有classes12.jre文件,如果有该文件,仍出现OracleDriver异常,尝试将下列路径加入环境变量 jdk/jre/lib/ext/classes.jre 5.8.2 连接MySql数据库 可以到地址:http://www.wordsercer.com/mm.mysql下载驱动程序,然后安装到某个盘,比如C:。 将下列路径加入环境变量 C:/mm.mysql.jdbc-2.0pre5。 与一个Mysal数据库建立连接有如下2步: (1)加载驱动程序:   Class.forName("org.gjt.mm.mysql.Driver").newInstance();   (2)建立连接:   Connection conn=DriverManager.getConnection(”jdbc:mysql://host:Port:数据库名”,”用户名”,”密码”); 5.9 查询Excel电子表格 有时需要查询Excel或更新删除Excel电子表格的内容,可以通过JDBC-ODBC桥接器访问Excel表格。访问Exel表格和我们访问其它的数据库有所不同,结合例子讲述如下: 假设有电子表格:goods.xls,见下图5.30。 (1)    设置数据源: 设置数据源的名字是star,为数据源选择的驱动程序是:Microsoft Excel Driver (2)    选择表: 与访问其它数据库不同的是,我们必须在电子表格中选出一工作区作为连接时使用的表。 在Excel电子表格中拖动鼠标选出范围,如下图5.31所示。然后在Excel菜单中选择插入→名称→定义,给选中的工作区命名(这一工作区的名称将作为连接时使用的表名)。如图5.32所示。 这样我们就创建了一个名字是“品名”、有3个字段的表。现在就可以在JSP中查询、更新、删除这个表中的记录了。       下面的例子12查询了“品名”表中的全部记录。 例子12(效果如图5.33所示) Example5_12.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <% Connection con;       Statement sql;       ResultSet rs;     try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");       }     catch(ClassNotFoundException e){}     try { con=DriverManager.getConnection("jdbc:odbc:star","","");          sql=con.createStatement();          rs=sql.executeQuery("SELECT * FROM 品名 ");          out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"品名");             out.print("<TH width=50>"+"单位");             out.print("<TH width=50>"+"单价");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");             String name=rs.getString(1);              out.print("<TD >"+name+"</TD>");             String  unit=rs.getString(2);              out.print("<TD >"+unit+"</TD>");             String  unitprice=rs.getString(3);             out.print("<TD >"+unitprice+"</TD>");          out.print("</TR>") ;                  }         out.print("</Table>");         con.close();      }    catch(SQLException e1) {}  %> </BODY> </HTML> 5.10 使用同步连接 数据库操作中,建立连接是耗时最大的操作之一。如果客户访问的是同一数据库,那么,为每个客户都建立一个连接是不合理的。我们已经知道,在“<%!”和“%>”之间声明的变量在整个JSP页面内都有效,因为JSP引擎将JSP页面转译成Java文件时,将这些变量作为类的成员变量。这些变量的内存空间直到服务器关闭才释放。当多个客户请求一个JSP页面时,JSP引擎为每个客户启动一个线程而不是启动一个进程,这些线程由Web服务器进程来管理,它们共享JSP页面的成员变量。在处理多线程问题时,可以将线程共享的变量放入一个synchronized块,或将修改该变量的方法用synchronized来修饰,这样,当一个客户用synchronized块或synchronized方法修改一个共享变量时,其它线程就必须等待,直到该线程执行完该方法或同步块。这样,我们可以把Connection对象作为一个成员变量被所有的客户共享,也就是说第一个访问数据库的客户负责建立连接,以后所有的客户共享这个连接,每个客户都不要关闭这个共享的连接。 例子13(效果如图5.34、5.35所示) Example5_13.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML> <BODY>  <%! //声明一个共享的连接对象:     Connection con=null;   %>  <% Statement sql=null;     ResultSet rs=null;     //第一个客户负责建立连接对象:     if(con==null)       { try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");            }            catch(ClassNotFoundException e)            {out.print(e);            }         try {con=DriverManager.getConnection("jdbc:odbc:moon","sa","");            sql=con.createStatement();            rs =sql.executeQuery("SELECT * FROM students");            out.print("i am  first");           }         catch(SQLException e)           {out.print(e);           }       }           else //其它客户通过同步块使用这个连接:       { synchronized(con)         {  try { sql=con.createStatement();                rs =sql.executeQuery("SELECT * FROM students");                out.print("i am not first");                }           catch(SQLException e)                {out.print(e);                }         }       }     try       {  out.print("<Table Border>");          out.print("<TR>");             out.print("<TH width=100>"+"学号");             out.print("<TH width=100>"+"姓名");             out.print("<TH width=50>"+"数学成绩");             out.print("<TH width=50>"+"英语成绩");             out.print("<TH width=50>"+"物理成绩");          out.print("</TR>");        while(rs.next())        { out.print("<TR>");            String  number=rs.getString(1);              out.print("<TD >"+number+"</TD>");            String  name=rs.getString(2);              out.print("<TD >"+name+"</TD>");            int  math=rs.getInt("数学成绩");              out.print("<TD >"+math+"</TD>");            int  english=rs.getInt("英语成绩");              out.print("<TD >"+english+"</TD>");            int  physics=rs.getInt("物理成绩");              out.print("<TD >"+physics+"</TD>");           out.print("</TR>") ;                  }       out.print("</Table>");     }    catch(SQLException e1) {}  %> </BODY> </HTML>

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2011-03-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档