SpringCloud微服务之学生管理
1.环境搭建
1.1 架构分析
- 注册中心:Nacos
- 网关:Gateway
- 后端基础框架:ssm
- 前端:Vue + SPA
- Axios(request.js)
1.2 数据库环境
1.2.1 学生数据库
#学生数据库
CREATE DATABASE nacos_ssm_student;
USE nacos_ssm_student;CREATE TABLE tb_city(c_id VARCHAR(32) PRIMARY KEY COMMENT '城市ID',city_name VARCHAR(20) COMMENT '城市名称' ,parent_id VARCHAR(32) COMMENT '父ID'
);INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320000','江苏省','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140000','山西省','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130000','河北省','0');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320100','南京市','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320102','玄武区','320100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320103','白下区','320100');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321300','宿迁市','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321322','沭阳县','321300');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321323','泗阳县','321300');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140100','太原市','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140106','迎泽区','140100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140108','尖草坪区','140100');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140800','运城市','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140823','闻喜县','140800');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140828','夏 县','140800');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130100','石家庄市','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130127','高邑县','130100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130185','鹿泉市','130100');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131000','廊坊市','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131003','广阳区','131000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131022','固安县','131000');CREATE TABLE `tb_student` (`s_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',`sname` VARCHAR(50) DEFAULT NULL COMMENT '姓名',`age` INT(11) DEFAULT NULL COMMENT '年龄',`birthday` DATETIME DEFAULT NULL COMMENT '生日',`gender` CHAR(1) DEFAULT NULL COMMENT '性别',`c_id` INT DEFAULT NULL,`city_ids` VARCHAR(32) DEFAULT NULL COMMENT '城市:320000,321300,321322'
);INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (1,'赵三33',21,'2001-01-17 00:00:00','1',1,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (2,'钱四444',1900,'2001-05-16 00:00:00','1',2,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (3,'孙五56',189,'2022-03-15 00:00:00','0',1,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (4,'张三',20,'2020-12-21 00:00:00','0',2,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (5,'xxx',18,'2020-12-21 00:00:00','0',2,'140000,140800,140823');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (6,'123',18,'2020-11-01 00:00:00','0',3,'130000,130100,130127');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (7,'xx',18,'2020-11-02 00:00:00','0',1,'130000,131000,131003');
1.2.2 用户数据库
# 用户数据库
CREATE DATABASE nacos_ssm_user;
USE nacos_ssm_user;CREATE TABLE `tb_user` (`u_id` VARCHAR(32) PRIMARY KEY NOT NULL COMMENT '用户编号',`user_name` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT '用户名',`password` VARCHAR(32) DEFAULT NULL COMMENT '密码',`gender` BIT(1) DEFAULT NULL COMMENT '性别,1表示男,0表示女',`image` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT '头像图片'
);INSERT INTO `tb_user`(`u_id`,`user_name`,`password`,`gender`,`image`) VALUES ('u001','jack','1234',1,'1.jpg');
INSERT INTO `tb_user`(`u_id`,`user_name`,`password`,`gender`,`image`) VALUES ('u002','rose','1234',0,'2.jpg');
INSERT INTO `tb_user`(`u_id`,`user_name`,`password`,`gender`,`image`) VALUES ('u003','tom','1234',1,'3.jpg');
1.2.3 班级数据库
# 班级数据库
CREATE DATABASE nacos_ssm_classes;
USE nacos_ssm_classes;CREATE TABLE `tb_teacher` (`tid` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,`tname` VARCHAR(50) DEFAULT NULL COMMENT '老师姓名',`type` INT(11) DEFAULT NULL COMMENT '老师类型:1.授课老师、2.助理老师、3.辅导员老师'
);
INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (1,'梁桐老师',1);
INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (2,'马坤老师',2);
INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (3,'仲燕老师',3);
INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (4,'袁新奇老师',1);
INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (5,'任林达老师',2);
INSERT INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (6,'王珊珊老师',3);CREATE TABLE `tb_class` (`cid` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,`cname` VARCHAR(50) DEFAULT NULL COMMENT '班级名称',`teacher1_id` INT(11) DEFAULT NULL COMMENT '授课老师',`teacher2_id` INT(11) DEFAULT NULL COMMENT '助理老师',`teacher3_id` INT(11) DEFAULT NULL COMMENT '辅导员老师'
);INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (1,'Java56',1,2,3);
INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (2,'Java78',1,2,3);
INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (3,'Java12',4,5,6);
INSERT INTO `tb_class`(`cid`,`cname`,`teacher1_id`,`teacher2_id`,`teacher3_id`) VALUES (4,'Java34',4,5,6);
1.2.4 学生数据库
#学生数据库
CREATE DATABASE nacos_ssm_student;
USE nacos_ssm_student;CREATE TABLE tb_city(c_id VARCHAR(32) PRIMARY KEY COMMENT '城市ID',city_name VARCHAR(20) COMMENT '城市名称' ,parent_id VARCHAR(32) COMMENT '父ID'
);INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320000','江苏省','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140000','山西省','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130000','河北省','0');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320100','南京市','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320102','玄武区','320100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320103','白下区','320100');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321300','宿迁市','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321322','沭阳县','321300');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321323','泗阳县','321300');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140100','太原市','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140106','迎泽区','140100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140108','尖草坪区','140100');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140800','运城市','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140823','闻喜县','140800');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140828','夏 县','140800');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130100','石家庄市','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130127','高邑县','130100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130185','鹿泉市','130100');INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131000','廊坊市','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131003','广阳区','131000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131022','固安县','131000');CREATE TABLE `tb_student` (`s_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',`sname` VARCHAR(50) DEFAULT NULL COMMENT '姓名',`age` INT(11) DEFAULT NULL COMMENT '年龄',`birthday` DATETIME DEFAULT NULL COMMENT '生日',`gender` CHAR(1) DEFAULT NULL COMMENT '性别',`c_id` INT DEFAULT NULL,`city_ids` VARCHAR(32) DEFAULT NULL COMMENT '城市:320000,321300,321322'
);INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (1,'赵三33',21,'2001-01-17 00:00:00','1',1,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (2,'钱四444',1900,'2001-05-16 00:00:00','1',2,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (3,'孙五56',189,'2022-03-15 00:00:00','0',1,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (4,'张三',20,'2020-12-21 00:00:00','0',2,'320000,321300,321322');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (5,'xxx',18,'2020-12-21 00:00:00','0',2,'140000,140800,140823');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (6,'123',18,'2020-11-01 00:00:00','0',3,'130000,130100,130127');
INSERT INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (7,'xx',18,'2020-11-02 00:00:00','0',1,'130000,131000,131003');
1.3 后端环境
1.3.1 父项目
步骤:
- 步骤1:创建项目 nacos-ssm-student
- 步骤2:添加坐标
步骤1:创建项目
步骤2:添加坐标:
<!-- 1 确定spring boot的版本--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.5.RELEASE</version></parent><!--2 确定版本--><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version><spring-cloud-release.version>Hoxton.SR3</spring-cloud-release.version><nacos.version>1.1.0</nacos.version><alibaba.cloud.version>2.2.1.RELEASE</alibaba.cloud.version><mybatis.starter.version>1.3.2</mybatis.starter.version><mapper.starter.version>2.0.2</mapper.starter.version><mysql.version>5.1.32</mysql.version><pageHelper.starter.version>1.2.5</pageHelper.starter.version><durid.starter.version>1.1.10</durid.starter.version><swagger.version>2.7.0</swagger.version><jwt.jjwt.version>0.9.0</jwt.jjwt.version><jwt.joda.version>2.9.7</jwt.joda.version><beanutils.version>1.9.3</beanutils.version><student.version>1.0-SNAPSHOT</student.version></properties><!-- 3 锁定版本--><dependencyManagement><dependencies><!-- sprig cloud--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud-release.version}</version><type>pom</type><scope>import</scope></dependency><!--nacos --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>${nacos.version}</version></dependency><!--nacos cloud 发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>${alibaba.cloud.version}</version></dependency><!--nacos cloud 配置 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>${alibaba.cloud.version}</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>${alibaba.cloud.version}</version></dependency><!-- mybatis启动器 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.starter.version}</version></dependency><!-- 通用Mapper启动器 --><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>${mapper.starter.version}</version></dependency><!-- 分页助手启动器 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pageHelper.starter.version}</version></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- Druid连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${durid.starter.version}</version></dependency><!--swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version></dependency><!--jwt--><!--JavaBean工具类,用于JavaBean数据封装--><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>${beanutils.version}</version></dependency><!--jwt工具--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.jjwt.version}</version></dependency><!--joda 时间工具类 --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${jwt.joda.version}</version></dependency><!-- 自定义项目 --><dependency><groupId>com.czxy</groupId><artifactId>nacos-ssm-student-domain</artifactId><version>${student.version}</version></dependency></dependencies></dependencyManagement>
1.3.2 domain项目
步骤:
- 步骤1:创建项目:nacos-ssm-student-domain
- 步骤2:添加pom
- 步骤3:拷贝vo(BaseResult)
- 步骤4:拷贝JavaBean
步骤1:创建项目:nacos-ssm-student-domain
步骤2:添加pom
<dependencies><!--jpa--><dependency><groupId>javax.persistence</groupId><artifactId>javax.persistence-api</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--jackson--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-json</artifactId></dependency></dependencies>
步骤3:拷贝vo
package com.czxy.vo;import lombok.Getter;import java.util.HashMap; import java.util.Map;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Getter public class BaseResult<T> {//成功状态码public static final int OK = 20000;//失败状态码public static final int ERROR = 0;//返回码private Integer code;//返回消息private String message;//存放数据private T data;//其他数据private Map<String,Object> other = new HashMap<>();public BaseResult() {}public BaseResult(Integer code, String message) {this.code = code;this.message = message;}public BaseResult(Integer code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** 快捷成功BaseResult对象* @param message* @return*/public static BaseResult ok(String message){return new BaseResult(BaseResult.OK , message);}public static BaseResult ok(String message, Object data){return new BaseResult(BaseResult.OK , message, data );}/*** 快捷失败BaseResult对象* @param message* @return*/public static BaseResult error(String message){return new BaseResult(BaseResult.ERROR , message);}/*** 自定义数据区域* @param key* @param msg* @return*/public BaseResult append(String key , Object msg){other.put(key , msg);return this;}}
步骤4:拷贝JavaBean
City
package com.czxy.domain;import lombok.Data;import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable;/*** (TbCity)实体类** @author 桐叔*/ @Table(name = "tb_city") @Data public class City implements Serializable {private static final long serialVersionUID = 660498290955870873L;/*** 城市ID*/@Id@Column(name = "c_id")private String cid;/*** 城市名称*/@Column(name = "city_name")private String cityName;/*** 父ID*/@Column(name = "parent_id")private String parentId;}
Classes
package com.czxy.domain;import lombok.Data;import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Table(name = "tb_class") @Data public class Classes {@Id@Column(name = "cid")private Integer cid;@Column(name = "cname")private String cname; //班级名称@Column(name = "teacher1_id")private Integer teacher1Id; //授课老师@Column(name = "teacher2_id")private Integer teacher2Id; //助理老师@Column(name = "teacher3_id")private Integer teacher3Id; //辅导员老师 }
Course
package com.czxy.domain;import lombok.Data;import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Table(name = "tb_course") @Data public class Course {@Id@Column(name = "c_id")private Integer cid;@Column(name = "cname")private String cname;@Column(name = "`desc`")private String desc;}
Student
package com.czxy.domain;import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data;import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; import java.util.ArrayList; import java.util.Date; import java.util.List;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Table(name = "tb_student") @Data public class Student {@Id@Column(name = "s_id")private Integer sid; //学生ID@Column(name = "sname")private String sname; //姓名@Column(name = "age")private Integer age; //年龄@Column(name = "birthday")@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")private Date birthday; //生日@Column(name = "gender")private String gender; //性别@Column(name = "c_id")private Integer cid; //班级外键@Column(name = "city_ids")private String cityIds; //城市private List<City> cityList; //所选城市@Transientprivate Classes classes; //班级对象@Transientprivate Integer courseCount; //选课数@Transientprivate List<Course> courseList = new ArrayList<>(); //选课详情@Transientprivate List<Integer> courseIds = new ArrayList(); //选课id}
Teacher
package com.czxy.domain;import lombok.Data;import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Table(name = "tb_teacher") @Data public class Teacher {@Id@Column(name = "tid")private Integer tid;@Column(name = "tname")private String tname; //老师姓名@Column(name = "type")private Integer type; //老师类型:1.授课老师、2.助理老师、3.辅导员老师 }
User
package com.czxy.domain;import lombok.Data;import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Table(name = "tb_user") @Data public class User {@Id@Column(name = "u_id")private String uid;@Column(name = "user_name")private String userName;private String password;private Integer gender;private String image; } /* CREATE TABLE `tb_user` (`u_id` VARCHAR(32) PRIMARY KEY NOT NULL COMMENT '用户编号',`user_name` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT '用户名',`password` VARCHAR(32) DEFAULT NULL COMMENT '密码',`gender` BIT(1) DEFAULT NULL COMMENT '性别,1表示男,0表示女',`image` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT '头像图片' );*/
1.3.3 网关:10010
步骤:
步骤1:创建项目,nacos-ssm-student-gateway
步骤2:添加坐标
步骤3:配置文件 application.yml
步骤4:拷贝全局跨域配置类 GlobalGatewayCorsConfig
步骤5:启动类 GatewayApplication
步骤1:创建项目,nacos-ssm-student-gateway
步骤2:添加坐标
<dependencies><!-- 网关 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- nacos 服务发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--JavaBean工具类,用于JavaBean数据封装--><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId></dependency><!--jwt工具--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><!--joda 时间工具类 --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency></dependencies>
步骤3:配置文件
#端口号 server:port: 10010 spring:application:name: student-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8848 #nacos服务地址gateway:discovery:locator:enabled: true #开启服务注册和发现的功能,自动创建router以服务名开头的请求路径转发到对应的服务lowerCaseServiceId: true #将请求路径上的服务名配置为小写
步骤4:拷贝全局跨域配置类
package com.czxy.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Configuration public class GlobalGatewayCorsConfig {@Beanpublic WebFilter corsFilter2() {return (ServerWebExchange ctx, WebFilterChain chain) -> {ServerHttpRequest request = ctx.getRequest();if (CorsUtils.isCorsRequest(request)) {HttpHeaders requestHeaders = request.getHeaders();ServerHttpResponse response = ctx.getResponse();HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();HttpHeaders headers = response.getHeaders();headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,requestHeaders.getAccessControlRequestHeaders());if (requestMethod != null) {headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());}headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");if (request.getMethod() == HttpMethod.OPTIONS) {response.setStatusCode(HttpStatus.OK);return Mono.empty();}}return chain.filter(ctx);};}}
步骤5:启动类
package com.czxy;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/*** @author 桐叔* @email liangtong@itcast.cn*/ @SpringBootApplication @EnableDiscoveryClient public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);} }
1.3.4 学生服务:9000
步骤:
- 步骤1:创建项目:nacos-ssm-student-service-student
- 步骤2:添加pom
- 步骤3:编写yml
- 步骤4:编写启动类,StudentServiceApplication
- 步骤5:拷贝 Swagger 配置类 ,Swagger2ConfigurationV3
步骤1:创建项目:nacos-ssm-student-service-student
步骤2:添加pom
<dependencies><!--web起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- nacos 客户端 --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId></dependency><!-- nacos 服务发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- mybatis启动器 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!-- 通用Mapper启动器 --><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId></dependency><!-- 分页助手启动器 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Druid连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!--swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId></dependency><!-- feign 远程调用 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- 自定义项目 --><dependency><groupId>com.czxy</groupId><artifactId>nacos-ssm-student-domain</artifactId></dependency></dependencies>
步骤3:编写yml
#端口号 server:port: 9000spring:application:name: student-service #服务名datasource:driverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/nacos_ssm_student?useUnicode=true&characterEncoding=utf8username: rootpassword: 1234druid: #druid 连接池配置initial-size: 1 #初始化连接池大小min-idle: 1 #最小连接数max-active: 20 #最大连接数test-on-borrow: true #获取连接时候验证,会影响性能cloud:nacos:discovery:server-addr: 127.0.0.1:8848 #nacos服务地址sentinel:transport:dashboard: 127.0.0.1:8080
步骤4:编写启动类
package com.czxy.student;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/*** @author 桐叔* @email liangtong@itcast.cn*/ @SpringBootApplication @EnableDiscoveryClient public class StudentServiceApplication {public static void main(String[] args) {SpringApplication.run(StudentServiceApplication.class, args );} }
步骤5:拷贝 Swagger2ConfigurationV3 配置类
package com.czxy.student.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.util.ArrayList; import java.util.List;/*** Swagger2 配置类,* 访问路径:swagger-ui.html* 自动注册:* 位置:resources/META-INF/spring.factories* 内容:* org.springframework.boot.autoconfigure.EnableAutoConfiguration=\* com.czxy.config.Swagger2Configuration*/ @Configuration @EnableSwagger2 public class Swagger2ConfigurationV3 {@Beanpublic Docket createRestApi() {// 1 确定文档Swagger版本Docket docket = new Docket(DocumentationType.SWAGGER_2);// 2 设置 api基本信息docket.apiInfo(apiInfo());// 3 设置自定义加载路径docket = docket.select().apis(RequestHandlerSelectors.basePackage("com.czxy")).paths(PathSelectors.any()).build();//4 设置权限docket.securitySchemes(securitySchemes());docket.securityContexts(securityContexts());return docket;}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("API").description("基于swagger接口文档").contact(new Contact("梁桐","http://www.javaliang.com","liangtong@itcast.cn")).version("1.0").build();}private List<ApiKey> securitySchemes() {List<ApiKey> list = new ArrayList<>();// name 为参数名 keyname是页面传值显示的 keyname, name在swagger鉴权中使用list.add(new ApiKey("Authorization", "Authorization", "header"));return list;}private List<SecurityContext> securityContexts() {List<SecurityContext> list = new ArrayList<>();list.add(SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.regex("^(?!auth).*$")).build());return list;}private List<SecurityReference> defaultAuth() {AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];authorizationScopes[0] = authorizationScope;List<SecurityReference> list = new ArrayList();list.add(new SecurityReference("Authorization", authorizationScopes));return list;}}
1.4 前端环境
1.4.1 创建项目
vue create nacos-student-spa
1.4.2 安装axios
cnpm install axios --save
1.4.3 抽取axios
安装依赖
npm i element-ui --save
创建工具
src/utils/request.js
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'// 方式1:设置基本路径
// axios.defaults.baseURL='http://localhost:10010/api'// 方式2:create an axios instance,并设置基本路径
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url// withCredentials: true, // send cookies when cross-domain requeststimeout: 5000 // request timeout
})// request interceptor
service.interceptors.request.use(config => {// 请求头中追加tokenlet token = localStorage.getItem('token')if (token) {config.headers.Authorization = token}return config},error => {// do something with request errorconsole.log(error) // for debugreturn Promise.reject(error)}
)// response interceptor
service.interceptors.response.use(response => {const res = response.data// if the custom code is not 20000, it is judged as an error.if (res.code !== 20000) {Message({message: res.message || 'Error',type: 'error',duration: 5 * 1000})// ajax异常提示信息 (路径信息,数据)console.info(response.config, response.data )return Promise.reject(new Error(res.message || 'Error'))} else {return res}},error => {console.log('err' + error) // for debugif(error.response.status == 401) {MessageBox.confirm(error.response.data, '重新登录确认框', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {// 删除tokenlocalStorage.removeItem('token')location.reload()})} else {Message({message: error.message,type: 'error',duration: 5 * 1000})}return Promise.reject(error)}
)export default service
使用工具,创建
src/api/student.js
// 导入工具 request.js
import axios from '@/utils/request.js'// 编写功能方法
export function condition(studentPage, studentVo) {return axios.post(`/student-service/student/condition/${studentPage.pageSize}/${studentPage.pageNum}`, studentVo)
}
1.4.4 启动
npm run serve
1.4.5 访问
http://localhost:8080/
1.4.6 修改入口页面
<template><div><router-link to="/classes_list">班级管理</router-link> | <router-link to="/student_list">学生管理</router-link> | <router-link to="/user_register">注册</router-link> | <router-link to="/user_login">登录</router-link> | <hr><!-- 视图显示区域 --><router-view/></div>
</template><script>
export default {}
</script><style></style>
1.4.7 优化:拷贝编辑器配置文件
创建文件
.editorconfig
# editorconfig.org root = true[*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true[*.md] trim_trailing_whitespace = false
2. 学生管理
2.1 查询所有:后端
2.1.1 需求
- 查询所有的学生,含条件查询、分页查询
2.1.2 接口
POST http://localhost:10010/student-service/student/condition/3/1
{"code": 20000,"message": "查询成功","data": {"records": [{"sid": 1,"sname": "赵三33","age": 21,"birthday": "2001-01-17","gender": "1","cid": 1,"cityIds": "320000,321300,321322","cityList": null,"classes": null,"courseCount": null,"courseList": [],"courseIds": []},...]
}
2.1.3 后端实现
步骤1:拷贝配置类(Swagger配置类)
步骤2:创建条件查询封装类:StudentVo
步骤3:编写Mapper
步骤4:编写service接口、实现类
步骤5:编写controller
步骤6:测试
步骤1:拷贝配置类(Swagger配置类)
步骤2:创建条件查询封装类:StudentVo
package com.czxy.student.vo;import lombok.Data;/*** @author 桐叔* @email liangtong@itcast.cn*/ @Data public class StudentVo {private String cid; //班级private String sname; //姓名private String startAge; //开始年龄private String endAge; //结束年龄 }
步骤3:编写Mapper
步骤4:编写service
接口
实现类
步骤5:编写controller
步骤6:测试
http://localhost:9000/student/condition/3/1http://localhost:10010/student-service/student/condition/3/1
2.2 查询所欲:前端
2.2.1 查询所有
需求:显示学生列表
步骤:
- 步骤1:确定访问路径
- 步骤2:编写路由
- 步骤3:查询所有
步骤1:确定访问路径
步骤2:编写路由
import Vue from 'vue' import VueRouter from 'vue-router'Vue.use(VueRouter)const routes = [{path: '/student_list',name: '学生列表',component: () => import('../views/StudentList.vue')} ]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes })export default router
步骤3:查询所有
<template><div><router-link to="/student_add">添加学生</router-link><!-- 查询列表 --><table id="tid" border="1" width="800"><tr><td>学生ID</td><td>班级ID</td><td>学生姓名</td><td>年龄</td><td>生日</td><td>性别</td><td>操作</td></tr><tr v-for="(student,index) in pageInfo.list" :key="index"><td>{{student.sid}}</td><td>{{student.cid}}</td><td>{{student.sname}}</td><td>{{student.age}}</td><td>{{student.birthday}}</td><td>{{student.gender == 1 ? "男" : "女"}}</td><td><a>修改</a><a>删除</a></td></tr></table></div> </template><script> import {condition} from '@/api/student.js'export default {data() {return {pageInfo: { //分页对象pageSize: 2,pageNum: 1},studentVo: { //条件表单对象cid: ''},}},mounted() {// 查询所有this.conditionFn()},methods: {async conditionFn() {let { data } = await condition(this.pageInfo,this.studentVo)console.info(data)this.pageInfo = data},}, } </script><style></style>
2.2.2 条件所有
需求:
步骤
- 步骤1:添加条件查询表单
- 步骤2:完善 conditionFn 函数
步骤1:添加条件查询表单
<!-- 查询条件 --><table><tr><td>班级</td><td><select v-model="studentVo.cid"><option value="">--选择班级--</option><option value="1">Java12班</option><option value="2">Java34班</option><option value="3">Java56班</option></select></td><td>姓名:</td><td><input type="text" placeholder="请输入姓名" v-model="studentVo.sname" size="10"></td><td>年龄:</td><td><input type="text" placeholder="请输入开始年龄" v-model="studentVo.startAge" size="10">--<input type="text" placeholder="请输入结束年龄" v-model="studentVo.endAge" size="10"></td><td><input type="button" value="查询" @click="conditionFn(1)"></td></tr></table>
步骤2:完善 conditionFn 函数
async conditionFn(pageNum) {if(pageNum) {this.pageInfo.pageNum = pageNum}let { data } = await condition(this.pageInfo,this.studentVo)console.info(data)this.pageInfo = data},
2.2.3 分页所有
需求:
步骤
- 步骤1:添加分页信息
- 步骤2:编写跳转函数
步骤1:添加分页信息
<!-- 分页条 --><div id="pageId">每页<select v-model="pageInfo.pageSize" @change="conditionFn(1)"><option value="1">1</option><option value="2">2</option><option value="5">5</option><option value="10">10</option></select>条,<a href="#" v-for="index in pageInfo.pages" :key="index" @click.prevent="conditionFn(index)" >{{index}}</a>,跳转到第 <input type="text" v-model="pageInfo.pageNum" size="5" @keydown.enter="go" />页</div>
步骤2:编写跳转函数
go() {if(parseInt(this.pageInfo.pageNum) == this.pageInfo.pageNum) {this.conditionFn()}},
SpringCloud微服务之学生管理相关推荐
- SpringCloud微服务架构实战库存管理与分布式文件系统
库存管理与分布式文件系统 在电商平台的库存管理系统设计中,将涉及商品和本地图库的管理,这里我们将使用另一种数据开发框架 MyBatis进行数据库访问方面的设计,还将实现与分布式文件系统的对接使用. 本 ...
- 计算机毕业设计springcloud“微服务”架构下新闻头条的设计与实现
最新计算机专业原创毕业设计参考选题都有源码+数据库是近期作品 你的选题刚好在下面有,有时间看到机会给您发 1 ssm毕业生实习管理系统 2 ssm基于vue.js开发的红酒网站 3 springboo ...
- SpringCloud微服务技术实践与总结(基础篇)
1.认识微服务 1.1.单体架构 单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署. 单体架构的优缺点如下: 优点: 架构简单.部署成本低 缺点: 耦合度高(维护困难.升级困难) 1.2 ...
- 学习笔记:SpringCloud 微服务技术栈_实用篇①_基础知识
若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 前言 学习视频链接 SpringCloud + RabbitMQ + Docker + Redis + 搜 ...
- SpringCloud 微服务架构,适合接私活(附源码)
欢迎关注方志朋的博客,回复"666"获面试宝典 今天给大家推荐一个牛逼的接私活项目,SpringCloud微服务架构项目! 一个由商业级项目升级优化而来的微服务架构,采用Sprin ...
- SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用
什么是SpringCloud 微服务架构 • "微服务"一词源于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到 http://mar ...
- Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案
Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明:Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在 ...
- Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲
Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台: 微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...
- SpringCloud 微服务
一微服务架构概述 1.1 微服务特性以及优点 每个服务可以独立运行在自己的进程里 一系列独立运行的微服务(goods,order,pay,user,search-)共同构建了整个系统 每个服务为独立的 ...
- 微服务 前台调用后台的慢的原因_20年IT农民工分享SpringCloud微服务架构实战文档...
前言 越来越多的企业使用 SpringCloud 实现微服务架构设计.我们可以看到这样一种现象:不管是全新开发,还是系统重构,大家似乎都在争先恐后地使用微服务.对于一个Java开发人员来说,学习微服务 ...
最新文章
- 微信聊天和朋友圈可以拍摄和分享大视频?
- glusterfs快速安装
- jmeter 线程执行顺序_Jmeter-线程组执行顺序控制
- 宝塔php共生,宝塔面板如何开启php扩展
- c语言动态内存分配数组,【C】动态内存分配
- centos7 关闭防火墙和selinux
- python读取配置文件configparser模块
- SEO优化之——html页面相关总结
- Google Drive 被曝0day,可诱骗用户安装恶意软件
- mysql btree面试_java面试题:你了解mysql的B+TREE索引吗?
- 一图精通python3
- cad图纸服务器共享文件慢,DWG文件打开慢?3个技巧教你实现快速预览!
- STM32 SIM800C SIM868 连接OneNet 以及远程控制流程详解
- java去除水印,Java 删除/复制Word文档水印
- RabbitMQ使用实践
- 3dMax 制作玻璃材质
- 幻14 连不上无线网 网卡掉驱动
- PnL Explained FAQ
- 一个女孩跳楼看到的(漫画)
- 云计算运维工程师前景怎么样?
热门文章
- java+pom.xml+是什么_pom.xml文件是啥
- python差异性分析_差异性分析
- Python 基于jieba的三国演义词频分析与可视化
- 基于egret的点光源光线效果的实现
- 短视频运营小技巧,掌握推荐机制很重要,吸粉引流也不难
- 对计算机科学的认识论文,关于对计算机的认识论文
- linux启动盘无法格式化u盘启动盘,U盘做了启动盘后无法格式化怎么办实测解决...
- 我的世界1.8.9无需正版的服务器,我的世界1.8-1.8.9勇者世界生存服务器
- 近红外光谱定性定量分析模型 Matlab
- 全能扫描王(一款识别率超高的OCR识别APP)