我就不吃芹菜

导航

 

 1, index页面(带直接显示数据)

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>        //刚开始的时候不要忘记引入各种包
<%@ page import="com.hanqi.Dao.*" %>
<%@ page import="com.hanqi.*" %>
<!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>地区列表显示页面</title>
<%
String pid = request.getParameter("parentid");   //接收自己传给自己的参数
if(pid==null||pid.trim().length()<=0) {
      pid = "0";
}  
int pid1 = Integer.parseInt(pid);
//获取数据
MemberDal md = new MemberDal();
Memberclass m = md.getMemberclass(pid1);
int backid = 0;
if(m!=null) {
    backid = m.getParentId();
}
%>
<script src="js/jquery-1.11.3.min.js"></script>
<script>      //这里使用jQuery隐藏和显示添加文本框
$(document).ready(function () {
    $("#i1").click(function (){
        $("#d1").toggle(100);
    })
});
$(document).ready($("#d1").hide());    //隐藏
</script>
<script>
function check() {
    var obj = /\d{6}/;      //正则表达式判断是否是6位数字以上的
    if(fm.name.value=="") {
        alert("地区不能为空");
        return false;
    }
    else if(!(obj.test(fm.postcode.value)||fm.postcode.value=="")) {
        alert("邮编请符合规则");
        return false;
    }
    else {
        return true;
    }
}
function con(){
    var cfm = confirm("确定要删除该地区吗? 删除该地区的同时, 会将该地区下的所有地区都删除! ");
        return cfm;
}
/*function show() {
    document.getElementById("fm").style.display="block";
}*/       
//样式表中的隐藏属性, display = none或者block
function backSuper() {
    window.location="index.jsp?parentid=<%=backid %>";
        //window.history.back();     //使页面后退的两种简单方法
    //window.history.go(-1);
}
</script>
</head>
<body>
<a href="Finder">显示全部省级地区</a>
<br>
<br>
<input id="i1" type="button" value="在此级别添加地区" />&nbsp;
<input type="button" value="返回上级地区" onclick="backSuper()" />
<br>
<table border="1" cellspacing="1" cellpadding="1">
  <tr>
    <th width="80">地名</th>
    <th width="80">邮编</th>
    <th width="80">管理</th>
    <th width="80">删除</th>
  </tr>
  <%
  ArrayList<Memberclass> al = md.getList(pid1);
  //Memberclass u;
  if(al!=null) {
      for(Memberclass rset : al) {
          out.print("<tr><td>");    //通过输出表格标签的形式组建表格
          out.print(rset.getName());
          out.print("</td><td>");
          out.print(rset.getPostCode()==null?"":rset.getPostCode());     //用三元表达式让其不显示"null"
          out.print("</td><td>");
          out.print("<a href='index.jsp?parentid="+rset.getId()+"'>下级地区</a>");
          out.print("</td><td>");
          out.print("<a onclick='return con()' href='DeleteMember?parentid="+rset.getParentId()+"&id="+rset.getId()+"'>删除</a></td></tr>");
      }
  }
  %>
</table>
<br>
<div id="d1">
<form id="fm" method="post" action="InsertMember" onSubmit="return check()">
<input name="parentid" type="hidden" value="<%=pid%>">
<ul>
<li>请输入地区: <input name="name" type="text" value="" /></li>
<li>请输入邮编: <input name="postcode" type="text" value="" maxlength="6"/></li>
<li><input type="submit" value="添加" /><input type="reset" value="取消" /></li>
</ul>
</form>
</div>
带刷新的三级联动<br>
<iframe src="list.jsp" width="500" height="50"></iframe><br><br>
无刷新三级联动<br>
<iframe src="ajaxlist1.jsp" width="500" height="50"></iframe>
</body>
<script>    //设置开始的隐藏状态, 隐藏添加的文本框
$("#d1").hide();
</script>
</html>
View Code

 2, Servlet控制层

