根据mvc分层思想

v层(视图层)


select.jsp(未封装公共方法)


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'select.jsp' starting page</title>
    <!--

    Ajax案例之三级联动:

     功能需求:

      页面中有三个下拉框选项,分别为省下拉框,市下拉框,区/县下拉框

      选择省,则市下拉框中出现对应的该省下的市信息,选择市,则区/县下拉框中

      出现对应的该市下面的区/县信息

     技术分析:

      ajax技术+jsp+servlet+jdbc

     需求分析(思路):

       

     数据库设计:

      创建表(area):存储了省、市、区/县信息

      设计表实现一:只存储了数据,但是数据之间的层级关系没有存储。

       地区id:areaid

       地区名:areaname

      设计表实现二:

       地区id:areaid

       地区名:areaname

       地区上级id:parentid

     sql语句设计:

      查询所有的省信息:

   

select * from area where parentid=0;

      查询选择的省的市信息(假如:选择的山东省的areaid为110000,)

   

select * from area where parentid=110000;

      查询选择的市的区/县信息(假如:选择的山东省的济南市areaid为110001)

   

select * from area where parentid =110001;

      代码中

     

select * from area where parentid=?;

     数据库实现:将资料中提供的area.sql文件导入到数据库中即可

     功能实现:参照源码即可

     代码缺陷:

      发现请求省,市,县的代码中基本上是一致的。代码的冗余量有点大

     解决:

      考虑使用封装

     实现:形同的保留,不同的传参。具体参照源码

   

-->
     <!--引入jQuery文件  -->
     <script type="text/javascript" src="js/j.js"></script>
     <!--声明js代码域  -->
     <script type="text/javascript">
      //页面加载成功请求省的信息
      $(function(){
      	
      	//发起ajax请求,请求所有的省信息
        $.get("area",{parentid:0},function(data){
        	//使用eval方法将数据转换为js对象
          eval("var areas="+data);
        	//将响应省数据填充到省下拉框中
          //获取下拉框对象
          var sel=$("#pre");
          //清空原有内容
          sel.empty();
          //遍历
          for(var i=0;i<areas.length;i++){
          	//填充
          	sel.append("<option value='"+areas[i].areaid+"'>"+areas[i].areaname+"</option>");
          }
          //触发省下拉框的change事件
          $("#pre").trigger("change");
        	});
      	//页面加载成功给省下拉框添加onchange事件
        $("#pre").change(function(){
        	//获取当前选择的省的areaid
        	var areaid=$("#pre").val();
        	//发起ajax请求,请求当前省的市信息
        	$.get("area",{parentid:areaid},function(data){
          //使用eval方法将数据转换为js对象
          eval("var areas="+data);
          //获取下拉框对象
          var sel=$("#city");
          //清空原有内容
          sel.empty();
          //遍历
          for(var i=0;i<areas.length;i++){
          	sel.append("<option value='"+areas[i].areaid+"'>"+areas[i].areaname+"</option>")
          }
          //触发省下拉框的change事件
          $("#city").trigger("change");
        	})
        });
      	//页面加载成功给市下拉框添加onchange事件
        $("#city").change(function(){
        	//获取当前选择的市的areaid
        	var areaid=$("#city").val();
        	//发起ajax请求,请求当前市下的区/县信息
        	$.get("area",{parentid:areaid},function(data){
          //使用eval方法将数据转换为js对象
          	eval("var areas="+data);
          //获取下拉框对象
          	var sel=$("#town");
          //清空原有内容
          	sel.empty();
          //遍历
          	for(var i=0;i<areas.length;i++){
              	sel.append("<option value='"+areas[i].areaid+"'>"+areas[i].areaname+"</option>")
              }
        	})
        	
        })
        
        
        //封装公共方法
          	function getData(areaid,sid){
        	//发起ajax请求,请求当前省的市信息
        	$.get("area",{parentid:areaid},function(data){
          //使用eval方法将数据转换为js对象
          eval("var areas="+data);
          //获取下拉框对象
          var sel=$("#"+sid);
          //清空原有内容
          sel.empty();
          //遍历
          for(var i=0;i<areas.length;i++){
          	sel.append("<option value='"+areas[i].areaid+"'>"+areas[i].areaname+"</option>")
          }
          //触发省下拉框的change事件
            	$("#"+sid).trigger("change");
        	})
          	}
        
        
      })
     </script>
  </head>
  <body style="background-color: gray;">
  	<div style="margin: auto;width: 750px;margin-top: 200px;">
     省: <select name="" id="pre" style="width: 200px;height: 30px;"></select>
       市: <select name="" id="city" style="width: 200px;height: 30px;"></select>
       区\县: <select name="" id="town" style="width: 200px;height: 30px;"></select>
  	</div>	
  </body>
