zoukankan      html  css  js  c++  java
  • 微项目: 地区导航——知识与技术点总结

     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+"
    Status:"+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
  • 相关阅读:
    JS LeetCode 1423. 可获得的最大点数简单题解
    SpringBoot 学集 (第六章) Docker
    Linux 学记 (第三章)
    Linux 学记 (第二章)
    Linux 学记 (第一章)
    SpringBoot 学集 (第五章) Web开发续
    SpringBoot 学集 (第四章)Web开发
    SpringBoot 学集 (第三章) 日志框架
    SpringBoot 学集 (第二章) 配置文件
    SpringBoot 学集 (第一章)
  • 原文地址:https://www.cnblogs.com/wgbs25673578/p/5067907.html
Copyright © 2011-2022 走看看