省市区 三级联动,Vue+SpringDataJpa实现

Posted autonomy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了省市区 三级联动,Vue+SpringDataJpa实现相关的知识,希望对你有一定的参考价值。

1.使用elementui中的下拉框

 注意:这里都是使用前后端分离的模式来写的,所以需要安装好node.js和vue的环境

 1.数据库文件,完整文件:https://files.cnblogs.com/files/autonomy/%E7%9C%81%E5%B8%82%E4%B8%89%E7%BA%A7%E8%81%94%E5%8A%A8.rar

  a>省份

 1 DROP TABLE IF EXISTS `t_address_province`;
 2 CREATE TABLE `t_address_province`  (
 3   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,
 4   `code` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 省份编码,
 5   `name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 省份名称,
 6   PRIMARY KEY (`id`) USING BTREE
 7 ) ENGINE = InnoDB AUTO_INCREMENT = 35 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 省份信息表 ROW_FORMAT = Compact;
 8 
 9 -- ----------------------------
10 -- Records of t_address_province
11 -- ----------------------------
12 INSERT INTO `t_address_province` VALUES (1, 110000, 北京市);
13 INSERT INTO `t_address_province` VALUES (2, 120000, 天津市);
14 INSERT INTO `t_address_province` VALUES (3, 130000, 河北省);
15 INSERT INTO `t_address_province` VALUES (4, 140000, 山西省);

 

  b>城市

 1 DROP TABLE IF EXISTS `t_address_city`;
 2 CREATE TABLE `t_address_city`  (
 3   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,
 4   `code` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 城市编码,
 5   `name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 城市名称,
 6   `province_code` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 所属省份编码,
 7   PRIMARY KEY (`id`) USING BTREE
 8 ) ENGINE = InnoDB AUTO_INCREMENT = 346 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 城市信息表 ROW_FORMAT = Compact;
 9 
10 -- ----------------------------
11 -- Records of t_address_city
12 -- ----------------------------
13 INSERT INTO `t_address_city` VALUES (1, 110100, 北京市, 110000);
14 INSERT INTO `t_address_city` VALUES (2, 1102xx, 北京下属县, 1100xx);
15 INSERT INTO `t_address_city` VALUES (3, 120100, 天津市, 120000);
16 INSERT INTO `t_address_city` VALUES (4, 1202xx, 天津下属县, 1200xx);

  c>城区