</html>

select2.jsp(封装公共方法)


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'select.jsp' starting page</title>
    <!--

    Ajax案例之三级联动:

     功能需求:

      页面中有三个下拉框选项,分别为省下拉框,市下拉框,区/县下拉框

      选择省,则市下拉框中出现对应的该省下的市信息,选择市,则区/县下拉框中

      出现对应的该市下面的区/县信息

     技术分析:

      ajax技术+jsp+servlet+jdbc

     需求分析(思路):

      1、创建页面:页面中有三个下拉框,分别为省、市、区/县

      2、页面加载成功发起ajax请求,请求省的信息,并将响应结果

            填充到省下拉框中

      3、选择省触发一个新的js函数 的执行,该函数中发起新的ajax请求

            请求该省下的市信息,并将响应数据填充到市下拉框

      4、选择市信息触发一个新的js函数的执行,该函数中发起新的ajax请求

           请求该市下的区/县信息,并将数据填充到区/县下拉框中

     数据库设计:

      创建表(area):存储了省、市、区/县信息

      设计表实现一:只存储了数据,但是数据之间的层级关系没有存储。

       地区id:areaid

       地区名:areaname

      设计表实现二:

       地区id:areaid

       地区名:areaname

       地区上级id:parentid

     sql语句设计:

      查询所有的省信息:

   

select * from area where parentid=0;

      查询选择的省的市信息(假如:选择的山东省的areaid为110000,)

   

select * from area where parentid=110000;

      查询选择的市的区/县信息(假如:选择的山东省的济南市areaid为110001)

     

select * from area where parentid =110001;

      代码中

   

select * from area where parentid=?;

     数据库实现:将资料中提供的area.sql文件导入到数据库中即可

     功能实现:参照源码即可

     代码缺陷:

      发现请求省,市,县的代码中基本上是一致的。代码的冗余量有点大

     解决:

      考虑使用封装

     实现:形同的保留,不同的传参。具体参照源码

   

-->
     <!--引入jQuery文件  -->
     <script type="text/javascript" src="js/j.js"></script>
     <!--声明js代码域  -->
     <script type="text/javascript">
      //页面加载成功请求省的信息
      $(function(){
      	
      	//发起ajax请求,请求所有的省信息
        getData(0,"pre");
      	//页面加载成功给省下拉框添加onchange事件:请求选择的省下的市信息
        $("#pre").change(function(){
        	//获取当前选择的省的areaid
        	var areaid=$("#pre").val();
        	//发起ajax请求,请求当前省的市信息
        	getData(areaid, "city");
        });
      	//页面加载成功给市下拉框添加onchange事件
        $("#city").change(function(){
        	//获取当前选择的市的areaid
        	var areaid=$("#city").val();
        	getData(areaid,"town");
        })
        //封装公共方法
          	function getData(areaid,sid){
        	//发起ajax请求,请求当前省的市信息
        	$.get("area",{parentid:areaid},function(data){
          //使用eval方法将数据转换为js对象
          eval("var areas="+data);
          //获取下拉框对象
          var sel=$("#"+sid);
          //清空原有内容
          sel.empty();
          //遍历
          for(var i=0;i<areas.length;i++){
          	sel.append("<option value='"+areas[i].areaid+"'>"+areas[i].areaname+"</option>")
          }
          //触发省下拉框的change事件
            	$("#"+sid).trigger("change");
        	})
          	}
        
        
      })
     </script>
  </head>
  <body style="background-color: gray;">
  	<div style="margin: auto;width: 750px;margin-top: 200px;">
     省: <select name="" id="pre" style="width: 200px;height: 30px;"></select>
       市: <select name="" id="city" style="width: 200px;height: 30px;"></select>
       区\县: <select name="" id="town" style="width: 200px;height: 30px;"></select>
  	</div>	
  </body>
