黑马程序员技术交流社区

标题: 【石家庄校区】关于下拉级联的实现。 [打印本页]

作者: 张荫    时间: 2017-12-1 09:56
标题: 【石家庄校区】关于下拉级联的实现。
本帖最后由 张荫 于 2017-12-6 11:31 编辑

很多小伙伴在找工作时需要实现省市县级联。遇到了不少问题,那我下面就分享下我是如何实现省市联动的。
首先我们要获取数据就是省市相关的代码,这个是有一个全国统一规划的叫做行政区划代码。度娘了一波找到了这个网站:最新县及县以上行政区划代码(截止2016年7月31日) 发现有这么几个字段 有一个行政区划代码 和 名称 所以 我们建立一个数据库 有 三个 字段   id  code name
[SQL] 纯文本查看 复制代码
CREATE TABLE `b_administrative_divisions` (
  `id` int(11) NOT NULL,
  `code` int(10) DEFAULT NULL COMMENT '行政区划代码',
  `name` varchar(30) DEFAULT NULL COMMENT '行政区划名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

有了数据库 如何把网页中的数据导进我们的数据库呢?
我用了jsoup这个简单的爬取网页内容的工具

页面分析

分析完了页面我们就要从这个网页里取数据了。首先来获取下所有的列(引入相应的jar就不过多介绍了)

[Java] 纯文本查看 复制代码
        public static void main(String[] args) throws Exception {
                Document doc = Jsoup.connect("http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201703/t20170310_1471429.html").get();
                Elements links = doc.select(".MsoNormal");
                for (Element element : links) {
                        System.out.println("----------------------");
                        Elements elementsSpan = element.getElementsByTag("span");
                        System.out.println(elementsSpan.size() + "size");
                        for (int i = 0; i < elementsSpan.size(); i++) {
                                System.out.println(i + "------>" + elementsSpan.get(i).text());
                        }
                        System.out.println("---");
                }
        }


得到了这样子的数据之后我们需要获得两个数据 1 行政编码 2 行政编码对应的行政区域名称
根据结果我们发现:
[Java] 纯文本查看 复制代码
4size
0------>  
1------>659004
2------>
3------>  五家渠市
---
----------------------
4size
0------>  
1------>659006
2------>
3------>  铁门关市
---
----------------------
3size
0------>710000
1------>
2------>台湾省
---
----------------------
3size
0------>810000
1------>
2------>香港特别行政区
---
----------------------

有两种数据 :
大小是4的 获取  行政编码   行政编码对应的行政区域名称分别是要取 集合中下标是1 和 3的
大小是3的 获取  行政编码   行政编码对应的行政区域名称分别是要取 集合中下标是0 和 2的
写个if判断然后存到数据库里这样行政代码就导入成功了。
以下列出全部代码:
[Java] 纯文本查看 复制代码
public static void main(String[] args) throws Exception {
                //连接数据库对象
                Connection connection = getConnection();
                //执行sql statement对象
                Statement statement = connection.createStatement();
                //获取网页document对象
                Document doc = Jsoup.connect("http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201703/t20170310_1471429.html").get();
                //获取class为MsoNormal (获取所有行)
                Elements links = doc.select(".MsoNormal");
               
                for (Element element : links) {
                        System.out.println("----------------------");
                        //获取某一行的 数据 根据span区分
                        Elements elementsSpan = element.getElementsByTag("span");
                        if(elementsSpan.size() == 4){
                                String strCode =  elementsSpan.get(1).text();
                                int code = Integer.parseInt(strCode);
                                //去重
                                String name = elementsSpan.get(3).text().replace(" ", "");
                                System.out.println(code + name);
                                doAdd(connection,statement, code, name);
                        }else if(elementsSpan.size() == 3){
                                String strCode =  elementsSpan.get(0).text();
                                int code = Integer.parseInt(strCode);
                                //去重
                                String name = elementsSpan.get(2).text().replace(" ", "");
                                System.out.println(code + name);
                                doAdd(connection,statement, code, name);
                        }
                        
                        System.out.println("---");
                }
                //批量执行
                statement.executeBatch();
                //关闭statement
                statement.close();
        }
        
        //获取连接
        public static Connection getConnection(){
                Connection conn= null;
                String url="jdbc:mysql://127.0.0.1:3306/skeleton_shiro";
                String user = "root";
                String password="root";
                try {
                        //获取mysql驱动
                        Class.forName("com.mysql.jdbc.Driver");
                        //链接数据库
                        conn=DriverManager.getConnection(url, user, password);
                        return conn;
                } catch (Exception e) {
                        e.printStackTrace();
                }
                return conn;
        }
        //将sql放入statement
        public static void doAdd(Connection conn,Statement statement,  int code, String name){
                        try {
                                statement.addBatch("INSERT INTO b_administrative_divisions (acode,aname) VALUES("+code+",'"+name+"')");
                        } catch (SQLException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
        }
至此我们的数据已经保存在数据库中了。
下面就要在页面中去级联展示了。
首先我们来一起分析下如何从数据库中展示出所有省份,以及某个省份下面的所有市
首先分析下行政区划的编码:一共6位 前两位 一样的代表是一个省,后四位为0的代表这个省的名称 后四位不为0代表这个省的某个市或者县。
由此可得 展示出所有省份的sql:
[SQL] 纯文本查看 复制代码
select * from b_administrative_divisions where acode%10000 = 0

展示出某个省下的所有市或县的sql(以北京为例 北京前两位为11):
[AppleScript] 纯文本查看 复制代码
select * from b_administrative_divisions where LEFT(acode,2)=11 and acode%10000 != 0

通过这两个sql我们就可以查出我们所需要的所有信息了。

前台页面需要两个select标签:
[HTML] 纯文本查看 复制代码
 <div class="col-md-4">
                                        <select class="form-control m-b" id="province" name="province"></select>
                                    </div>
                                    <div class="col-md-4">
                                        <select class="form-control m-b" id="city" name="city"></select>
                                    </div>
                                </div>


加载省级select
前台:
[JavaScript] 纯文本查看 复制代码
    $(function () {
        $.ajax({
            type: 'POST',
            url: "/admin/housekeeping/getProvince",
            // data: data ,
            success: function (data) {
                for (var i = 0; i < data.length; i++) {
                    $("#province").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
                }
            }
        });
    })

后台:
[Java] 纯文本查看 复制代码
    /**
     * 获取所有省份id
     * @return
     */
    @RequestMapping("/getProvince")
    @ResponseBody
    public List getProvince() {
       EntityWrapper<Administrative_divisions> wrapper = new EntityWrapper();
        wrapper.where("acode%10000 = 0");
        List<Administrative_divisions> alist = administrative_divisionsService.selectList(wrapper);
        return alist;
    }

下面就是如何加载市级的列表
前台:
[JavaScript] 纯文本查看 复制代码
$("#province").change(function(){
    $("#city").empty();
var pid = $("#province").val()
    $.ajax({
        type: 'POST',
        url: "/admin/housekeeping/getCity",
         data: {"provinceId":pid} ,
        success: function (data) {
            for (var i = 0; i < data.length; i++) {
                $("#city").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
            }
        }
    });

});


这块要做这么几件事
1:需要获取选择省份的id
2:要删除市级select中的所有option数据
3:查询出所有省份下的市级内容并且放入市的select中

后台:
[Java] 纯文本查看 复制代码
   /**
     * 根据省份id获取市
     * @param provinceId
     * @return
     */
    @RequestMapping("/getCity")
    @ResponseBody
    public List getCity(int provinceId) {
        int cityId = provinceId/10000;
        EntityWrapper<Administrative_divisions> wrapper = new EntityWrapper();
        wrapper.where("LEFT(acode,2)={0}",cityId).and("acode%10000 != 0");
        List<Administrative_divisions> alist = administrative_divisionsService.selectList(wrapper);
        return alist;
    }


那么现在还有一个问题就是 一开始只是加载了省份 没有加载市级select
所以需要就修改下 :
[JavaScript] 纯文本查看 复制代码
    $(function () {
        $.ajax({
            type: 'POST',
            url: "/admin/housekeeping/getProvince",
            // data: data ,
            success: function (data) {
                for (var i = 0; i < data.length; i++) {
                    $("#province").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
                }
                $.ajax({
                    type: 'POST',
                    url: "/admin/housekeeping/getCity",
                    data: {"provinceId": data[0].acode} ,
                    success: function (data) {
                        for (var i = 0; i < data.length; i++) {
                            $("#city").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
                        }
                    }
                });

            }
        });
    })

上一张 完成的效果图:

效果图





我只是做了一个两级级联的功能那么三级级联道理其实市一样的。有兴趣的同学可以自己去试试,有什么问题可以直接和我联系。


附前台js代码:
[JavaScript] 纯文本查看 复制代码
    $(function () {
        var provinceId = getProvince();
        var cityId = getCity(provinceId);
        var district = getDistrict(cityId);
    });

    $("#province").change(function () {
        $("#city").empty();
        $("#district").empty();
        var provinceId = $("#province").val();
        var cityId = getCity(provinceId);
        var district = getDistrict(cityId);

    });
    $("#city").change(function () {
        $("#district").empty();
        var cityId = $("#city").val();
        var district = getDistrict(cityId);

    });


    function getProvince() {
        var firstProvince;
        $.ajax({
            type: 'POST',
            url: "/admin/housekeeping/getProvince",
            async: false,
            // data: data ,
            success: function (data) {
                firstProvince = data[0].acode;
                console.log("firstProvince:" + firstProvince)
                for (var i = 0; i < data.length; i++) {
                    $("#province").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
                }
            }
        });
        return firstProvince;

    }

    function getCity(provinceId) {
        var firstCity;
        $.ajax({
            type: 'POST',
            url: "/admin/housekeeping/getCity",
            async: false,
            data: {"provinceId": provinceId},
            success: function (data) {
                if(data != null && data.length >0){
                    firstCity = data[0].acode;
                    console.log("firstCity:" + firstCity);
                    for (var i = 0; i < data.length; i++) {
                        $("#city").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
                    }
                }

            }
        });

        return firstCity;
    }

    function getDistrict(cityId) {
        var firstDistrict;

        $.ajax({
            type: 'POST',
            url: "/admin/housekeeping/getDistrict",
            data: {"cityId": cityId},
            success: function (data) {
                if(data != null && data.length >0){
                    firstDistrict = data[0].acode;
                    console.log("firstDistrict:" + firstDistrict);
                    for (var i = 0; i < data.length; i++) {
                        $("#district").append("<option value='" + data.acode + "'>" + data.aname + "</option>");
                    }
                }

            }
        });

        return firstDistrict;
    }

后台代码:

[Java] 纯文本查看 复制代码
    /**
     * 获取所有省份id
     * @return
     */
    @RequestMapping("/getProvince")
    @ResponseBody
    public List getProvince() {
       EntityWrapper<Administrative_divisions> wrapper = new EntityWrapper();
        wrapper.where("acode%10000 = 0");
        List<Administrative_divisions> alist = administrative_divisionsService.selectList(wrapper);
        return alist;
    }

    /**
     * 根据省份id获取市
     * @param provinceId
     * @return
     */
    @RequestMapping("/getCity")
    @ResponseBody
    public List getCity(@RequestParam int provinceId) {
        int cityId = provinceId/10000;
        EntityWrapper<Administrative_divisions> wrapper = new EntityWrapper();
        wrapper.where("LEFT(acode,2)={0}",cityId).and("acode%10000 != 0").and("acode%100 = 0");
        List<Administrative_divisions> alist = administrative_divisionsService.selectList(wrapper);
        return alist;
    }

    /**
     * 根据城市id获取地区
     * @param
     * @return
     */
    @RequestMapping("/getDistrict")
    @ResponseBody
    public List getDistrict(@RequestParam int cityId) {
        int districtId = cityId/100;
        EntityWrapper<Administrative_divisions> wrapper = new EntityWrapper();
        wrapper.where("LEFT(acode,4)={0}",districtId).and("acode%10000 != 0").and("acode%100 != 0");
        List<Administrative_divisions> alist = administrative_divisionsService.selectList(wrapper);
        return alist;
    }


作者: 尹哈哈哈    时间: 2017-12-4 14:17
支持下楼主




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2