录入数据

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");          //先设置转码的指令
        String name = request.getParameter("name");
        String postcode = request.getParameter("postcode");   //接收参数
        String parentid = request.getParameter("parentid");
        
        if(name!=null&&name.trim().length()>0) {
            //get方法需要在这里在进行一次转码
            //name = new String(name.getBytes("iso-8859-1"),"utf-8");
    
            if(parentid!=null&&parentid.trim().length()>0) {
                Memberclass m = new Memberclass();
                m.setName(name);
                m.setParentId(Integer.parseInt(parentid));
                m.setPostCode(postcode);
                MemberDal ma = new MemberDal();
                try {
                    if(ma.insert(m)>0) {
                        response.sendRedirect("Finder?parentid="+parentid);   //顺便将参数传回去, 控制显示页面
                    }
                    else {
                        response.getWriter().append("添加失败");
                    }
                } catch (Exception e) {
                    response.getWriter().append(e.getMessage());
                }
            }
            else {
                response.getWriter().append("地区parentid不能为空");
            }
        }
        else {
            response.getWriter().append("地区name不能为空");
        }
    }
View Code

删除数据

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/htm; charset=utf-8");
        String id = request.getParameter("id");
        String parentid = request.getParameter("parentid");
        if(id==null||id.trim().length()<=0) {
            response.getWriter().append("id不能为空");
        }
        else {
            MemberDal1 de = new MemberDal1();
            try {
                if(de.deleteDG(Integer.parseInt(id))>0) {   //判断递归级联删除的返回值为多少
                    response.sendRedirect("Finder?parentid="+(parentid==null?"0":parentid));   //使用三元表达式赋值控制显示数据
                }
                else {
                    response.getWriter().append("删除数据失败");
                }
            }
            catch(Exception e) {
                response.getWriter().append(e.getMessage());
            }
        }
    }
View Code

查询显示数据(使用一个sevrlet), 在index中可以直接获取数据, 两种方法均可

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
        try {    //异常包裹处理是非常重要的
            Connection con = Dbhelper.getConnection();
            if(con!=null) {
                String parentid = null;
                String sql = "select * from member where parentid ="+parentid;
                Statement stm = con.createStatement();
                ResultSet rs = stm.executeQuery(sql);   //在这里混了好几次了, 根据返回值的不同, 执行的语句也是不一样的, 高度注意这里
                ArrayList<Memberclass> result = new ArrayList<Memberclass>();   //实例化一个集合要标明对象类型Memberclass
                if(rs!=null) {
                    while(rs.next()) {
                        Memberclass place = new Memberclass();
                        place.setId(rs.getInt("id"));
                        place.setParentId(rs.getInt("parentid"));
                        place.setName(rs.getString("name"));
                        place.setPostCode(rs.getString("postcode"));
                        result.add(place);
                    }
                    request.setAttribute("placelist", result);
                }
                else {
                    response.getWriter().append("无结果返回");
                }
                //p.close();
                con.close();
                stm.close();
            }
            else{
                response.getWriter().append("连接数据库失败");
            }
        }
        catch(Exception e) {
            response.getWriter().append(e.getMessage());
        }
        request.getRequestDispatcher("index.jsp").forward(request, response);   //注意跳转的方式
    }
View Code

 3, Dal工具类

链接数据库, 加载驱动(没什么好说的, 背下来)

public class Dbhelper {
    public static Connection getConnection() throws Exception {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String url = "jdbc:oracle:thin:@localhost:1521:orcl";
        Connection conn = DriverManager.getConnection(url, "test1204", "1234");
        return conn;
    }
}
View Code

对象类(当时学的时候觉得很深奥, 现在已经用的比较熟练了, 为什么?)

package com.hanqi.Dao;

public class Memberclass {
    private int id;
    private int ParentId;
    private String Name;
    private String PostCode;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getParentId() {
        return ParentId;
    }
    public void setParentId(int parentId) {
        ParentId = parentId;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public String getPostCode() {
        return PostCode;
    }
    public void setPostCode(String postCode) {
        PostCode = postCode;
    }
}
View Code

增删查方法体类(重点是递归级联删除, 以后关于地区的问题, 大部分都要使用到这个技术, 还有建立树形文件夹)

package com.hanqi.Dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
public class MemberDal {
    //插入数据
    public int insert(Memberclass m) throws Exception {
        int row = 0;
        Connection conn = Dbhelper.getConnection();
        PreparedStatement pst = null;
        if(conn!=null) {
            try {   //注意在写占位符的时候尽量不要加空格
                String sql = "insert into member (id, parentid, name, postcode) values (sq_member.nextval,?,?,?)";
                pst = conn.prepareStatement(sql);
                pst.setInt(1, m.getParentId());
                pst.setString(2, m.getName());
                pst.setString(3, m.getPostCode());
                row = pst.executeUpdate();
            }
            catch(Exception ex) {
                throw ex;
            }
            finally {
                try{
                    pst.close();                      //如果出现异常也要确保资源能够正常释放
                }
                catch(Exception ex1) {
                    throw ex1;
                }
                conn.close();
            }
        }
        return row;
    }
    