</html>


m层(service业务处理层,dao层数据访问层,pojo实体类层)


dao


AreaDao.java

package com.madi.dao;

import java.util.List;

import com.madi.pojo.Area;

public interface AreaDao {
	/**
  * 根据pid查询地区信息
  * @param pid
  * @return
  */
	List<Area> getAreaInfoDao(String pid);

}
AreaDaoImpl.java

package com.madi.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.madi.dao.AreaDao;
import com.madi.pojo.Area;
import com.madi.util.DBUtil;

public class AreaDaoImpl implements AreaDao{
	//根据pid查询地区信息
	public List<Area> getAreaInfoDao(String pid) {
  //声明jdbc变量
  Connection conn=null;
  PreparedStatement ps=null;
  ResultSet rs=null;
  //声明变量
  ArrayList<Area> la=null;
  try {
  	//获取连接
  	conn=DBUtil.getConnection();
  	//创建SQL命令
  	String sql="select * from area where parentid=?";
  	//创建SQL命名对象
  	ps=conn.prepareStatement(sql);
  	//给占位符赋值
  	ps.setString(1,pid);
  	//执行sql
  	rs=ps.executeQuery();
  	la=new ArrayList<>();
  	//遍历结果
  	while (rs.next()) {
    //创建实体类对象
    Area a=new Area();
    a.setAreaid(rs.getInt("areaid"));
    a.setAreaname(rs.getString("areaname"));
    a.setParentid(rs.getInt("parentid"));
    a.setArealevel(rs.getInt("arealevel"));
    a.setStatus(rs.getInt("status"));
    
    la.add(a);
  	}
  	//关闭资源
  } catch (Exception e) {
  	e.printStackTrace();
  }finally{
  	DBUtil.closeAll(rs, ps, conn);
  }
  
  //返回
  return la;
	}

}


service层


AreaService.java

package com.madi.service;

import java.util.List;

import com.madi.pojo.Area;

public interface AreaService {
	/**
  *根据pid查询地区信息
  * @param pid
  * @return
  */
	List<Area> getAreaInfoService(String pid);

}
AreaServiceImpl.java

package com.madi.service.impl;

import java.util.List;

import com.madi.dao.AreaDao;
import com.madi.dao.impl.AreaDaoImpl;
import com.madi.pojo.Area;
import com.madi.service.AreaService;

public class AreaServiceImpl implements AreaService{
	//创建Dao层对象
	AreaDao ad=new AreaDaoImpl();
	//根据pid查询地区信息
	@Override
	public List<Area> getAreaInfoService(String pid) {
  
  return ad.getAreaInfoDao(pid);
	}
	
}


pojo层


Area.java


package com.madi.pojo;

public class Area {
	private int areaid;
	private String areaname;
	private int parentid;
	private int arealevel;
	private int status;
	public int getAreaid() {
  return areaid;
	}
	public void setAreaid(int areaid) {
  this.areaid = areaid;
	}
	public String getAreaname() {
  return areaname;
	}
	public void setAreaname(String areaname) {
  this.areaname = areaname;
	}
	public int getParentid() {
  return parentid;
	}
	public void setParentid(int parentid) {
  this.parentid = parentid;
	}
	public int getArealevel() {
  return arealevel;
	}
	public void setArealevel(int arealevel) {
  this.arealevel = arealevel;
	}
	public int getStatus() {
  return status;
	}
	public void setStatus(int status) {
  this.status = status;
	}
	@Override
	public String toString() {
  return "Area [areaid=" + areaid + ", areaname=" + areaname
    + ", parentid=" + parentid + ", arealevel=" + arealevel
    + ", status=" + status + "]";
	}
	@Override
	public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + areaid;
  result = prime * result + arealevel;
  result = prime * result
    + ((areaname == null) ? 0 : areaname.hashCode());
  result = prime * result + parentid;
  result = prime * result + status;
  return result;
	}
	@Override
	public boolean equals(Object obj) {
  if (this == obj)
  	return true;
  if (obj == null)
  	return false;
  if (getClass() != obj.getClass())
  	return false;
  Area other = (Area) obj;
  if (areaid != other.areaid)
  	return false;
  if (arealevel != other.arealevel)
  	return false;
  if (areaname == null) {
  	if (other.areaname != null)
    return false;
  } else if (!areaname.equals(other.areaname))
  	return false;
  if (parentid != other.parentid)
  	return false;
  if (status != other.status)
  	return false;
  return true;
	}
	public Area() {
  super();
  // TODO Auto-generated constructor stub
	}
	public Area(int areaid, String areaname, int parentid, int arealevel,
  	int status) {
  super();
  this.areaid = areaid;
  this.areaname = areaname;
  this.parentid = parentid;
  this.arealevel = arealevel;
  this.status = status;
	}
	
	
	
	
}


