今天给大家带来使用jQuery ajax实现的省市联动效果。我们直奔主题,先说下实现思路:
这里数据库我使用的是mysql,先看下表格:
provience表
city表
这里使用provience表的主键作为city表的外键,等下根据省份的id查找对应的市区
接下来就是实现查询所有省市以及根据省份id查找对应的城市的方法,这里我写了一个BaseDao封装了一些基本的数据库链接以及关闭连接的方法:
BaseDao.java
package com.jqueryajax.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BaseDao {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/ajax?useUnicode=true&characterEncoding=UTF-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "root";
private Connection conn;
private PreparedStatement psmt;
public ResultSet rs;
/** * 获取连接 alt+shift+z:捕获异常 */
public void getConn() {
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
/** * 释放资源 */
public void closeAll() {
try {
if (rs != null)
rs.close();
if (psmt != null)
psmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/** * 执行查询的方法 * * @param sql * :执行的SQL语句 * @param parmms * :占位符的值 * @return 封装数据的结果集 String * */
public ResultSet execQuery(String sql, String[] params) {
getConn();
try {
psmt = conn.prepareStatement(sql);// 创建PreparedStatement对象,执行增,删,改,查
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
psmt.setString(i + 1, params[i]);// psmt.setString(1,"aa");
}
}
rs = psmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
}
ProvinceDaoImpl继承自BaseDao,在该类中封装了getAllProvince和getCitiesByProvinceId这两个方法,顾名思义,就是查询所有省市和更具省份id查找城市。
package com.jqueryajax.dao.impl;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.jqueryajax.dao.BaseDao;
import com.jqueryajax.entity.City;
import com.jqueryajax.entity.Province;
public class ProvinceDaoImpl extends BaseDao{
public List<Province> getAllProvince() {
List<Province> list = new ArrayList<Province>();
String sql="select * from province";
rs = this.execQuery(sql, null);
try {
while(rs.next()){
Province province = new Province();
province.setProvinceId(rs.getInt("provinceId"));
province.setProvinceName(rs.getString("provinceName"));
list.add(province);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.closeAll();
}
return list;
}
public List<City> getCitiesByProvinceId(int provinceId) {
List<City> list = new ArrayList<City>();
String sql="select * from city where provinceId="+provinceId;
rs = this.execQuery(sql, null);
try {
while(rs.next()){
City city = new City();
city.setCityId(rs.getInt("cityId"));
city.setCityName(rs.getString("cityName"));
city.setPersonSize(rs.getInt("personSize"));
city.setCityArea(rs.getInt("cityArea"));
city.setPlace(rs.getString("place"));
city.setProvinceId(rs.getInt("provinceId"));
list.add(city);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.closeAll();
}
return list;
}
}
接下来实现两个Servlet:ProvinceJsonServlet和CityJsonServlet用来处理用户的请求:
ProvinceJsonServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");//设置响应的内容格式
PrintWriter out = response.getWriter();
ProvinceDaoImpl provinceDao = new ProvinceDaoImpl();
List<Province> list = provinceDao.getAllProvince();//查询所有的省份
//[{"provinceId":1,"provinceName":"陕西省"},...]
JSONArray jsonArray = JSONArray.fromObject(list);
System.out.print(jsonArray);
out.print(jsonArray);
}
这里就是一个查询所有的省份,然后将其转换成json对象。然后将该json对象返回给客户端,这里需要用到下面一些jar文件:
commons-beanutils.jar
commons-collections.jar
commons-lang.jar
commons-logging.jar
ezmorph-1.0.6.jar
json-lib-2.3-jdk15.jar
CityJsonServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");//设置响应的内容格式
PrintWriter out = response.getWriter();
ProvinceDaoImpl provinceDao = new ProvinceDaoImpl();
//根据省份ID查询旗下的城市
String provinceIdStr = request.getParameter("provinceId");
int provinceId = Integer.parseInt(provinceIdStr);
List<City> list = provinceDao.getCitiesByProvinceId(provinceId);
JSONArray jsonArray = JSONArray.fromObject(list);
out.print(jsonArray);
}
在CityServlet中根据客户端通过jQuery ajax传递过来的省份id,(这里假设客户端传递的参数名称是”provinceId”),查询旗下的城市,然后转换成json对象,返回给客户端。
注意:一定记得在web.xml中配置这两个servlet
现在万事俱备只欠东风,开始编写我们的前端页面,这里就不使用css美化页面了,我们今天的主要任务是使用jQuery ajax请求,并在回调函数中处理该请求。
在jsp页面内容如下:
<body>
<div id="province"></div>
<div id="city"></div>
</body>
这里我使用了两个div来显示省份和城市。首先我们需要在页面加载完毕之前就要加载所有的省份,所以需要使用到页面加载函数:
<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
<script type="text/javascript"> $(document).ready(function(){ $.get("ProvinceJsonServlet", null, function(data){ alert("Data Loaded: " + data); }); }); </script>
记得引入jQuery文件哈。这里我在页面加载函数中查询所有的省份,请求ProvinceJsonServlet,由于不需要传递任何参数,所有参数填写null,在回调函数中的data就是服务器返回给前端的数据。我们先将该data打印出来看下是否正确.
http://localhost:8080/jqueryajax/index.jsp
可以看到在页面加载之前已经正确的加载了所有的省份。
接下来就是根据这些数据构造一个select选择器。完整的回调函数,如下:
function(data){
//alert("Data Loaded: " + data);
var optionHTML="<select name=\"province\" onchange=\"loadCities(this.value)\">";
var data = eval("("+data+")");
for(var i=0;i<data.length;i++){
var province = data[i];
//alert(province.provinceId);
optionHTML+="<option value=\""+province.provinceId+"\">"+province.provinceName+"</option>";
}
optionHTML+="</select>";
$("#province").html(optionHTML);//将数据填充到省份的下拉列表中
});
这里需要注意一定要使用eval(“(“+data+”)”);函数,这是因为服务器返回给我们的是json格式的字符串,我们需要使用eval()函数将其转换成json数组。并且为该select设置了onchange方法,在改方法中传递的参数就是当前选中的省份的id。
function loadCities(cityId) {
$.post("CityJsonServlet", {provinceId:cityId},
loadCityCallback
);
}
function loadCityCallback(data) {
alert(data);
}
在loadCities方法中使用jquery的post方法请求CityJsonServlet,并且传递了一个provinceId作为参数,并且设置自定义的回调函数loadCityCallback,在该回调函数中首先通过alert查看数据是否正确.
当选择不同的省份,弹出的数据也是不同的,说明服务器返回给我们的json字符串是正确的。
接下来和省份一样,根据json字符串构造页面:
function loadCityCallback(data) {
//alert(data);
var data = eval("("+data+")");
var cityHTML="";
for(var i=0;i<data.length;i++){
var city = data[i];
cityHTML+="<p><b>"+city.cityName+"</b></p>";
cityHTML+="人口:"+city.personSize+",面积:"+city.cityArea+"<br>";
cityHTML+="名胜:"+city.place+"<br>";
}
$("#city").html(cityHTML);
}
源码下载