    //删除数据, 只能删除两级
    public int delete(int id) throws Exception {
        int row = 0;
        Connection con = Dbhelper.getConnection();
        PreparedStatement ps = null;
        if(con!=null) {
            try {   //运用上下级id的关系
                String sql = "delete member where id = ? or parentid = ?";
                ps = con.prepareStatement(sql);
                ps.setInt(1, id);
                ps.setInt(2, id);
                row = ps.executeUpdate();
            }
            catch(Exception e) {
                throw e;
            }
            finally {
                try {
                    ps.close();
                }
                catch(Exception e1) {
                    throw e1;
                }
                con.close();
            }
        }
        return row;
    }

    
    //构造查询的方法
    public ArrayList<Memberclass> getList(int parentid) throws Exception {
        ArrayList<Memberclass> rst = null;
        Connection con = Dbhelper.getConnection();
        PreparedStatement p = null;
        ResultSet rs = null;
            if(con!=null) {
                try {
                    String sql = "select * from member where parentid = ?";
                    p = con.prepareStatement(sql);
                    p.setInt(1, parentid);
                    rs = p.executeQuery();
                    rst = new ArrayList<Memberclass>();
                    if(rs!=null) {
                        while(rs.next()) {
                            Memberclass place = new Memberclass();
                            place.setId(rs.getInt("id"));
                            place.setParentId(rs.getInt("parentid"));
                            place.setName(rs.getString("name"));
                            place.setPostCode(rs.getString("postcode"));
                            rst.add(place);
                        }
                    }
                }
                catch(Exception e) {
                    System.out.println(e);
                }
                finally {
                    try {
                        p.close();
                    }
                    catch(Exception e1) {
                        System.out.println(e1);
                    }
                    finally {
                        try {
                            con.close();
                        }
                        catch(Exception e2) {
                            
                        }
                        finally {
                            rs.close();
                        }
                    }
                }
            }
        return rst;
    }
    
    
    
    //返回上一级单条查询
    public Memberclass getMemberclass(int id) throws Exception{
        Memberclass rtn = null;
        Connection conn = Dbhelper.getConnection();
        PreparedStatement pst = null;
        ResultSet rs = null;
        if(conn!=null) {
            try {
                String sql = "select * from member where id=?";
                pst = conn.prepareStatement(sql);
                pst.setInt(1, id);
                rs = pst.executeQuery();
                if(rs!=null&&rs.next()) {
                        rtn = new Memberclass();
                        rtn.setId(rs.getInt("id"));
                        rtn.setParentId(rs.getInt("parentid"));
                }
            }
            catch(Exception ex) {
                throw ex;
            }
            finally {
                try {
                    pst.close();                      //如果出现异常也要确保资源能够正常释放
                }
                catch(Exception ex1) {
                    throw ex1;
                }
                conn.close();
            }
        }
        return rtn;
    }
    
    
    
    //递归级联删除
    //递归级联删除
    private void dgDel(Connection con, int id) throws SQLException {
        PreparedStatement pst = null;
        ResultSet rs = null;
        Statement st = null;
        try {
            //找到第一条复合条件的先将其删除
            String sql = "delete member where id = ? ";
            pst = con.prepareStatement(sql);
            pst.setInt(1, id);
            pst.executeUpdate();
            //找到其下一级
            sql = "select * from member where parentid = " + id;
            st = con.createStatement(); 
            rs = st.executeQuery(sql);
          //因为在这个题目当中有一个id==parentid的隐含条件, 所以这里可以使用递归级联删除
            //遍历子节点
            if (rs != null) {
                while(rs.next()) {
                    dgDel(con, rs.getInt("id"));//递归调用
                }  
            }
        }
        catch(Exception ex) {
            System.out.println(ex);
        }
        finally {
            try {
                rs.close();
            }
            catch(Exception ex) { }
            try {
                pst.close();
            }
            catch(Exception ex) { }
            try {
                st.close();
            }
            catch(Exception ex) { }
        }
    }
    
