分析:实现这一功能需要发送三次Ajax请求
1.第一次请求:是页面加载完毕之后,发送一次Ajax请求,查询出所有的省级单位,将这些查询结果展示在<select>标签中。
2.第二次请求:当所选省级单位发生变化的时候发送一次Ajax请求,查询出该省级单位下的所有市级单位;
3.第三次请求:市级单位发生变化的时候再一次发送Ajax请求,查询出该市下所有的县级单位。
在前端代码中,编写Ajax请求时,需要使用jQuery代码;在查询时需要使用JDBC技术,将Java对象转换成JSON需要使用fastjson
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>省市县联动</title>
<script type="text/javascript" src="/ajax/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
$(function () {
//发送Ajax请求,查询省级部门
$.ajax({
type : "GET",
url : "/ajax/request6",
async : true,
//这里没有发送数据,所以没写data : "t=" + new Data().getTime
success : function(json){
var jsonObjList = JSON.parse(json);
var html = "<option value=\"\">--请选择省份--</option>";
for (var i = 0;i < jsonObjList.length; i ++){
var jsonObj = jsonObjList[i];
//以下两种拼串形式都正确,拼串不正确程序没有反应,谷歌浏览器按F12有提示信息
// html += "<option value=\""+ jsonObj.code +"\">"+ jsonObj.name +"</option>"
html += "<option value='"+ jsonObj.code +"'>"+ jsonObj.name +"</option>";
}
//将拼好的字符串以html代码的形式响应到<select id="province">标签之中
$("#province").html(html);
}
});
//发送Ajax请求,查询市级部门
//这里不能写成$("#province").change = function(){}
//当<select id="province>标签的value值发生改变的时候,发送Ajax请求
$("#province").change(function () {
$.ajax({
type : "GET",
url : "/ajax/request6",
async : true,
//这里其他的数据需要发送就需要在后面&name=xxx&password=xxx
data : "pCode=" + this.value,
success : function (json){
var jsonObjList = JSON.parse(json);
var html = "<option value=\"\">--请选择市区--</option>";
for (var i = 0;i < jsonObjList.length; i ++){
var jsonObj = jsonObjList[i];
html += "<option value=\""+ jsonObj.code +"\">"+ jsonObj.name +"</option>"
}
//将拼好的字符串以html代码的形式响应到<select id="city">标签之中
$("#city").html(html);
}
})
});
//发送Ajax请求,查询县级部门
//当<select id="city>标签的value值发生改变的时候,发送Ajax请求
$("#city").change(function () {
$.ajax({
type : "GET",
url : "/ajax/request6",
data : "pCode=" + this.value,
async : true,
success :function (json) {
var jsonObjList = JSON.parse(json);
var html = "<option value=\"\">--请选择县区--</option>";
for (var i = 0;i < jsonObjList.length; i ++){
var jsonObj = jsonObjList[i];
html += "<option value='"+ jsonObj.code +"'>"+ jsonObj.name +"</option>"
}
//将拼好的字符串以html代码的形式响应到<select id="county">标签之中
$("#county").html(html);
}
})
});
})
</script>
</head>
<body bgcolor="#faebd7">
<!-- 省级标签 -->
<select id="province">
<!-- <option value="">--请选择省份--</option>-->
<!-- <option value="001">河北省</option>-->
<!-- <option value="002">河南省</option>-->
<!-- <option value="003">北京市</option>-->
</select>
<!-- 市级标签 -->
<select id="city">
</select>
<!-- 县级标签 -->
<select id="county">
</select>
</body>
</html>
服务端代码:
package com.yjg.ajax.servlet;
import com.alibaba.fastjson.JSON;
import com.yjg.ajax.bean.Pac;
import com.yjg.ajax.util.DBUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/request6")
public class AjaxRequest6Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//接收参数,前端没有传递参数的时候,接收结果是null
String pCode = request.getParameter("pCode");
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Pac> pacArrayList = new ArrayList<>();
String sql = null;
try {
conn = DBUtil.getConnection();
//如果前端没有传递参数,执行查询省级部门的sql语句
if (pCode == null){
sql = "select code,name from pac where pcode is null";
ps = conn.prepareStatement(sql);
//如果前端传递了参数,执行查询市级部门的sql语句
}else {
sql = "select code,name from pac where pcode = ?";
ps = conn.prepareStatement(sql);
ps.setString(1,pCode);
}
//执行查询语句
rs = ps.executeQuery();
//处理查询结果集
while (rs.next()) {
String code = rs.getString("code");
String name = rs.getString("name");
//通过查询结果,创建Java对象
Pac pac = new Pac(code,name);
//将Java对象添加到List集合中
pacArrayList.add(pac);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
//将List集合变成JSON格式的字符串
String jsonString = JSON.toJSONString(pacArrayList);
//设置响应内容类型和字符集
response.setContentType("text/html;charset=UTF-8");
//将JSON格式的字符串响应给浏览器
response.getWriter().print(jsonString);
}
}
数据库表:(表名:pac)
程序中使用了工具类:DBUtil.java
package com.yjg.ajax.util;
import java.sql.*;
import java.util.ResourceBundle;
public class DBUtil {
//私有的构造方法
private DBUtil(){}
//类加载时绑定属性资源文件(静态变量和静态代码块的执行时间一样,都是在类加载的时候执行,这时就看代码的先后顺序了,谁在前谁先执行)
private static ResourceBundle bundle = ResourceBundle.getBundle("resources/db");
static {
try {
Class.forName(bundle.getString("driver"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接对象 (以后在实际开发中只要调用该方法就会完成注册驱动和获取连接两步)
* @return 新的连接对象
* @throws SQLException 这里选择上抛异常,由使用者捕捉。
*/
public static Connection getConnection() throws SQLException {
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = DriverManager.getConnection(url,user,password);
return conn;
}
/**
* 释放资源
* @param conn 连接对象
* @param stmt 数据库操作对象 这里最好写Statement,而不写PreparedStatement,
* 原因是今后可以使用多态,既可以传一个父类对象,也可以传入子类对象。
* @param rs 查询结果集
*/
public static void close(Connection conn, Statement stmt, ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
属性资源配置文件:
############# mysql connectivity configuration ###############
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
user=root
password=XXXXXX
创建了实体类:Pac.java
package com.yjg.ajax.bean;
//省市实体类
public class Pac {
private String code;
private String name;
public Pac() {
}
public Pac(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Pac{" +
"code='" + code + '\'' +
", name='" + name + '\'' +
'}';
}
}
程序运行之后浏览器显示如下: