省市区 三级联动,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实现的主要内容,如果未能解决你的问题,请参考以下文章