DROP TABLE IF EXISTS `t_address_town`;
CREATE TABLE `t_address_town`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,
  `code` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 区县编码,
  `name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 区县名称,
  `city_code` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 所属城市编码,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3145 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 区县信息表 ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_address_town
-- ----------------------------
INSERT INTO `t_address_town` VALUES (1, 110101, 东城区, 110100);
INSERT INTO `t_address_town` VALUES (2, 110102, 西城区, 110100);
INSERT INTO `t_address_town` VALUES (3, 110103, 崇文区, 110100);
INSERT INTO `t_address_town` VALUES (4, 110104, 宣武区, 110100);
INSERT INTO `t_address_town` VALUES (5, 110105, 朝阳区, 110100);

2.实体类代码,注意:实体类中最好不要重写tostrig方法,数据量太大,会报错。

/**
 * 省份
 */
@Entity
@Table(name = "t_address_province")
public class Province implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",updatable = false,insertable = false)
    private int id;

    @Column(name = "code")
    private String code;//省份编码

    @Column(name = "name")
    private String name;    //省份名称

    /**
     *   一个省份对应多个城市
     *     @JoinColumn
     *      name:来自从表,指向另一个表的外键,也就是城市表中的外键
     *      referencedColumnName:来自主表
     *
     */

    @OneToMany(targetEntity = City.class,fetch =FetchType.EAGER)
    @JoinColumn(name = "province_code",referencedColumnName = "code")
    private Set<City> cityList = new HashSet<>();
/**
 * 城市
 */
@Entity
@Table(name = "t_address_city")
public class City implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",insertable = false,updatable = false)
    private int id;

    @Column(name = "code")
    private String code;

    @Column(name = "name")
    private String name;

    @Column(name = "province_code")
    private String provinceCode;

    /**
     * 一个城市对应多个城区
     *
     */
    @OneToMany(targetEntity = Town.class,fetch = FetchType.LAZY)
    @JoinColumn(name = "city_code",referencedColumnName = "code")
    private Set<Town> areaList = new HashSet<>();
/**
 *  城区
 */

@Entity
@Table(name = "t_address_town")
public class Town {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",insertable = false,updatable = false)
    private int id;

    @Column(name = "code")
    private String code;

    @Column(name = "name")
    private String name;

    @Column(name = "city_code")
    private String cityCode;

2.dao层,只需要写城市表的数据访问层就行,可以通过一对多关系,查询到其他相关数据

@Repository
public interface ProvinceDao extends JpaRepository<Province,Integer> {}

3.service层。

@Service
@Transactional
public class ProvinceService {
    @Autowired
    private ProvinceDao provinceDao;
    public List<Province> findProvince(){
        return provinceDao.findAll();
    }
}

4.web层

@RestController
public class JlController {
    @Autowired
    private ProvinceService provinceService;
    @GetMapping("province")
    public List<Province> findProvince(){
        return provinceService.findProvince();
    }
}

5.因为是前后端分离模式开发,需要解决跨域的问题,这里从后端解决,写一个配置类。

@Configuration
public class CorsConfig {
    // 初始化 CorsConfiguration 对象并设置允许的域名、请求头部信息和请求方式
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 允许任何域名使用
        corsConfiguration.addAllowedHeader("*"); // 2 允许任何头
        corsConfiguration.addAllowedMethod("*"); // 3 允许任何方法(post、get 等)
        return corsConfiguration;
    }
    /**
     * 创建 CorsFilter 对象
     * @return CorsFilter
     */
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new
                UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); //拦截所有请求
        return new CorsFilter(source);
    }
}

6.使用postman测试

  返回部分结果:

  

[
    {
        "id": 1,
        "code": "110000",
        "name": "北京市",
        "cityList": [
            {
                "id": 1,
                "code": "110100",
                "name": "北京市",
                "provinceCode": "110000",
                "areaList": [
                    {
                        "id": 6,
                        "code": "110106",
                        "name": "丰台区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 8,
                        "code": "110108",
                        "name": "海淀区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 14,
                        "code": "110115",
                        "name": "大兴区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 10,
                        "code": "110111",
                        "name": "房山区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 15,
                        "code": "110116",
                        "name": "怀柔区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 16,
                        "code": "110117",
                        "name": "平谷区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 3,
                        "code": "110103",
                        "name": "崇文区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 17,
                        "code": "110228",
                        "name": "密云县",
                        "cityCode": "110100"
                    },
                    {
                        "id": 1,
                        "code": "110101",
                        "name": "东城区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 2,
                        "code": "110102",
                        "name": "西城区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 12,
                        "code": "110113",
                        "name": "顺义区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 4,
                        "code": "110104",
                        "name": "宣武区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 13,
                        "code": "110114",
                        "name": "昌平区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 7,
                        "code": "110107",
                        "name": "石景山区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 11,
                        "code": "110112",
                        "name": "通州区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 18,
                        "code": "110229",
                        "name": "延庆县",
                        "cityCode": "110100"
                    },
                    {
                        "id": 5,
                        "code": "110105",
                        "name": "朝阳区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 9,
                        "code": "110109",
                        "name": "门头沟区",
                        "cityCode": "110100"
                    }
                ]
            }
        ]
    },
    。。。。。
】

7.前端代码,引如element和axios

  

import ElementUI from ‘element-ui‘
import ‘element-ui/lib/theme-chalk/index.css‘
import axios from ‘axios‘
import VueAxios from ‘vue-axios‘

Vue.use(VueAxios, axios)
Vue.use(ElementUI)

 

8.使用element的下拉框
<b-col md="6">
    <label >省</label>
    <el-select v-model="provinceValue" placeholder="请选择省" @change="chooseProvince">
        <el-option    
            v-for="item in provinceData"
            :key="item.code"
            :label="item.name"
            :value="item.name">
        </el-option>
    </el-select>
</b-col>
<b-col md="6">
    <label >市</label>
    <el-select v-model="cityValue" placeholder="请选择市" @change="chooseCity">
        <el-option    
            v-for="item in cityData"
            :key="item.code"
            :label="item.name"
            :value="item.name">
        </el-option>
    </el-select>
</b-col>
<b-col md="6">
    <label >区、县</label>
    <el-select v-model="areaValue" @change="chooseArea" placeholder="请选择区、县">
        <el-option
            v-for="item in areaData"
            :key="item.code"
            :label="item.name"
            :value="item.name">
        </el-option>
    </el-select>
</b-col>

9.script代码

 

axios.get(‘http://localhost:8082/province‘).then(res=>{
                this.provinceData = res.data;
                console.log(res)
            }).catch(e => {
                this.$message.error("网络连接超时");
            })
  },
 
data () {
    return {
        areaData: [],
        provinceValue:‘‘,
        cityValue:‘‘,
        areaValue:‘‘,
        provinceData:[],
        cityData:[],
        areaData:[],
                
    }
  },

  methods: {
    chooseProvince(value){
                this.cityValue = ‘‘;
                this.areaValue = ‘‘;
                this.cityData = [];
                this.areaData = [];
        this.provinceData.map(e=>{ //遍历数据
        //console.log(e.name)
                    if( value == e.name){
            console.log(value)
                        this.cityData = e.cityList;
                        return;
                    }
                })
            },
            chooseCity(value){
                this.areaValue = ‘‘;
                this.cityData.map(e=>{//遍历数据
                    if( value == e.name){
                        this.areaData = e.areaList;
                        return;
                    }
                })
            },
            chooseArea(){
            }
  },
//记得引入axios
  const axios = require("axios")
 

 

10. 页面效果

技术图片

 

 

 

 

 

 

2.使用elementUi提供的cascader组件。

1. 前端代码,环境和第一种方法一样。

 <el-cascader
        v-model="dataModel"
        placeholder="请选择地区"
          :props="{ expandTrigger: ‘hover‘ }"
        :options="areaData2"
      >
  </el-cascader

2. script

 data () {
    return {
        dataModel:‘‘,
        areaData2:[]
    }
  },
created(){
  axios.get(‘http://localhost:8083/getprovince‘).then(res=>{
                this.areaData2 = res.data
                  for (var i = 0; i < this.areaData2.length; i++) {
                    if (this.areaData2[i].children.length == 0) {
                      delete this.areaData2[i].children //解决因为省级区域没有下级市的BUG
                        }
                      }
                console.log(res.data)
                //console.log(res)
            }).catch(e => {
                this.$message.error("网络连接超时");
            })
},

 

 3.java代码,需要改写实体类,因为cascader组件迭代的参数为 :value,:label。实体类中需要将城市编码code改为value,城市名称name改为label。同时将1对多字段全部改为children。

/**
 * 城市表
 */
@Entity
@Table(name = "t_address_city")
public class City implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",insertable = false,updatable = false)
    private int id;

    @Column(name = "code")
    private String value;   //城市编码

    @Column(name = "name")
    private String label;   //城市名称

    @Column(name = "province_code")
    private String provinceCode;

    /**
     * 一个城市对应多个城区
     */
    @OneToMany(targetEntity = Town.class,fetch = FetchType.LAZY)
    @JoinColumn(name = "city_code",referencedColumnName = "code")
    private Set<Town> children = new HashSet<>();
/**
 * 省份表
 */
@Entity
@Table(name = "t_address_province")
public class Province implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",updatable = false,insertable = false)
    private int id;

    @Column(name = "code")
    private String value;//省份编码

    @Column(name = "name")
    private String label;    //省份名称

    //一个省份对应多个城市
    @OneToMany(targetEntity = City.class,fetch =FetchType.EAGER)
    @JoinColumn(name = "province_code",referencedColumnName = "code")
    private Set<City> children = new HashSet<>();
/**
 * 城区
 */
@Entity
@Table(name = "t_address_town")
public class Town {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",insertable = false,updatable = false)
    private int id;

    @Column(name = "code")
    private String value; //城市编码

    @Column(name = "name")  //城市名称
    private String label;

 

4 测试返回部分结果

  

[
    {
        "id": 1,
        "value": "110000",
        "label": "北京市",
        "children": [
            {
                "id": 1,
                "value": "110100",
                "label": "北京市",
                "provinceCode": "110000",
                "children": [
                    {
                        "id": 11,
                        "value": "110112",
                        "label": "通州区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 13,
                        "value": "110114",
                        "label": "昌平区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 1,
                        "value": "110101",
                        "label": "东城区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 16,
                        "value": "110117",
                        "label": "平谷区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 4,
                        "value": "110104",
                        "label": "宣武区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 12,
                        "value": "110113",
                        "label": "顺义区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 6,
                        "value": "110106",
                        "label": "丰台区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 9,
                        "value": "110109",
                        "label": "门头沟区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 7,
                        "value": "110107",
                        "label": "石景山区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 5,
                        "value": "110105",
                        "label": "朝阳区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 14,
                        "value": "110115",
                        "label": "大兴区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 18,
                        "value": "110229",
                        "label": "延庆县",
                        "cityCode": "110100"
                    },
                    {
                        "id": 17,
                        "value": "110228",
                        "label": "密云县",
                        "cityCode": "110100"
                    },
                    {
                        "id": 2,
                        "value": "110102",
                        "label": "西城区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 3,
                        "value": "110103",
                        "label": "崇文区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 8,
                        "value": "110108",
                        "label": "海淀区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 15,
                        "value": "110116",
                        "label": "怀柔区",
                        "cityCode": "110100"
                    },
                    {
                        "id": 10,
                        "value": "110111",
                        "label": "房山区",
                        "cityCode": "110100"
                    }
                ]
            }
        ]
    },
。。。
]

 

5. 页面效果

技术图片

 

 

 

以上是关于省市区 三级联动,Vue+SpringDataJpa实现的主要内容,如果未能解决你的问题,请参考以下文章

vue.js实现省市区三级联动

使用vue+element ui 实现省市区三级联动

vue 省市区三级联动

省市区 三级联动,Vue+SpringDataJpa实现

vue中搭配element ui实现省市区三级联动

vue中搭配element ui实现省市区三级联动