JSP中使用数据库 (2).ppt

上传人:小飞机 文档编号:6510398 上传时间:2023-11-07 格式:PPT 页数:64 大小:394.50KB
返回 下载 相关 举报
JSP中使用数据库 (2).ppt_第1页
第1页 / 共64页
JSP中使用数据库 (2).ppt_第2页
第2页 / 共64页
JSP中使用数据库 (2).ppt_第3页
第3页 / 共64页
JSP中使用数据库 (2).ppt_第4页
第4页 / 共64页
JSP中使用数据库 (2).ppt_第5页
第5页 / 共64页
点击查看更多>>
资源描述

《JSP中使用数据库 (2).ppt》由会员分享,可在线阅读,更多相关《JSP中使用数据库 (2).ppt(64页珍藏版)》请在三一办公上搜索。

1、知识回顾:1 JDBC的工作过程2 ODBC3 连接不同数据库的方式4 数据库的顺序查询,1 其它查询 2 更新记录3 添加记录4 删除记录5 分页显示记录6 查询Excel表格7 使用同步连接8 PreparedStatement对象应用,本讲内容:,游动查询 前面我们学习了使用Result的next()方法顺序地查询数据,但有时候我们需要在结果集中前后移动、或显示结果集指定的一条记录等等。这时,我们必须要返回一个可滚动的结果集。为了得到一个可滚动的结果集,和上一节不同的是,我们必须使用下述方法先获得一个Statement对象:Statement stmt=con.createStateme

2、nt(int type,int concurrency);然后,根据参数的type、concurrency的取值情况,stmt返回相应类型的结果集:ResultSet re=stmt.executeQuery(SQL语句);,type的取值决定滚动方式,取值可以是:ResultSet.TYPE_FORWORD_ONLY:结果集的游标只能向下滚动。ResultSet.TYPE_SCROLL_INSENSITIVE:结果集的游标可以上下移动,当数据库变化时,当前结果集不变。ResultSet.TYPE_SCROLL_SENSITIVE:返回可滚动的结果集,当数据库变化时,当前结果集同步改变。Con

3、currency 取值决定是否可以用结果集更新数据库,Concurrency取值:ResultSet.CONCUR_READ_ONLY:不能用结果集更新数据库中的表。ResultSet.CONCUR_UPDATETABLE:能用结果集更新数据库中的表。,滚动查询经常用到ResultSet的下述方法:public boolean previous():将游标向上移动,该方法返回boolean型数据,当移到结果集第一行之前时返回false.public void beforeFirst:将游标移动到结果集的初始位置,即在第一行之前。public void afterLast():将游标移到结果集最

4、后一行之后。public void first():将游标移到结果集的第一行。public void last():将游标移到结果集的最后一行。public boolean isAfterLast():判断游标是否在最后一行之后。public boolean isBeforeFirst():判断游标是否在第一行之前,public boolean ifFirst():判断游标是否指向结果集的第一行。public boolean isLast():判断游标是否指向结果集的最后一行。public int getRow():得到当前游标所指行的行号,行号从1开始,如果结果集没有行,返回0 public

5、 boolean absolute(int row):将游标移到参数row指定的行号。注意,如果row取负值,就是倒数的行数,absolute(-1)表示移到最后一行,absolute(-2)表示移到倒数第2行。当移动到第一行前面或最后一行的后面时,该方法返回false。,在下面的例子中,首先将游标移动到最后一行,然后再获取行号,这样就获得表中的记录数目。然后我们倒序输出结果集中的记录,即首先输出最后一行。最后单独输出第5条记录。例子dbf_youdong.jsp:,%String name,number;int math,physics,english;Connection con;Stat

6、ement sql;ResultSet rs;,tryClass.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);/将游标移动

