Spring Boot + Ajax前后端分离实现三级联动
引言
本项目为前后端分离的项目,前端采用Ajax技术,后端采用Spring Boot实现前后端分离,一个简单的案例,让你更加理解前后端分离的好处
需求描述
在静态页面写调用服务端接口,获取省、市、县区的数据
调用接口后显示在静态页面上,初始化时应该加载省份信息,当选择省份后,后面的加载出对应的市,选择市后,后面加载出对应的县区
当选中一个后,想切换另一个,需要将之前的选择数据清空再加载对应的数据
技术栈介绍:前端采用Ajax、Jquery、Bootstrap框架,后端采用SpringBoot
请求采用Ajax,后端皆为Post请求
效果图
数据表准备
t_province省份表
CREATE TABLE `t_county` (
`id` int(255) DEFAULT NULL,
`name` varchar(765) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`parent_id` int(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
t_city市区表
CREATE TABLE `t_city` (
`id` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`name` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`parent_id` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
t_county县区表
CREATE TABLE `t_county` (
`id` int(255) DEFAULT NULL,
`name` varchar(765) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`parent_id` int(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
==注意:由于数据过大,我会上传sql文件至百度网盘,需要的小伙伴可以在文末下载哦~==
项目结构
后端结构
前端为一个html页面,引用了Bootstrap框架
注意:文末有百度网盘项目源码
核心源码
前端核心
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<body>
<div style="padding: 20px;">
<label>
行政地区:
</label>
<div class="form-inline">
<div class="form-group">
<select id="province" class="form-control">
<option value="">请选择省</option>
</select>
</div>
<div class="form-group" >
<select id="city" class="form-control" onchange="loadCounty()">
<option value="">请选择市</option>
</select>
</div>
<div class="form-group">
<select id="county" class="form-control">
<option value="">请选择县区</option>
</select>
</div>
</div>
</div>
</body>
</html>
<script src="js/jquery-3.6.0.js"></script>
<script>
//初始化时加载此函数
$(function () {
//初始化时加载所有省份
loadProvince();
//当选择省份后加载所选择省份的市区
$("#province").change(function () {
let obj = $("#province").val();
let url = "http://localhost:8345/springbootajax/ajax4/list_city";
let data = JSON.stringify({parent_id:obj});
$.ajax({
url,
data,
type:'post',
contentType : 'application/json;charset=utf-8',
success(res) {
//删除之前选择的记录
$("option").remove('.op1');
res.data.map((obj) => {
$("#city").append("<option class='op1' value='"+obj.id+"'>"+obj.name+"</option>")
})
}
})
});
//当市区选择后加载选择市区的县区
$("#city").change(function () {
let obj = $("#city").val();
let url = "http://localhost:8345/springbootajax/ajax4/list_county";
let data = JSON.stringify({parent_id:obj});
$.ajax({
url,
data,
type:'post',
contentType : 'application/json;charset=utf-8',
success(res) {
console.log(res);
//删除之前选择的记录
$("#county option").remove('.op1');
res.data.map((obj) => {
$("#county").append("<option class='op1' value='"+obj.id+"'>"+obj.name+"</option>")
})
}
})
})
})
//加载所有省份
function loadProvince() {
let url = "http://localhost:8345/springbootajax/ajax4/list_province";
let data = {};
$.post(url, data, function (res) {
res.data.map((obj) => {
$("#province").append("<option value='"+obj.id+"'>"+obj.name+"</option>");
})
}, 'json');
}
</script>
后端核心
pom依赖文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wanshi</groupId>
<artifactId>test_springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test_springboot</name>
<description>test_springboot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.5</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.juniversalchardet</groupId>
<artifactId>juniversalchardet</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>libs/</directory>
<targetPath>libs</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</resources>
</build>
</project>
ResultBean统一返回风格类
package com.wanshi.bean;
public class ResultBean<C> {
private Integer code;
private String msg;
private C data;
private ResultBean(Integer code, String msg, C data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static ResultBean create(Integer code, String msg, Object data) {
ResultBean res = new ResultBean(code, msg, data);
return res;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public C getData() {
return data;
}
public void setData(C data) {
this.data = data;
}
}
XingzhengMapper数据访问层
package com.wanshi.mapper;
import com.wanshi.bean.City;
import com.wanshi.bean.County;
import com.wanshi.bean.Province;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface XingzhengMapper {
@Select("select * from t_province")
List<Province> listProvince();
@Select("select * from t_city where parent_id = #{parent_id}")
List<City> listCity(City param);
@Select("select * from t_county where parent_id = #{parent_id}")
List<County> listCounty(County param);
}
XingzhengService核心业务类
package com.wanshi.service;
import com.wanshi.bean.City;
import com.wanshi.bean.County;
import com.wanshi.bean.Province;
import com.wanshi.bean.ResultBean;
import com.wanshi.mapper.XingzhengMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class XingzhengService {
@Autowired
private XingzhengMapper xingzhengMapper;
public ResultBean<List<Province>> listProvince() {
List<Province> provinceList = xingzhengMapper.listProvince();
return ResultBean.create(0, "success", provinceList);
}
public ResultBean<List<City>> listCity(City param) {
List<City> provinceCityList = xingzhengMapper.listCity(param);
return ResultBean.create(0, "success", provinceCityList);
}
public ResultBean<List<County>> listCounty(County param) {
List<County> cityCountyList = xingzhengMapper.listCounty(param);
return ResultBean.create(0, "success", cityCountyList);
}
}
XingzhengController访问层类
package com.wanshi.controller;
import com.wanshi.bean.City;
import com.wanshi.bean.County;
import com.wanshi.bean.Province;
import com.wanshi.bean.ResultBean;
import com.wanshi.service.XingzhengService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@CrossOrigin
@RestController
@RequestMapping("/ajax4")
public class XingzhengController {
@Autowired
private XingzhengService xingzhengService;
@PostMapping("/list_province")
public ResultBean<List<Province>> listProvince() {
ResultBean<List<Province>> res = xingzhengService.listProvince();
return res;
}
@PostMapping("/list_city")
public ResultBean<List<City>> listCity(@RequestBody City param) {
ResultBean<List<City>> res = xingzhengService.listCity(param);
return res;
}
@PostMapping("/list_county")
public ResultBean<List<County>> listCounty(@RequestBody County param) {
ResultBean<List<County>> res = xingzhengService.listCounty(param);
return res;
}
}
SpringBootRunApplication主启动类
@EnableTransactionManagement
//扫描mapper层的包存入springioc容器
@MapperScan("com.wanshi.mapper")
@SpringBootApplication
public class TestSpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(TestSpringbootApplication.class, args);
}
}
结语
本项目为前后端分离的一个小项目,项目不难,逻辑稍微有点复杂,但也是简单的,通过本项目,相信你不断的练习,注入实战开发,你的开发能力会有一个质的飞跃,加油~
项目源码地址(百度网盘):https://pan.baidu.com/s/1dal4kZxxlGt6CSwZd9NWGg 提取码: jrqu