7.1 JDBC介绍
7.1.1 什么是JDBC
JDBC全称为Java DataBase Connectivity,两组分别面向应用程序开发人员和数据库驱动程序开发人员的应用程序接口 (Application Programming Interface,API),以及将前者向后者转化的内在封装逻辑
JDBC是一个面向对象的应用程序接口(API),通过它可访问各类关系数据库。JDBC也是java核心类库的一部分,由一些Java语言编写的类和界面组成。JDBC为数据库应用开发人员、数据库前台工具开发人员提供了一种标准的应用程序设计接口,使开发人员可以用纯Java语言编写完整的数据库应用程序
JDBC的功能:
(1)同一个数据库建立连接;
(2)向数据库发送SQL语句;
(3)处理数据库返回的结果。
7.1.2 JDBC的结构
7.2 通过JDBC-ODBC桥访问数据库
建议尽可能使用纯javaJDBC驱动程序代替桥和ODBC驱动程序,这样可以省云了ODBC所需的客户机配置,也免除了java虚拟机被桥引入的本地代码
7.3 通过JDBC驱动访问数据库
7.3.1 通过JDBC驱动使用MySQL数据
2.建立数据库student和表studentInfo
3.编写jsp文件访问数据库(accessMYSQL.JSP)
<%--
Document : accessMySql.jsp
Created on : 2010-3-31, 11:02:08
Author : zzf
--%>
<%@page contentType="text/html" pageEncoding="UTF-8" import= "java.sql.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>通过MySQL的JDBC驱动访问数据库</title>
</head>
<body>
<table border="1" bgcolor="#ccceee" align="center">
<tr>
<th width="87" align="center">学号</th>
<th width="87" align="center">姓名</th>
<th width="87" align="center">年龄</th>
<th width="87" align="center">专业</th>
</tr>
<%
Class.forName("com.mysql.jdbc.Driver");
//数据库URL jdbc:<subprotocol>:3306(端口)/ student (数据库名),
//”root”(数据库用户名),"99999999"(数据库密码)
Connection con= DriverManager.getConnection ("jdbc:mysql://localhost:3306/student","root","99999999");
Statement stmt=con.createStatement();
String query="SELECT * FROM studentInfo";
ResultSet rs=stmt.executeQuery(query);
while(rs.next()){
%>
<tr>
<td><%=new String(rs.getString("id").getBytes("ISO-8859-1"),"GB2312")%> </td>
<td><%=new String(rs.getString("name").getBytes("ISO-8859-1"),"GB2312")%> </td>
<td><%=new String(rs.getString("age").getBytes("ISO-8859-1"),"GB2312")%> </td>
<td><%=new String(rs.getString("class").getBytes("ISO-8859-1"),"GB2312")%> </td>
</tr>
<%}%>
<%
rs.close();
stmt.close();
con.close();
%>
</table></body></thml>
7.3.2 通过JDBC驱动使用Microsoft SQL Server数据库
1.本例使用了 SQL Server2000自带的pubs数据库,将其设置为Windows和SQL混合模式登录,用户名字为sa,密码为空
2.v建立数据库和表
3.编写jsp文件访问数据库(accessSQLServel.jsp)
<%--
Document : accessSQLServer
Created on : 2010-3-31, 16:34:28
Author : zzf
--%><%@page contentType="text/html" pageEncoding="UTF-8" import= "java.sql.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>通过SQL Server的JDBC驱动访问数据库</title>
</head>
<body>
<center>
<br> <br> <br>
<h2> 欢迎使用SQL Server的JDBC驱动访问SQL Server数据库</h2>
<hr>
<table border=2 bgcolor="ccceee" align="center">
<tr>
<td>job_id</td>
<td>job_desc</td>
<td>min_lvl</td>
<td>max_lvl</td>
</tr>
<%
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
//url,其中pubs为你选择数据库
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs";
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select top 6 * from jobs";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()){
%>
<tr>
<td><%=rs.getString("job_id")%> </td>
<td><%=rs.getString("job_desc")%> </td>
<td><%=rs.getString("min_lvl")%> </td>
<td><%=rs.getString("max_lvl")%> </td>
</tr>
<%}%>
<%
rs.close();
stmt.close();
conn.close();
%>
</table>
<hr>
</center>
</body>
</html>
7.3.3 通过JDBC驱动使用oracle数据库
7.4 查询数据库
在查询数据库中的记录时,都是通过标准的SQL语句来实现的。SQL的查询语句即SELECT语句,是SQL语言的核心,其语法格式为:
SELECT [ALL | DISTINCT] column1[,column2]
FROM table1[,table2]
[WHERE "conditions"]
[GROUP BY "column-list"]
[HAVING "conditions]
[ORDER BY "column-list" [ASC | DESC] ]
其中,column1[,column2]为要查询的列名。table1[,table2]用来指定要查询的表的名称。[WHERE “conditions”]用来指定用于限制返回的结果的搜索条件。[HAVING “conditions]用来指定组或聚合的搜索条件。 [ORDER BY ”column-list“ [ASC | DESC] ]用来指定结果集的排序。
JDBC能实现以下3个方面功能:同一个数据库建立连接、向数据库发送SQL语句和处理数据库返回的结果
JDBC提供了3种接口来实现SQL语句的发送执行,它们分别是Statment、PreparedStatement和CallableStatement。Statment接口的对象用于执行简单的不带参数的sql语句,PreparedStatemnet 接口的对象用于执行带有IN参数的预编译过的SQL语句,CallableStatement接口的对象用于执行一个数据库的存储过程。PreparedStatement继承了Statement,而callableStatement又从PreparedStatement继承来的
1.Statement类
方法1:Statement createStatement()throws SQLException
方法2:Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException
其中resultSetType参数有两个取值:
1)ResultSet.TYPE_SCROLL_INSENSITIVE 游标上下滚动,数据库变化时,当前结果集不变。
2)ResultSet.TYPE_SCROLL_SENSITIVE 游标上下滚动,数据库变化时,结果集随之变动。
resultSetConcurrency用来指定是否可以使用结果集更新数据库,它也有两个取值:
1)ResultSet.CONCUR_READ_ONLY:结果集不能被更新
2)ResultSet.CONCUR_UPDATABLE: 结果集可以更新
statement对象的一些常用方法如表7-1
方法 说明 方法 说明 executeQuery() 用来执行查询 getMaxRow() 获取结果集的最多行数 executeUpdate() 用来执行更新 setQueryTimeOut() 设置一个语句的等待时间 execute() 用来执行动态的未知操作 getQueryTimeOut() 获取一个语句执行的等待时间 setMaxRow() 设置结果集容纳的最多行数 close() 关闭Statement对象,释放其资源 2.PreparedStatement类
PreparedStatement类可以将SQL语句传给数据库做预编译处理,即在执行的SQL语句中包含一个或多个IN参数,可以通过设置IN参数值多次执行SQL语句,不必重新给出SQL 语句,这样可以大大提高执行SQL语句的速度。
所谓IN参数就是指那些在SQL语句创立时尚未指定值的参数,在SQL语句中IN参数用“?”号代替。例如:
PreparedStatement pstmt=connection.preparedStatement("SELECT * FROM student WHERE年龄>=? AND性别=? ");
这个PreparedStatement对象用来查查询表中指定条件的信息,在执行查询之前必须对每个IN参数进行设置,设置In参数的语法格式如下:
pstmt.setXXX(position,value);postion为IN参数在SQL语句中的位置,value指该参数被设置的值。例如
pstmt.setInt(1,20);
【例7-1】利用PreparedStatement对象查询作者表信息(PreparedStatementSQL.jsp
<%@page contentType="text/html" pageEncoding="UTF-8" import= "java.sql.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>PreparedStatement类的使用</title>
</head>
<body>
<br><br>
<center>
<h2>PreparedStatement类使用(访问SQL Server)</h2>
</center>
<hr>
<table border=2 bgcolor="ccceee" align="center">
<tr>
<td>job_id</td>
<td>job_desc</td>
<td>min_lvl</td>
<td>max_lvl</td>
</tr>
<%
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs";
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
String sql="select * from jobs where min_lvl>=? and max_lvl<=?";
PreparedStatement stmt=conn.prepareStatement(sql);
stmt.setInt(1,160);
stmt.setInt(2,300);
ResultSet rs=stmt.executeQuery();
while(rs.next()){
%>
<tr>
<td><%=rs.getString("job_id")%> </td>
<td><%=rs.getString("job_desc")%> </td>
<td><%=rs.getString("min_lvl")%> </td>
<td><%=rs.getString("max_lvl")%> </td>
</tr>
<%
}
rs.close();
stmt.close();
conn.close();
%>
</table>
<hr>
</body>
</html>3.ResultSet的方法
在结果集中进行滚动查询,常用滚动查询方法如下7-2表所示:
方法 next() 顺序查询 previous() 将记录指针向上移动,当移动到结果集第一行之前返回false beforeFirst() 将记录指针移到结果集的第一行之前 afterLast() 将记录指针移到结果集的第一行之后 first() 将记录指针移动到结果集的第一行 last() 将记录指针移动到结果集的最后一行 isAfterLast() 判断记录指针是否到达记录集的最后一行之后 isFirst() 判断记录指针是否移动到结果集的第一行 isLast() 判断记录指针是否移动到结果集的最后一行 getRow() 返回当前记录指针指身体的行号,行号从1开始,如果没有结果集返回结果为0 absolute(int row) 将记录指针移动到指定ROW行中 close() 关闭对象,并释放它的资源 例7-2ResultSet对象的游标滚动(ResultSetSQL.JSP)
<%@page contentType="text/html" pageEncoding="UTF-8" import= "java.sql.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ResultSet方法使用</title>
</head>
<body>
<center>
<br> <br> <br>
<h2> ResultSet方法使用(访问SQL Server)</h2>
<hr>
<table border=2 bgcolor="ccceee" align="center">
<tr>
<td>job_id</td>
<td>job_desc</td>
<td>min_lvl</td>
<td>max_lvl</td>
</tr>
<%
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs";
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from jobs";
ResultSet rs=stmt.executeQuery(sql);
rs.last();
int num=rs.getRow();
rs.afterLast();
while(rs.previous()){
%>
<tr>
<td><%=rs.getString("job_id")%> </td>
<td><%=rs.getString("job_desc")%> </td>
<td><%=rs.getString("min_lvl")%> </td>
<td><%=rs.getString("max_lvl")%> </td>
</tr>
<%
}
rs.close();
stmt.close();
conn.close();
%>
</table>
<hr>
</center>
</body>
</html>补充:
使用CallableStatement对象用于执行对数据库中存储过程。建立CallableStatement类对象可以通过Connection类中prepareCall()方法创建。
方法1:CallableStatement prepareCall(String sql) throws SQLException
方法2:CallableStatement prepareCall(String sql,
int resultSetType,
int resultSetConcurrency)
throws SQLException
例7-3 利用存储过程查询school数据库中学生学号、姓名、课程名和成绩
create procedure stud_degree
as
select studnet.sno,student.sname,course.cname,score.degree
from
studnet,course,score
where studnet.sno=score.sno and course.cno=score.cn
GO
(2)servetht_example4.jsp
<%@ page contentType="text/html; charset=gb2312" import="java.sql.*" %>
<HTML>
<BODY>
<CENTER>
<FONT SIZE = 4 COLOR = blue>JDBC直接访问SQL Server数据库</FONT>
</CENTER>
<HR>
<CENTER>
<%!
String driverName = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String dbURL = "jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=school";
String userName = "sa";
String userPwd = "";
Connection con;
CallableStatement callstmt;
ResultSet rs;
%>
<%
try {
Class.forName(driverName);
con = DriverManager.getConnection(dbURL, userName, userPwd);
out.print("连接成功!");
callstmt = con.prepareCall("exec stud_degree",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = callstmt.executeQuery(); //建立ResultSet(结果集)对象,并执行SQL语句
rs.last(); //移至最后一条记录
}
catch(Exception e) {
e.printStackTrace();
}
%>
<br>
数据表中共有
<FONT SIZE = 4 COLOR = red>
<!--取得最后一条记录的行数-->
<%= rs.getRow() %>
</FONT>
笔记录
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>记录条数</B></TD>
<TD><B>学号</B></TD>
<TD><B>姓名</B></TD>
<TD><B>课程名</B></TD>
<TD><B>成绩</B></TD>
</TR>
<%
rs.beforeFirst(); //移至第一条记录之前
//利用while循环配合next方法将数据表中的记录列出
while(rs.next())
{
%>
<TR ALIGN=CENTER>
<!--利用getRow方法取得记录的位置-->
<TD><B><%= rs.getRow() %></B></TD>
<TD><B><%= rs.getString("sno") %></B></TD>
<TD><B><%= rs.getString("sname") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("degree") %></B></TD>
</TR>
<%
}
rs.close();//关闭ResultSet对象
callstmt.close();//关闭Statement对象
con.close();//关闭Connection对象
%>
</TABLE>
</CENTER>
</BODY>
</HTML>
7.5 更新数据库
Statement对象调用executeUpdate()方法用于执行INSERT、DELETE和UPDATE操作。
int executeUpdate(String sql) throws SQLException方法返回值是一个整数,指示受影响的行数。对于创建表create table或删除表drop table 等不操作行的语句,executeUpdate()返回值总是0
7.5.1. 插入记录
例7-6
seventh_example6_jsp;
<%@ page contentType="text/html; charset=gb2312" import="java.sql.*" %>
<HTML>
<BODY>
<CENTER>
<FONT SIZE = 4 COLOR = blue>JDBC直接访问SQL Server数据库</FONT>
</CENTER>
<HR>
<CENTER>
<%!
String driverName = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String dbURL = "jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=school";
String userName = "sa";
String userPwd = "";
Connection con;
Statement stmt;
ResultSet rs;
%>
<%
try {
Class.forName(driverName);
con = DriverManager.getConnection(dbURL, userName, userPwd);
out.print("连接成功!");
stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT * FROM course"); //建立ResultSet(结果集)对象,并执行SQL语句
rs.last(); //移至最后一条记录
}
catch(Exception e) {
e.printStackTrace();
}
%>
<br>
插入前数据表中共有
<FONT SIZE = 4 COLOR = red>
<!--取得最后一条记录的行数-->
<%= rs.getRow() %>
</FONT>
笔记录
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>记录条数</B></TD>
<TD><B>课程号</B></TD>
<TD><B>课程名</B></TD>
<TD><B>教师号</B></TD>
</TR>
<%
rs.beforeFirst(); //移至第一条记录之前
//利用while循环配合next方法将数据表中的记录列出
while(rs.next())
{
%>
<TR ALIGN=CENTER>
<!--利用getRow方法取得记录的位置-->
<TD><B><%= rs.getRow() %></B></TD>
<TD><B><%= rs.getString("cno") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("tno") %></B></TD>
</TR>
<%
}
%>
</TABLE>
<%
try {
int count=stmt.executeUpdate("insert into course values('3-102','JSP','825')");
if( count!=0) System.out.print("影响行数"+count);
rs = stmt.executeQuery("SELECT * FROM course"); //建立ResultSet(结果集)对象,并执行SQL语句
rs.last(); //移至最后一条记录
}
catch(Exception e) {
e.printStackTrace();
}
%>
<br>
插入后数据表中共有
<FONT SIZE = 4 COLOR = red>
<!--取得最后一条记录的行数-->
<%= rs.getRow() %>
</FONT>
笔记录
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>记录条数</B></TD>
<TD><B>课程号</B></TD>
<TD><B>课程名</B></TD>
<TD><B>教师号</B></TD>
</TR>
<%
rs.beforeFirst(); //移至第一条记录之前
//利用while循环配合next方法将数据表中的记录列出
while(rs.next())
{
%>
<TR ALIGN=CENTER>
<!--利用getRow方法取得记录的位置-->
<TD><B><%= rs.getRow() %></B></TD>
<TD><B><%= rs.getString("cno") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("tno") %></B></TD>
</TR>
<%
}
%>
<%
rs.close();//关闭ResultSet对象
stmt.close();//关闭Statement对象
con.close();//关闭Connection对象
%>
</TABLE>
</CENTER>
</BODY>
</HTML>插入代码:int count=stmt.executeUpdate("insert into course values('3-102','JSP','825')");
7.5.2 更新记录
<%@ page contentType="text/html; charset=gb2312" import="java.sql.*" %>
<HTML>
<BODY>
<%!
String driverName = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String dbURL = "jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=school";
String userName = "sa";
String userPwd = “";
Connection con;
Statement stmt;
ResultSet rs;
%>
<%
try {
Class.forName(driverName);
con = DriverManager.getConnection(dbURL, userName, userPwd);
stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT * FROM course where cno='3-102'"); //建立ResultSet(结果集)对象,并执行SQL语句
rs.first();
}
catch(Exception e) {
e.printStackTrace();
}
%>
<br>
记录修改前
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>课程号</B></TD>
<TD><B>课程名</B></TD>
<TD><B>教师号</B></TD>
</TR>
<TR ALIGN=CENTER>
<TD><B><%= rs.getString("cno") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("tno") %></B></TD>
</TR>
</TABLE>
<%
try {
int count=stmt.executeUpdate("update course set cname='Servlet' where cno='3-102'");
if( count!=0) System.out.print("影响行数"+count);
rs = stmt.executeQuery("SELECT * FROM course"); //建立ResultSet(结果集)对象,并执行SQL语句
}
catch(Exception e) {
e.printStackTrace();
}
%>
<br>
记录修改后
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>课程号</B></TD>
<TD><B>课程名</B></TD>
<TD><B>教师号</B></TD>
</TR>
<%rs.first();%>
<TR ALIGN=CENTER>
<TD><B><%= rs.getString("cno") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("tno") %></B></TD>
</TR>
</TABLE>
<%
rs.close();//关闭ResultSet对象
stmt.close();//关闭Statement对象
con.close();//关闭Connection对象
%>
</TABLE>
</CENTER>
</BODY>
</HTML>更新记录代码如下:
int count=stmt.executeUpdate("update course set cname='Servlet' where cno='3-102'");
7.5.3 删除记录
seventh_example8.jsp
<%@ page contentType="text/html; charset=gb2312" import="java.sql.*" %>
<HTML>
<BODY>
<%!
String driverName = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String dbURL = "jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=school";
String userName = "sa";
String userPwd = "&&#@&&";
Connection con;
Statement stmt;
ResultSet rs;
int count;
%>
<%
try {
Class.forName(driverName);
con = DriverManager.getConnection(dbURL, userName, userPwd);
stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT * FROM course where cno='3-102'"); //建立ResultSet(结果集)对象,并执行SQL语句
rs.first();
}
catch(Exception e) {
e.printStackTrace();
}
%>记录删除前
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>课程号</B></TD>
<TD><B>课程名</B></TD>
<TD><B>教师号</B></TD>
</TR>
<TR ALIGN=CENTER>
<TD><B><%= rs.getString("cno") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("tno") %></B></TD>
</TR>
</TABLE>
<%
try {
count=stmt.executeUpdate("delete from course where cno='3-102'");
rs = stmt.executeQuery("SELECT * FROM course where cno='3-102'"); //建立ResultSet(结果集)对象,并执行SQL语句
}
catch(Exception e) {
e.printStackTrace();
}
%>
<br>
记录删除后
<br>
<%if(count!=0) out.print("不存在cno='3-102'的记录");%>
<br>
<TABLE border=1 bordercolor="#FF0000" bgcolor=#EFEFEF WIDTH=400>
<TR bgcolor=CCCCCC ALIGN=CENTER>
<TD><B>课程号</B></TD>
<TD><B>课程名</B></TD>
<TD><B>教师号</B></TD>
</TR>
<%while(rs.next()){ %>
<TR ALIGN=CENTER>
<TD><B><%= rs.getString("cno") %></B></TD>
<TD><B><%= rs.getString("cname") %></B></TD>
<TD><B><%= rs.getString("tno") %></B></TD>
</TR>
<%} %>
</TABLE>
<%
rs.close();//关闭ResultSet对象
stmt.close();//关闭Statement对象
con.close();//关闭Connection对象
%>
</BODY>
</HTML>
7.6 JSP在数据库应用中的相关问题
7.6.1 jsp的分页浏览问题
假设总记录为intRowCount,每页显示记录的数量为intPageSize,总页数为intPageCount,那么总页数的计算公式如下:
如果(intRowCount%intPageSize)>0 则intPageCount=intRowCount/intPageSize+1.
如果(intPageCount=intRowCount/intPageSize)=0则intPageCount=intRowCount/intPageSize.翻页后显示第intPage页的内容,将
记录指针移到(intPage-1)*intPageSize+1.
<%@ page contentType="text/html; charset=gb2312" import="java.sql.*" %>
<html>
<head>
<style type="text/css">
<!--
.style1 {
font-size: 24px;
color: #3300FF;
}
-->
</style>
</head>
<body>
<div align="center"><span class="style1">分页显示记录</span><BR>
</div>
<BR>
<table border=2 bordercolor="#FF0000" align="center">
<tr>
<td>sno</td>
<td>sname</td>
<td>ssex</td>
<td>sbirthday</td>
<td>sage</td>
</tr>
<% Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=school";
//school为你的数据库
String user="sa";
String password="&&#@&&";
Connection conn= DriverManager.getConnection(url,user,password);
int intPageSize; //一页显示的记录数
int intRowCount; //记录总数
int intPageCount; //总页数
int intPage; //待显示页码
java.lang.String strPage;
int i;
intPageSize = 2; //设置一页显示的记录数
strPage = request.getParameter("page"); //取得待显示页码
if(strPage==null){
//表明在QueryString中没有page这一个参数,此时显示第一页数据
intPage = 1;
} else{
//将字符串转换成整型
intPage = java.lang.Integer.parseInt(strPage);
if(intPage<1) intPage = 1;
}
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from student";
ResultSet rs=stmt.executeQuery(sql);
rs.last(); //光标指向查询结果集中最后一条记录
intRowCount = rs.getRow(); //获取记录总数
intPageCount = (intRowCount+intPageSize-1) / intPageSize; //记算总页数
if(intPage>intPageCount)
intPage = intPageCount;//调整待显示的页码
if(intPageCount>0)
{
rs.absolute((intPage-1) * intPageSize + 1); //将记录指针定位到待显示页的第一条记录上
//显示数据
i = 0;
while(i<intPageSize && !rs.isAfterLast()) {%>
<tr>
<td><%=rs.getString("sno")%> </td>
<td><%=rs.getString("sname")%> </td>
<td><%=rs.getString("ssex")%> </td>
<td><%=rs.getDate("sbirthday")%> </td>
<td><%=rs.getInt("sage")%> </td>
</tr>
<% rs.next();
i++;
}
}
%>
</table>
<hr color="#999999" >
<div align="center">第<%=intPage%>页 共<%=intPageCount%>页
<%if(intPage<intPageCount){%>
<a href="seventh_example9.jsp?page=<%=intPage+1%>">下一页</a>
<%}%>
<%if(intPage>1){%>
<a href="seventh_example9.jsp?page=<%=intPage-1%>">上一页</a>
<%}%>
<%rs.close();
stmt.close();
conn.close();
%>
</div>
</body>
</html>补充
7-10seventh_example10.jsp:(第二种方法)
1)首先开发一个页面控制的JavaBean.
package com;
import java.util.Vector;
public class PageBean {
public int curPage;//当前是第几页
public int maxPage;//一共有多少页
public int maxRowCount;//一共有多少行
public int rowsPerPage=2;//每页多少行
public Vector data;//本页中要显示资料
public PageBean()
{
}
public void countMaxPage(){//根据总行数计算总页数
if(this.maxRowCount%this.rowsPerPage==0){
this.maxPage=this.maxRowCount/this.rowsPerPage;
}
else{
this.maxPage=this.maxRowCount/this.rowsPerPage+1;
}
}public Vector getResult()
{
return this.data;
}
public PageBean(ContactBean contact)throws Exception
{
this.maxRowCount=contact.getAvailableCount();//得到总行数
this.data=contact.getResult();//得到要显示于本页的资料
this.countMaxPage();
}
}2)ContactBean是一个特定业务务相关的javaBean,它操作数据库,返回相关的结果
package com;
import java.sql.*;
import java.util.Vector;
public class ContactBean {
Connection conn;
Vector v;public ContactBean() throws Exception
{ Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=school";
// school为你的数据库
String user="sa";
String password="&&#@&&";
conn= DriverManager.getConnection(url,user,password);
v=new Vector();
}
public int getAvailableCount() throws Exception//返回要查询记录数
{int ret=0;
Statement stmt=conn.createStatement();
String strSql="select count(*) from student";
ResultSet rset=stmt.executeQuery(strSql);
while(rset.next())
{
ret=rset.getInt(1);
}
return ret;
}
public PageBean listData(String page)throws Exception
//获取指定页面数据,并封装在PageBean中返回
{
try{
PageBean pageBean=new PageBean(this);
int pageNum=Integer.parseInt(page);
Statement stmt=conn.createStatement();
String strSql="select top "+pageNum*pageBean.rowsPerPage+"* from student order by sno";
ResultSet rset=stmt.executeQuery(strSql);
int i=0;
while(rset.next())
{
if(i>(pageNum-1)*pageBean.rowsPerPage-1)
{
Object[]obj=new Object[5];
obj[0]=rset.getString("sno");
obj[1]=rset.getString("sname");
obj[2]=rset.getString("ssex");
obj[3]=rset.getDate("sbirthday");
obj[4]=rset.getInt("sage");
v.add(obj);
}
i++;
}
rset.close();
stmt.close();
pageBean.curPage=pageNum;
pageBean.data=v;
return pageBean;
}
catch(Exception e)
{
e.printStackTrace();
throw e;
}
}
public Vector getResult()throws Exception
{
return v;
}}
3.如何使用控制页面控制javaBean呢?需要一个Servlet(ContactServlet.java),用于接收客户端的请求,调用ContactBean的listData()方法,并且获得PageBean对象,把它保存在request对象中
package com;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class ContactServlet extends HttpServlet {
public ContactServlet() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {response.setContentType("text/html");
try{
ContactBean contact=new ContactBean();
PageBean pageCtl=contact.listData((String)request.getParameter("jumpPage"));
request.setAttribute("pageCtl",pageCtl);//把PageBean保存在request中
}
catch(Exception e)
{
e.printStackTrace();
}
RequestDispatcher dis=request.getRequestDispatcher("/seventh_example10.jsp");
dis.forward(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {doGet(request,response);
}
public void init() throws ServletException {
}}
ContactServlet执行过程如下:获得要显示的页面代码,ContactBean对象使用页面代码为参数调用ContactBean的listData方法。从ContactBean获得一个PageBean物件,把PageBean对象设置为request属姓,把视图派发到目的页面seventh_example10.jsp
(4)seventh_example10.jsp:
<%@ page language="java" import="java.util.*,com.PageBean" pageEncoding="GBK"%>
<jsp:useBean id="pageCtl" class="com.PageBean" scope="request"/>
<script language="JavaScript">function Jumping()
{
//document.write(document.PageForm.jumpPage.value);
document.PageForm.submit();
return;
}
function gotoPage(pagenum){
document.PageForm.jumpPage.value=pagenum;
//document.write(document.PageForm.jumpPage.value);
document.PageForm.submit();
return;
}
</script>
<table border=1>
<tr>
<td align="center" width="95">sno</td>
<td align="center" width="95">sname</td>
<td align="center" width="95">ssex</td>
<td align="center" width="95">sbirthday</td>
<td align="center" width="95">sage</td>
</tr>
<%
//pageCtl=(PageBean)request.getAttribute("pageCtl");
Vector v=pageCtl.getResult();
Enumeration e=v.elements();
while(e.hasMoreElements())
{Object[]obj=(Object[])e.nextElement();
%>
<tr>
<td align="center" width="95"><%=obj[0]%></td>
<td align="center" width="95"><%=obj[1]%></td>
<td align="center" width="95"><%=obj[2]%></td>
<td align="center" width="95"><%=obj[3]%></td>
<td align="center" width="95"><%=obj[4]%></td>
</tr>
<%}%>
</table><%if(pageCtl.maxPage!=1) {%>
<form name="PageForm" action="/jsp7/CS" method="post">每页<%=pageCtl.rowsPerPage %>行
共<%=pageCtl.maxRowCount %>行
第<%=pageCtl.curPage %>页
共<%=pageCtl.maxPage%>页
<br>
<%if(pageCtl.curPage==1){out.print("首页 上一页"); }else{%>
<a href="javascript:gotoPage(1)">首页</a>
<a href="javascript:gotoPage(<%=pageCtl.curPage-1%>)">上一页</a>
<%}%>
<%if(pageCtl.curPage==pageCtl.maxPage){out.print("下一页 尾页"); }else{%>
<a href="javascript:gotoPage(<%=pageCtl.curPage+1%>)">下一页</a>
<a href="javascript:gotoPage(<%=pageCtl.maxPage%>)">尾页</a>
<%}%>
转到<select name="jumpPage" onchange="Jumping()">
<%for(int i=1;i<=pageCtl.maxPage;i++)
{
if(i==pageCtl.curPage){
%>
<option selected value=<%=i%>><%=i %></option>
<%}else{ %>
<option value=<%=i%>><%=i %></option>
<%}} %>
</select>页
</form>
<%} %>
7.7 JSP数据库应用实例