环境:
DB2 9.1
J2SDK 1.5
Servlet 2.4
一、问题
在web开发中,经常会遇到两级三级甚至更多级的选项框连动的情况,一般情况下都考虑用js来实现,但是在有大量等级选项的情况下,js实现也很麻烦,并且页面反应很慢,抛弃了js,我们还能用什么来做呢?
这是我在实际项目中遇到的一个问题,为了在有大量数据请况下不至于慢的无法接受,我打算用JSP/java来实现这个需求。下面我给出我做测试用的例子,以探求其可行性,是两级连动的,有数据回填功能。
作为测试,业务很简单,第一个选择况是省,第二个显示省里的市,省市分别存储在数据库中的两个表province、city(实际项目中一般都用一个表)。另外还有个静态选择框和文本况,目的是演示数据回填功能。
所谓的数据回填就是自动为客户回复填过的选项,比如你填写一个注册单,填写有错误,又返回了,在返回的时候,要把所有正确的填写项恢复回来,不必用户再从头填写。(这个回填功能用struts很容易实现,但是我面对现实是不用struts、hibernate,呵呵,因为没有复杂业务处理,主要是报表页面)。
下面是省市两个建表SQL的(DB2脚本)
drop table province;
create table province(
code varchar(10),
name varchar(10));
insert into province (code,name) values('1','河南'),
('2','陕西'),
('3','河北');
drop table city;
create table city(
code varchar(10),
name varchar(10));
insert into city (code,name) values('1','郑州'),
('1','洛阳'),
('1','许昌'),
('1','焦作'),
('1','开封'),
('2','西安'),
('2','咸阳'),
('2','宝鸡'),
('3','石家庄'),
('3','唐山');
二、实现方法
1、两级连动
在省选择框中读取所有省,当选项改变的时候触发一个js事件(onchange),将选择的省份代码和发送给自身页面,进一步显示该省下的城市选择框。
2、回填
对于文本框回填,则将请求参数记录下来。
对于静态选择框,将选择项记录下来,在再次进入页面时候利用查询,设置checked属性。
对于动态文本框,有专门的后台方法来实现。
三、实现代码
实现很简单,就两个文件,一个后台工具类,一个页面就搞定了。
1、后台工具类
package test;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.sql.DataSource;
import java.sql.*;
/**
* File Name: TestDBUitl.java
* Created by: IntelliJ IDEA.
* Copyright: Copyright (c) 2003-2006
* Date Time: 2007-3-6 14:05:42
* Readme: JSP实现多级选择框连动测试,后台工具类
*/
/**
* 数据库工具类
*/
public final class TestDBUitl {
/**
* 通过数据源获取一个JDBC链接(如果没有配置数据源,可以将此完全方法注释掉,下面直接用JDBC的方式获取数据库连接)
*
* @return 一个JDBC链接
*/
public static Connection getConnectionByJNDI() {
try {
//建立数据库连接
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/zfvds"); //tomcat数据源
//DataSource ds = (DataSource) ctx.lookup("zfvds"); //Weblogic或者WebSphere数据源
return ds.getConnection();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 直接获取JDBC链接
*
* @return 一个JDBC链接(测试用,方便)
*/
public static Connection getConnectionByJDBC() {
Connection conn = null;
try {
//装载驱动类
Class.forName("com.ibm.db2.jcc.DB2Driver");
} catch (ClassNotFoundException e) {
System.out.println("装载驱动异常!");
e.printStackTrace();
}
try {
//建立JDBC连接
conn = DriverManager.getConnection("jdbc:db2://192.168.3.8:50000/zfvims", "zfvims", "zfvimsdb2");
} catch (SQLException e) {
System.out.println("链接数据库异常!");
e.printStackTrace();
}
return conn;
}
/**
* 获取省份选项的html代码串
* @param sect 要选择的省份
* @param topage 要转向的页面
* @return 省份选项的html代码串
*/
public static String getProvinceOptions(String sect, String topage) {
String optionHTML = "";
Connection conn = getConnectionByJDBC();
Statement stmt;
ResultSet rs;
String sqlx = "select t.code,t.name from province t order by t.code asc";
try {
//创建一个JDBC声明
stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
//执行查询
rs = stmt.executeQuery(sqlx);
while (rs.next()) {
String code = rs.getString("code");
String name = rs.getString("name");
String linked = "\"" + topage + "?province=" + code + "\"";
if (sect.equals(code)) {
optionHTML = optionHTML + "<option value=\"" + code + "\"" + "\" tourl=" + linked + " selected>" + code + "-" + name + "</option>\n\t\t";
} else {
optionHTML = optionHTML + "<option value=\"" + code + "\" tourl=" + linked + ">" + code + "-" + name + "</option>\n\t\t";
}
}
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return optionHTML;
}
/**
* 获取一个省份下城市选项的html代码串
* @param pcode 省份
* @param sect 默认选中的城市代码
* @return 城市选项的html代码串
*/
public static String getCityOptions(String pcode, String sect) {
String optionHTML = "";
Connection conn = getConnectionByJDBC();
ResultSet rs;
String sqlx = "select t.code,t.name from city t where t.code = ? order by t.code asc";
try {
//开始一个事务(注意关闭事务)
conn.setAutoCommit(false);
//创建一个JDBC声明
PreparedStatement pstmt = conn.prepareStatement(sqlx, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
//设置预定义参数
pstmt.setString(1, pcode);
rs = pstmt.executeQuery();
while (rs.next()) {
String code = rs.getString("code");
String name = rs.getString("name");
if (sect.equals(code)) {
optionHTML = optionHTML + "<option value=\"" + code + "\"" + " selected>" + code + "-" + name + "</option>\n\t\t";
} else {
optionHTML = optionHTML + "<option value=\"" + code + "\">" + code + "-" + name + "</option>\n\t\t";
}
}
//提交事务
conn.commit();
//关闭连接等资源(注意先后顺序)
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
//预防性关闭连接(避免异常发生时在try语句块关闭连接没有执行)
try {
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
return optionHTML;
}
}
[1] [2] 下一页