JSP 五讲

基    本    内    容

第 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>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我是攻城师

Elasticsearch如何检索数据

3498
来自专栏菩提树下的杨过

将淘宝数据包导入自己的商城系统

淘宝网有一个淘宝助理,可以方便的将淘宝店的商品资源导出成csv格式的数据包。很多商城系统为了能快速输入商品,都会要求开发者能最大限度的利用淘宝数据包直接导入产品...

2449
来自专栏个人随笔

C# 操作 access 数据库

随笔: (1)   命名空间             using System.Data.OleDb; (2)   连接字符串             priv...

2905
来自专栏CDA数据分析师

入门必学!在Python中利用Pandas库处理大数据

在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,Had...

2109
来自专栏搜云库

Spring Boot 中使用 Java API 调用 Elasticsearch

ElasticSearch 是一个高可用开源全文检索和分析组件。提供存储服务,搜索服务,大数据准实时分析等。一般用于提供一些提供复杂搜索的应用。 Elastic...

1.9K11
来自专栏大数据挖掘DT机器学习

使用Python Pandas处理亿级数据

原文:http://www.justinablog.com/archives/1357?utm_source=tuicool&utm_medium=refer...

4587
来自专栏大数据和云计算技术

索引技术简介

2.索引技术 索引是关系型数据库里的重要概念。总的来说,索引就是拿空间换时间。数据库技术和大数据技术会有一个融合的过程,除了前面讲到的B数索引、Hash索引等,...

5588
来自专栏PPV课数据科学社区

【学习】在Python中利用Pandas库处理大数据的简单介绍

在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,...

4207
来自专栏算法修养

Lucene的索引系统和搜索过程分析

前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移。因为项目整体要迁移到ASP.NET Core ...

4213
来自专栏数据小魔方

动态地理信息可视化——leaflet填充地图

这一篇是leaflet动态地图的第四篇,也是最值得推荐的一篇,这一篇涉及到热力地图填充,通过该篇内容,大家可以体会大leaflet在线地图的R借口在处理热力地图...

7364

扫码关注云+社区

领取腾讯云代金券