    //
    public int deleteDG(int id) throws Exception {
        int rtn = -1;
        Connection conn = Dbhelper.getConnection();
        PreparedStatement pst = null;
        if (conn != null) {                        
            try {
                //因为牵扯到级联删除, 这个地方一定要用到事务, 设置为手动提交
                //手动提交
                conn.setAutoCommit(false);
                //递归级联删除
                dgDel(conn, id);
                conn.commit();
                //之前一直返回的是一个负数是因为rtn这个一直没被赋值, 这样做一下判断, 如果删除成功了就赋值为1
                rtn = 1;
            }
            catch(Exception ex) {
                conn.rollback();
                throw ex;
            }
            finally {
                try {
                    pst.close();
                }
                catch(Exception ex) { }
                conn.close();
            }
        } 
        return rtn;
    }
    
    
    
    
    
}
View Code

 

地区的三级联动

1, 显示页面, jsp页面

带刷新的三级联动

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.hanqi.Dao.*" %>
<%@ page import="com.hanqi.*" %>    
<!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>三级联动</title>
<%
String first = request.getParameter("first");   //接收自己传给自己的数据
String second = request.getParameter("second");
int ifirst = 0;
int isecond = 0;
if(first!=null&&first.trim().length()>0) {
    ifirst = Integer.parseInt(first);
}
if(second!=null&&second.trim().length()>0) {
    isecond = Integer.parseInt(second);
}
%>  
<script>
function firstOnChange() {
    //将第一级的id传进去, 再刷新页面
    var first = document.getElementById("first");
    window.location = "list.jsp?first="+first.value;
}
function secondOnChange() {
//在这里, 当选择第二级和第三级选项是, 会影响第一级的选择, 
//这时候要把两个参数都传一下, 使页面重新刷新 
    var first = document.getElementById("first");
    var second = document.getElementById("second");
    window.location = "list.jsp?first="+first.value+"&second="+second.value;
}
</script>
</head>
<body>
一级地区
<select id="first" onchange="firstOnChange()">
<option value="0">未选择</option>
<%
MemberDal md = new MemberDal();
ArrayList<Memberclass> al = md.getList(0);
if(al!=null) {
    for(Memberclass m:al) {
//运用三元表达式在页面刷新之后还能选中之前选中的选项
        out.print("<option value='"+m.getId()+"' "+(m.getId()==ifirst?"selected":"")+">"+m.getName()+"</option>");
    }
}
%>
</select>


二级地区
<select id="second" onchange="secondOnChange()">
<option value="0">未选择</option>
<%
ArrayList<Memberclass> al2 = null;
if(ifirst!=0) {
    al2 = md.getList(ifirst);
    if(al2!=null) {
        for(Memberclass m1:al2) {
            out.print("<option value='"+m1.getId()+"' "+(m1.getId()==isecond?"selected":"")+">"+m1.getName()+"</option>");
        }
    }
}
%>
</select>


三级地区
<select id="third">
<option value="0">未选择</option>
<%
ArrayList<Memberclass> al3 = null;
if(isecond!=0) {
    al3 = md.getList(isecond);
    //必须判断是否为空, 否则会出现空指令异常
    if(al3!=null) {
        for(Memberclass m2:al3) {
            out.print("<option value='"+m2.getId()+"'>"+m2.getName()+"</option>");
        }
    }
}
%>
</select>
</body>
</html>
View Code

不带刷新的三级联动(关于onchange事件的调用函数有N种, 包括自己定义一种格式, 手工接收返回的数据, 包括使用jQuery+Ajax写onchange的函数, 包括使用json来接收和编译取到的数据)

使用jQuery的话就不需要Servlet来控制了, 可以直接返回数据

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.hanqi.Dao.*" %>
<%@ page import="com.hanqi.*" %>    
<!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>无刷新三级联动</title>
<script src="js/jquery-1.11.3.min.js"></script>
<script>
var hx = false;
//最原始的方法, 直接用ajax, 自己手工接收参数, 在sevrlet控制层自己构造一个格式
function firstOnChange() {
    if(window.XMLHttpRequest) {
        hx = new XMLHttpRequest;
    }
    else if(window.ActiveXObject) {
        hx = new ActiveXObject(Msxml2.XMLHTTP);
    }
    else {
        hx = new ActiveXObject(Microsoft.XMLHTTP);
    }
    var first = document.getElementById("first");
    hx.open("GET","AjaxGetList1?parentid="+first.value,true);
//这里使用的GET方法, 注意与POST方法的区别
//设置回调函数
    hx.onreadystatechange = firstCh;
    hx.send(null);
    function firstCh() {
        if(hx.readyState==4) {
            if(hx.status==200) {
//接收返回的内容
                var ts = hx.responseText;
分割字符串
                var ar = ts.split(";");
                var doc = document.getElementById("second");   
//清除掉之前的下拉选项
                doc.options.length=1;
                for(var i = 0; i<ar.length-1; i++) {
                    var rr = ar[i].split(":");
                    doc.options.add(new Option(rr[1],rr[0]));
                }
            }
        }
    }
//清除掉第三级下拉菜单
    var doc = document.getElementById("third");
    doc.options.length=1;
    //secondOnChangeJq();
}
//同上
function secondOnChange() {
    if(window.XMLHttpRequest) {
        hx = new XMLHttpRequest;
    }
    else if(window.ActiveXObject) {
        hx = new ActiveXObject(Msxml2.XMLHTTP);
    }
    else {
        hx = new ActiveXObject(Microsoft.XMLHTTP);
    }
    var second = document.getElementById("second");
    hx.open("GET","AjaxGetList1?parentid="+second.value,true);
    hx.onreadystatechange = secCh;
    hx.send(null);
    function secCh() {
        if(hx.readyState==4) {
            if(hx.status==200) {
                var ts = hx.responseText;
                var ar = ts.split(";");
                var doc = document.getElementById("third");
                doc.options.length=1;
                for(var i = 0; i<ar.length-1; i++) {
                    var rr = ar[i].split(":");
                    doc.options.add(new Option(rr[1],rr[0]));
                }
            }
        }
    }
}


//使用jQuery运行ajax
function secondOnChangeJq() {
    var url="AjaxGetList1?parentid="+$("#second").val();
    var cb = function(data,status) {   //直接返回数据和状态
        //alert("data:"+data+"\nStatus:"+status);
        var ar = data.split(";");
        var doc = document.getElementById("third");
        doc.options.length=1;   //必须要等于1, 要保留第一个选项
        for(var i = 0; i<ar.length-1; i++) {
            var rr = ar[i].split(":");
//设置下拉选项的value
            doc.options.add(new Option(rr[1],rr[0]));
        }
    }
//直接调用
    $.get(url,cb);
}


//使用JSON来接收字符串
function jsonChange() {
    var cb = function(data,status) {
                    alert(data);
                    //使用eval()方法解析json
                    var array = eval("("+data+")");
                    var doc = document.getElementById("second");
                    doc.options.length=1;
                    //json返回的是一个数组, 数组的每个单位是一个对象, 每个对象都是一个键值对, 可以在这里直接调用属性值
                    for(var i = 0; i<array.length; i++) {
                        doc.options.add(new Option(array[i].name,array[i].id));
                    }
                }
    var url = "JsonGetList?parentid="+$("#first").val()+"&nocache="+new Date().getTime();   //添加一个时间消除缓存
    $.get(url,cb);
}
</script>
</head>
<body>
一级地区
<select id="first" onchange="firstOnChange()">
<option value="0">未选择</option>
<%
MemberDal md = new MemberDal();
ArrayList<Memberclass> al = md.getList(0);
if(al!=null) {
    for(Memberclass m:al) {
        out.print("<option value='"+m.getId()+"'>"+m.getName()+"</option>");
    }
}
%>
</select>

二级地区
<select id="second" onchange="secondOnChangeJq()">
<option value="-1">未选择</option>
</select>

三级地区
<select id="third">
<option value="-1">未选择</option>
</select>
</body>
</html>
View Code

2, Servlet控制层

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//啥事也别干, 先设置字符集
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
//第二步, 接收参数
        String parentid = request.getParameter("parentid");
        int pid = 0;
        if(parentid!=null&&parentid.trim().length()>0) {
            pid = Integer.parseInt(parentid);
        }
        else {
            pid = -1;
        }
        String str = "";
        try {
            MemberDal m = new MemberDal();
            ArrayList<Memberclass> array =  m.getList(pid);
            if(array!=null) {
                for(Memberclass q:array) {
                    str = str+q.getId()+":"+q.getName()+";";   //这里就是自己构造的一个格式
                }
            }
        } 
        catch (Exception e) {
            //response.getWriter().append(e.getMessage());
        }
//返回只能返回一个文本或者字符串, 
        response.getWriter().append(str);
    }
View Code

 

posted on 2015-12-22 19:45  我就不吃芹菜  阅读(192)  评论(0编辑  收藏  举报