SpringCloud微服务之学生管理

1.环境搭建

1.1 架构分析

SpringCloud微服务之学生管理

  • 注册中心: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:创建项目

    SpringCloud微服务之学生管理

  • 步骤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

    SpringCloud微服务之学生管理

  • 步骤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

    SpringCloud微服务之学生管理

    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

    SpringCloud微服务之学生管理

    • 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;    //所选城市
      
          @Transient
          private Classes classes;    //班级对象
      
          @Transient
          private Integer courseCount;        //选课数
      
          @Transient
          private List<Course> courseList = new ArrayList<>();    //选课详情
      
          @Transient
          private 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

    SpringCloud微服务之学生管理

    SpringCloud微服务之学生管理

  • 步骤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:配置文件

    SpringCloud微服务之学生管理

    #端口号
    server:
      port: 10010
    spring:
      application:
        name: student-gateway
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848   #nacos服务地址
        gateway:
          discovery:
            locator:
              enabled: true               #开启服务注册和发现的功能,自动创建router以服务名开头的请求路径转发到对应的服务
              lowerCaseServiceId: true    #将请求路径上的服务名配置为小写
    
    
  • 步骤4:拷贝全局跨域配置类

    SpringCloud微服务之学生管理

    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 {
    
        @Bean
        public 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:启动类

    SpringCloud微服务之学生管理

    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

    SpringCloud微服务之学生管理

    SpringCloud微服务之学生管理

  • 步骤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

    SpringCloud微服务之学生管理

    #端口号
    server:
      port: 9000
    
    spring:
      application:
        name: student-service          #服务名
      datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/nacos_ssm_student?useUnicode=true&characterEncoding=utf8
        username: root
        password: 1234
        druid:    #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:编写启动类

    SpringCloud微服务之学生管理

    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 配置类

    SpringCloud微服务之学生管理

    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 {
    
        @Bean
        public 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

SpringCloud微服务之学生管理

1.4.2 安装axios

cnpm install axios --save

SpringCloud微服务之学生管理

1.4.3 抽取axios

  • 安装依赖

    npm i element-ui --save
    
  • 创建工具src/utils/request.js

    SpringCloud微服务之学生管理

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 requests
  timeout: 5000 // request timeout
})



// request interceptor
service.interceptors.request.use(
  config => {
    // 请求头中追加token
    let token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = token
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return 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 debug
    if(error.response.status == 401) {
      MessageBox.confirm(error.response.data, '重新登录确认框', {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 删除token
        localStorage.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

    SpringCloud微服务之学生管理

// 导入工具 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

SpringCloud微服务之学生管理

1.4.5 访问

http://localhost:8080/

SpringCloud微服务之学生管理

1.4.6 修改入口页面

SpringCloud微服务之学生管理

<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>

SpringCloud微服务之学生管理

1.4.7 优化:拷贝编辑器配置文件

SpringCloud微服务之学生管理

  • 创建文件 .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": []
      },
      ...
   ]
}

SpringCloud微服务之学生管理

2.1.3 后端实现

  • 步骤1:拷贝配置类(Swagger配置类)

  • 步骤2:创建条件查询封装类:StudentVo

  • 步骤3:编写Mapper

  • 步骤4:编写service接口、实现类

  • 步骤5:编写controller

  • 步骤6:测试

  • 步骤1:拷贝配置类(Swagger配置类)

    SpringCloud微服务之学生管理

  • 步骤2:创建条件查询封装类:StudentVo

    SpringCloud微服务之学生管理

    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

    SpringCloud微服务之学生管理

    
    
  • 步骤4:编写service

    • 接口

      SpringCloud微服务之学生管理

      
      
    • 实现类

      SpringCloud微服务之学生管理

  • 步骤5:编写controller

    SpringCloud微服务之学生管理

  • 步骤6:测试

    http://localhost:9000/student/condition/3/1
    
    http://localhost:10010/student-service/student/condition/3/1
    

    SpringCloud微服务之学生管理

2.2 查询所欲:前端

2.2.1 查询所有

  • 需求:显示学生列表

    SpringCloud微服务之学生管理

  • 步骤:

    • 步骤1:确定访问路径
    • 步骤2:编写路由
    • 步骤3:查询所有
  • 步骤1:确定访问路径

    SpringCloud微服务之学生管理

  • 步骤2:编写路由

    SpringCloud微服务之学生管理

    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:查询所有

    SpringCloud微服务之学生管理

    <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 条件所有

  • 需求:

    SpringCloud微服务之学生管理

  • 步骤

    • 步骤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 函数

    SpringCloud微服务之学生管理

        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 分页所有

  • 需求:

    SpringCloud微服务之学生管理

  • 步骤

    • 步骤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:编写跳转函数

    SpringCloud微服务之学生管理

        go() {
          if(parseInt(this.pageInfo.pageNum) == this.pageInfo.pageNum) {
            this.conditionFn()
          }
        },
    
上一篇:Cmake的install与file命令的区别


下一篇:VMware 全虚拟打开