c层


servlet

AreaServlet.java

package com.madi.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.madi.pojo.Area;
import com.madi.service.AreaService;
import com.madi.service.impl.AreaServiceImpl;
import com.google.gson.Gson;

public class AreaServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
  	throws ServletException, IOException {
  //设置请求编码格式
  req.setCharacterEncoding("utf-8");
  //设置响应编码格式
  resp.setContentType("text/html;charset=utf-8");
  //获取请求信息
  String pid=req.getParameter("parentid");
  //处理请求
  	//获取业务层对象
  	AreaService as=new AreaServiceImpl();
  	List<Area> la=as.getAreaInfoService(pid);
  //响应处理结果
  	//直接响应
  	resp.getWriter().write(new Gson().toJson(la));
	}
}


Dbutil.java工具类


package com.madi.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DBUtil {
	//声明全局变量记录jdbc参数
	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	//使用静态代码块,在类加载时即完成对属性文件的读取
	static{
  //动态获取属性配置文件的流对象
  InputStream in=DBUtil.class.getResourceAsStream("/db.properties");
  //创建Properties对象
  Properties p=new Properties();
  //加载
  try {
  	p.load(in);//会将属性配置文件的所有数据存储到Properties对象中
  	//将读取的jdbc参数赋值给全局变量
  	driver=p.getProperty("driver");
  	url=p.getProperty("url");
  	username=p.getProperty("username");
  	password=p.getProperty("password");
  	//加载驱动
  	Class.forName(driver);
  } catch (IOException e) {
  	// TODO Auto-generated catch block
  	e.printStackTrace();
  } catch (ClassNotFoundException e) {
  	// TODO Auto-generated catch block
  	e.printStackTrace();
  }
	}
	//创建连接对象并返回
	public static Connection getConnection(){
  Connection conn=null;
  try {
  	conn = DriverManager.getConnection(url, username, password);
  } catch (SQLException e) {
  	// TODO Auto-generated catch block
  	e.printStackTrace();
  }
  
  return conn;
	}
	//关闭资源
	public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
  try {
  	if(rs!=null){
    rs.close();
  	}
  } catch (SQLException e1) {
  	// TODO Auto-generated catch block
  	e1.printStackTrace();
  }
  try {
  	stmt.close();
  } catch (SQLException e) {
  	// TODO Auto-generated catch block
  	e.printStackTrace();
  }
  try {
  	conn.close();
  } catch (SQLException e) {
  	// TODO Auto-generated catch block
  	e.printStackTrace();
  }
  
  
	}
	//封装增加删除修改的通用工具方法
	/**
  * @param sql SQL语句
  * @param objs	SQL语句占位符实参,如果没有参数则传入null
  * @return 返回增删改的结果,类型为int
  */
	public static int executeDML(String sql,Object...objs){
  // 声明jdbc变量
    Connection conn = null;
    PreparedStatement ps = null;
    int i = -1;
    try {
    	// 获取连接对象
    	conn = DBUtil.getConnection();
    	// 开启事务管理
    	conn.setAutoCommit(false);
    	// 创建SQL命令对象
    	ps = conn.prepareStatement(sql);
    	// 给占位符赋值
    	if(objs!=null){
      for(int j=0;j<objs.length;j++){
      	ps.setObject(j+1,objs[j]);
      }
    	}
    	// 执行SQL
    	i = ps.executeUpdate();
    	conn.commit();
    } catch (Exception e) {
    	try {
      conn.rollback();
    	} catch (SQLException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    	}
    	e.printStackTrace();
    } finally {
    	DBUtil.closeAll(null, ps, conn);
    }
    return i;
	}
	}