7、到最后一行:rs.last();/获取最后一行的行号:int lownumber=rs.getRow();,out.print(该表共有+lownumber+条记录);out.print(现在逆序输出记录:);out.print();out.print();out.print(+学号);out.print(+姓名);out.print(+数学成绩);out.print(+英语成绩);out.print(+物理成绩);out.print();/为了逆序输出记录,需将游标移动到最后一行之后:rs.afterLast();while(rs.previous()out.print();number=r

8、s.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+);out.print();out.print();out.print(单独输出第5条记录);rs.absolute(5);number=rs.getString(1);,out.print(nu

9、mber+,);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)%,随机查询 在下面的例子中,我们随机从结果集中取出4条记录,并计算4条记录的数学成绩的平均值。用Math类的静态方法random()可以产生一个大于0小于1的随机数,再用下述公式

10、:int i=(int)(Math.random()*number+1);产生一个1到number之间的随机数,根据这个随机数将游标移动到相应的行,并输出该行,算法的进一步细节可见下述例子4。,例子dbf_suiji.jsp:,%String xuehao,name;int math;Connection con;Statement sql;ResultSet rs;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException e),try con=DriverManager.getConnection(

11、jdbc:odbc:sun,sa,);sql=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);/返回可滚动的结果集:rs=sql.executeQuery(SELECT*FROM students);out.print();out.print();out.print(+学号);out.print(+姓名);out.print(+数学成绩);out.print();/将游标移动到最后一行:rs.last();,/获取最后一行的行号:int lownumber=rs.getRow();/

12、获取记录数: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;mold_i.length;m+),/查找该行是否已被取出。if(i=old_im)boo=true;if(boo)continue;/假如该行已被取出,结束本次循环,继续产生随机数。rs.absolute(i);/游标移到这一

13、行。out.print();xuehao=rs.getString(1);/获取该行学号字段的值。out.print(+xuehao+);name=rs.getString(2);/获取该行姓名字段的值。out.print(+name+);math=rs.getInt(数学成绩);,/获取改行数学成绩字段的值 out.print(+math+);out.print();sum=sum+math;抽取数目-;old_ij=i;/记录已取出的行号。j+;out.print();out.print(平均成绩是:+sum/k);con.close();catch(SQLException e1)%,更

14、新记录我们可以使用SQL语句更新记录中字段的值。Statement对象调用方法:public int executeUpdate(String sqlStatement);通过参数sqlStatement指定的方式实现对数据库表中记录的字段值的更新,例如,下述语句将表students中王名同学的数学字段的值更新88:executeUpdate(UPDATE students SET 数学成绩=88 WHERE 姓名=王名);注:你可以使用一个Statement对象进行更新和查询操作,但需要注意的是,当查询语句返回结果集后,没有立即输出结果集的记录,而接着执行了更新语句,那么结果,集就不能输出记

15、录了。要想输出记录就必须重新返回结果集。在下面的例子1中,可以更新学生的各科的成绩。在dbf_gengxin.jsp页面提交学生的学号以及这个学生新的成绩到newResult.jsp页面,该页面负责更新记录的字段值。,输入要修改成绩的同学的学号:输入新的数学成绩:输入新的英语成绩:,输入新的物理成绩:数据库更新前的数据记录是:%String name,number;int math,physics,english;Connection con;Statement sql;ResultSet rs;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);ca

16、tch(ClassNotFoundException e)try con=DriverManager.getConnection(jdbc:odbc:sun,sa,);sql=con.createStatement();,rs=sql.executeQuery(SELECT*FROM students);out.print();out.print();out.print(+学号);out.print(+姓名);out.print(+数学成绩);out.print(+英语成绩);out.print(+物理成绩);out.print();while(rs.next()out.print();num

17、ber=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+);out.print();out.print();con.close();catch(SQLException e1)%,newResult.jsp,%/获取提交的学号:String

18、number=request.getParameter(”number);if(number=null)number=;byte b=number.getBytes(ISO-8859-1);number=new String(b);,/获取提交的新的数学成绩:String newMath=request.getParameter(math);if(newMath=null)newMath=;/获取提交的新的英语成绩:String newEnglish=request.getParameter(english);if(newEnglish=null)newEnglish=;/获取提交的新的物理成

19、绩:String newPhysics=request.getParameter(physics);if(newPhysics=null)newPhysics=;,Connection con=null;Statement sql=null;ResultSet rs=null;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException e)try con=DriverManager.getConnection(jdbc:odbc:sun,sa,);sql=con.createStatement();St

20、ring condition1=“UPDATE students SET 数学成绩=”+newMath+“WHERE 学号=+number+,condition2=UPDATE students SET 英语成绩=+newEnglish+WHERE 学号=+number+,condition3=UPDATE students SET 物理成绩=+newPhysics+WHERE 学号=+number+;,/空值不操作:if(newMath.equals()condition1=;if(newPhysics.equals()condition2=;if(newEnglish.equals()co

21、ndition3=;/执行更新操作:sql.executeUpdate(condition1);sql.executeUpdate(condition2);sql.executeUpdate(condition3);/显示更新后的表中的记录:%,更新后的表的记录:);out.print();out.print(+学号);out.print(+姓名);out.print(+数学成绩);out.print(+英语成绩);out.print(+物理成绩);out.print();while(rs.next()out.print();out.print(+rs.getString(1)+);out.p

22、rint(+rs.getString(2)+);,out.print(+rs.getInt(数学成绩)+);out.print(+rs.getInt(英语成绩)+);out.print(+rs.getInt(物理成绩)+);out.print();out.print();con.close();catch(SQLException e)%,添加记录 使用SQL语句添加新的记录,Statement对象调用方法:public int executeUpdate(String sqlStatement);通过参数sqlStatement指定的方式实现向数据库表中添加新记录,例如,下述语句将向表stu

23、dents中添加一条新的记录:(199911,美丽家,100,99,98)。executeUpdate(INSERT INTO students VALUES(199911,美丽,100,99,98));例如:dbf_zengjia.jsp 注:使用Statement对象进行添加和查询操作,当查询语句返回结果集后,没有立即输出结果集的记录,而接着执行了添加语句,那么结果集就不能输出记录了。要想输出记录就必须重新返回结果集。,删除记录 使用SQL语句删除记录,Statement对象调用方法:public int executeUpdate(String sqlStatement);通过参数sql

24、Statement指定的方式删除数据库表中的记录,例如,下述语句将删除学号是199904的记录:executeUpdate(DELETE FROM students WHERE 学号=199904);例如:dbf_delete.jsp 注:使用Statement对象进行删除和查询操作,当查询语句返回结果集后,没有立即输出结果集的记录,而接着执行了删除语句,那么结果集就不能输出记录了。要想输出记录就必须重新返回结果集。,分页显示记录 简单地实现数据库表中记录的分页显示。设总记录数为m,每页显示数量是n,那么总页数的计算公式是:如果m除以n的余数大于0,总页数等于m除以n的商加1;如果m除以n的余

25、数等于0,总页数等于m除以n的商。即总页数=(m%n)=0?(m/n):(m/n+1);如果准备显示第p页的内容,应当把游标移动到第(p-1)*n+1条记录处。,dbf_fenye.jsp,输入页码数,%Connection con;Statement sql;ResultSet rs;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException e)try con=DriverManager.getConnection(jdbc:odbc:sun,sa,);sql=con.createStatement

26、(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;/告知客户总页数:%共有页 每页显示条记

27、录.%/获取客户想要显示的页数:String integer=request.getParameter(showPage);if(integer=null)integer=1;,try showPage=Integer.parseInt(integer);catch(NumberFormatException e)showPage=1;if(showPage=pageCount)showPage=pageCount;%目前显示第页%/如果要显示第showPage页,那么游标应移到posion的值是:int posion=(showPage-1)*pageSize+1;,/设置游标的位置rs.a

28、bsolute(posion);out.print();out.print();out.print(+学号);out.print(+姓名);out.print(+数学成绩);out.print(+英语成绩);out.print(+物理成绩);out.print();for(int i=1;i);out.print(+rs.getString(1)+);out.print(+rs.getString(2)+);,out.print(+rs.getInt(数学成绩)+);out.print(+rs.getInt(英语成绩)+);out.print(+rs.getInt(物理成绩)+);out.pr

29、int();rs.next();out.print();con.close();catch(SQLException e1)%,查询Excel电子表格 有时需要查询Excel或更新删除Excel电子表格的内容,可以通过JDBC-ODBC桥接器访问Excel表格。访问Exel表格和我们访问其它的数据库有所不同,结合例子讲述如下:假设有电子表格:goods.xls,见下图。,图 2 Excel表,(1)设置数据源:设置数据源的名字是star,为数据源选择的驱动程序是:Microsoft Excel Driver(2)选择表:与访问其它数据库不同的是,我们必须在电子表格中选出一工作区作为连接时使用的

30、表。在Excel电子表格中拖动鼠标选出范围,如图3所示。然后在Excel菜单中选择插入名称定义,给选中的工作区命名(这一工作区的名称将作为连接时使用的表名)。如图4所示。这样就创建了一个名字是“品名”、有3个字段的表。现在就可以在JSP中查询、更新、删除这个表中的记录了。,dbf_excel.jsp,%Connection con;Statement sql;ResultSet rs;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException e)try con=DriverManager.getCon

31、nection(jdbc:odbc:star,);sql=con.createStatement();rs=sql.executeQuery(“SELECT*FROM 品名”);,out.print();out.print();out.print(+品名);out.print(+单位);out.print(+单价);out.print();while(rs.next()out.print();String name=rs.getString(1);out.print(+name+);String unit=rs.getString(2);out.print(+unit+);String uni

32、tprice=rs.getString(3);out.print(+unitprice+);out.print();,out.print();con.close();catch(SQLException e1)%,使用同步连接 数据库操作中,建立连接是耗时最大的操作之一。如果客户访问的是同一数据库,那么,为每个客户都建立一个连接是不合理的。我们已经知道,在“”之间声明的变量在整个JSP页面内都有效,因为JSP引擎将JSP页面转译成Java文件时,将这些变量作为类的成员变量。这些变量的内存空间直到服务器关闭才释放。当多个客户请求一个JSP页面时,JSP引擎为每个客户启动一个线程而不是启动一个进程

33、,这些线程由Web服务器进程来管理,它们共享JSP页面的成员变量。,在处理多线程问题时,可以将线程共享的变量放入一个synchronized块,或将修改该变量的方法用synchronized来修饰,这样,当一个客户用synchronized块或synchronized方法修改一个共享变量时,其它线程就必须等待,直到该线程执行完该方法或同步块。这样,我们可以把Connection对象作为一个成员变量被所有的客户共享,也就是说第一个访问数据库的客户负责建立连接,以后所有的客户共享这个连接,每个客户都不要关闭这个共享的连接。,dbf_tongbu.jsp,%Statement sql=null;Re

34、sultSet rs=null;/第一个客户负责建立连接对象:if(con=null)tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);,catch(ClassNotFoundException e)out.print(e);try con=DriverManager.getConnection(jdbc:odbc:sun,sa,);sql=con.createStatement();rs=sql.executeQuery(SELECT*FROM students);out.print(i am first);catch(SQLException e

35、)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();out.print();out.print(+学号);out.print(+姓名);out.print(+数学成绩);out.print(+英语成绩);out.print(+物理成绩);out.

36、print();while(rs.next()out.print();String number=rs.getString(1);out.print(+number+);String name=rs.getString(2);out.print(+name+);,int math=rs.getInt(数学成绩);out.print(+math+);int english=rs.getInt(英语成绩);out.print(+english+);int physics=rs.getInt(物理成绩);out.print(+physics+);out.print();out.print();cat

37、ch(SQLException e1)%,PreparedStatement对象应用:Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);Connection concon=DriverManager.getConnection(jdbc:odbc:sun,sa,);PreparedStatement sp=con.prepareStatement(Update student SET 数学成绩=?where xm=?);sp.setString(1,88);sp.setString(2,张三);sp.executeUpdate();,网上投票我们创建一个A

38、ccess数据库vote.mdb,将该数据库设置为一个数据源,数据源的名字是vote。该库含有2个表“people”和“IP”,其结构如图6、图7所示:,图6 候选人表,图7 候选人的IP地址表,people表存放候选人的名字和得票数,IP表存放投票人的IP地址。投票之前,我们要把候选人的名字和初始得票数存入people表中,如图8所示:投票系统由两个页面组成:dbf_toupiao.jsp和startvote.jsp。vote.jsp按着people表中的候选人生成一个投票的表单。如图9所示:,图8 录入候选人,图9 投票选择,dbf_toupiao.jsp(效果如图9所示):,%Strin

39、gBuffer nameList=new StringBuffer();Connection con;Statement sql;ResultSet rs;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException e),try con=DriverManager.getConnection(jdbc:odbc:vote,);sql=con.createStatement();rs=sql.executeQuery(SELECT*FROM people);nameList.append();nameLi

40、st.append();nameList.append();nameList.append();nameList.append(+姓名);nameList.append(+投票选择);nameList.append();while(rs.next()nameList.append();,String name=rs.getString(1);nameList.append(+name+);String s=;nameList.append(+s+);nameList.append();nameList.append();nameList.append();nameList.append(,st

41、artvote.jsp页面获取dbf_toupiao.jsp页面提交的候选人的名字。该页面在进行投票之前,首先查询IP表,判断该用户的IP地址是否已经投过票,如果该IP地址没有投过票,就可以参加投票了,投票之后,将投票用户的IP写入数据库的IP表中;如果该IP地址已经投过票,将不允许再投票。我们通过IP地址来防止一台计算机反复的投票,但不能有效地限制拨号上网的用户,因为拨号上网的用户的IP是动态分配的,用户可以重新拨号上网获得一个新的IP地址。startvote.jsp:,%boolean vote=true;/决定用户是否有权投票的变量。/得到被选择的候选人名字:String name=;n

42、ame=request.getParameter(name);if(name=null)name=?;byte a=name.getBytes(ISO-8859-1);name=new String(a);,/得到投票人的IP地址:String IP=(String)request.getRemoteAddr();/加载桥接器:tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);catch(ClassNotFoundException e)Connection con=null;Statement sql=null;ResultSet rs=null;

43、/首先查询IP表,判断该用户的IP地址是否已经投过票:try con=DriverManager.getConnection(jdbc:odbc:vote,);sql=con.createStatement();rs=sql.executeQuery(SELECT*FROM IP WHERE IP=+IP+);int row=0;,while(rs.next()row+;if(row=1)vote=false;/不允许投票。catch(SQLException e)if(name.equals(?)out.print(您没有投票,没有权利看选举结果);else if(vote)out.prin

44、t(您投了一票);,/将总票数加1:countTotal();/通过连接数据库,给该候选人增加一票,/同时将自己的IP地址写入数据库。try rs=sql.executeQuery(SELECT*FROM people WHERE name=+name+);rs.next();int count=rs.getInt(count);count+;String condition=UPDATE people SET count=+count+WHERE name=+name+;/执行更新操作(投票计数):sql.executeUpdate(condition);,/将IP地址写入IP表:Strin

45、g to=INSERT INTO IP VALUES+(+IP+);sql.executeUpdate(to);catch(SQLException e)out.print(+e);/显示投票后的表中的记录:try rs=sql.executeQuery(SELECT*FROM people);out.print();out.print();out.print(+姓名);out.print(+得票数);out.print(+总票数:+total);,out.print();while(rs.next()out.print();out.print(+rs.getString(1)+);int count=rs.getInt(count);out.print(+count+);double b=(count*100)/total;/得票的百分比。out.print(+b+%+);out.print();out.print();con.close();catch(SQLException e),else out.print(您已经投过票了);%,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号