Student management of SpringCloud micro service

Posted by echoninja on Fri, 10 Dec 2021 13:26:07 +0100

1. Environmental construction

1.1 architecture analysis

  • Registry: Nacos
  • Gateway: Gateway
  • Backend infrastructure: ssm
  • Front end: Vue + SPA
  • Axios(request.js)

1.2 database environment

1.2. 1 student database

#Student database
CREATE DATABASE nacos_ssm_student;
USE nacos_ssm_student;

CREATE TABLE tb_city(
  c_id VARCHAR(32) PRIMARY KEY COMMENT 'city ID',
  city_name VARCHAR(20) COMMENT 'City name' ,
  parent_id VARCHAR(32) COMMENT 'father ID'
);

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320000','Jiangsu Province','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140000','Shanxi Province','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130000','Hebei Province','0');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320100','Nanjing City','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320102','Xuanwu District','320100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320103','Baixia District','320100');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321300','Suqian City','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321322','Shuyang County','321300');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321323','Siyang County','321300');


INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140100','Taiyuan City','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140106','Yingze District','140100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140108','Jiancaoping District ','140100');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140800','Yuncheng City','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140823','Wenxi County','140800');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140828','summer county','140800');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130100','Shijiazhuang City ','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130127','Gaoyi County','130100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130185','Luquan ','130100');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131000','Langfang City','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131003','Guangyang District','131000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131022','Gu'an County','131000');


CREATE TABLE `tb_student` (
  `s_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'student ID',
  `sname` VARCHAR(50) DEFAULT NULL COMMENT 'full name',
  `age` INT(11) DEFAULT NULL COMMENT 'Age',
  `birthday` DATETIME DEFAULT NULL COMMENT 'birthday',
  `gender` CHAR(1) DEFAULT NULL COMMENT 'Gender',
  `c_id` INT DEFAULT NULL,
  `city_ids` VARCHAR(32) DEFAULT NULL COMMENT 'City: 320000,321300,321322'
);

INSERT  INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (1,'Zhao San 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,'Qian Si 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,'Sun wu56',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,'Zhang San',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 user database

# User database
CREATE DATABASE nacos_ssm_user;
USE nacos_ssm_user;

CREATE TABLE `tb_user` (
  `u_id` VARCHAR(32) PRIMARY KEY NOT NULL COMMENT 'User number',
  `user_name` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT 'user name',
  `password` VARCHAR(32) DEFAULT NULL COMMENT 'password',
  `gender` BIT(1) DEFAULT NULL COMMENT 'Gender,1 Indicates male, 0 indicates female',
  `image` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT 'Avatar picture'
);

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

# Class database
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 'Teacher name',
  `type` INT(11) DEFAULT NULL COMMENT 'Teacher type: 1.Instructor, 2.Assistant teacher, 3.Counselor teacher'
);
INSERT  INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (1,'Miss Liang Tong',1);
INSERT  INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (2,'Mr. Ma Kun',2);
INSERT  INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (3,'Miss Zhong Yan',3);
INSERT  INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (4,'Mr. Yuan Xinxin',1);
INSERT  INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (5,'Mr. Ren Linda',2);
INSERT  INTO `tb_teacher`(`tid`,`tname`,`type`) VALUES (6,'Miss Wang Shanshan',3);


CREATE TABLE `tb_class` (
  `cid` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `cname` VARCHAR(50) DEFAULT NULL COMMENT 'Class name',
  `teacher1_id` INT(11) DEFAULT NULL COMMENT 'Instructor',
  `teacher2_id` INT(11) DEFAULT NULL COMMENT 'Assistant teacher',
  `teacher3_id` INT(11) DEFAULT NULL COMMENT 'Counselor teacher'
);

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

#Student database
CREATE DATABASE nacos_ssm_student;
USE nacos_ssm_student;

CREATE TABLE tb_city(
  c_id VARCHAR(32) PRIMARY KEY COMMENT 'city ID',
  city_name VARCHAR(20) COMMENT 'City name' ,
  parent_id VARCHAR(32) COMMENT 'father ID'
);

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320000','Jiangsu Province','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140000','Shanxi Province','0');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130000','Hebei Province','0');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320100','Nanjing City','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320102','Xuanwu District','320100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('320103','Baixia District','320100');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321300','Suqian City','320000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321322','Shuyang County','321300');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('321323','Siyang County','321300');


INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140100','Taiyuan City','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140106','Yingze District','140100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140108','Jiancaoping District ','140100');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140800','Yuncheng City','140000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140823','Wenxi County','140800');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('140828','summer county','140800');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130100','Shijiazhuang City ','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130127','Gaoyi County','130100');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('130185','Luquan ','130100');

INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131000','Langfang City','130000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131003','Guangyang District','131000');
INSERT INTO tb_city(c_id,city_name,parent_id) VALUES('131022','Gu'an County','131000');


CREATE TABLE `tb_student` (
  `s_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'student ID',
  `sname` VARCHAR(50) DEFAULT NULL COMMENT 'full name',
  `age` INT(11) DEFAULT NULL COMMENT 'Age',
  `birthday` DATETIME DEFAULT NULL COMMENT 'birthday',
  `gender` CHAR(1) DEFAULT NULL COMMENT 'Gender',
  `c_id` INT DEFAULT NULL,
  `city_ids` VARCHAR(32) DEFAULT NULL COMMENT 'City: 320000,321300,321322'
);

INSERT  INTO `tb_student`(`s_id`,`sname`,`age`,`birthday`,`gender`,`c_id`,`city_ids`) VALUES (1,'Zhao San 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,'Qian Si 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,'Sun wu56',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,'Zhang San',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 back end environment

1.3. 1 parent project

  • Steps:

    • Step 1: create the project Nacos SSM student
    • Step 2: add coordinates
  • Step 1: create a project

  • Step 2: add coordinates:

    
        <!-- 1 determine spring boot Version of-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.5.RELEASE</version>
        </parent>
    
        <!--2  Determine version-->
        <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 Locked version-->
        <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 find -->
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                    <version>${alibaba.cloud.version}</version>
                </dependency>
    
                <!--nacos cloud to configure -->
                <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 starter -->
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>${mybatis.starter.version}</version>
                </dependency>
                <!-- currency Mapper starter -->
                <dependency>
                    <groupId>tk.mybatis</groupId>
                    <artifactId>mapper-spring-boot-starter</artifactId>
                    <version>${mapper.starter.version}</version>
                </dependency>
                <!-- Paging assistant launcher -->
                <dependency>
                    <groupId>com.github.pagehelper</groupId>
                    <artifactId>pagehelper-spring-boot-starter</artifactId>
                    <version>${pageHelper.starter.version}</version>
                </dependency>
                <!-- mysql drive -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
                <!-- Druid Connection pool -->
                <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 Tool class for JavaBean Data encapsulation-->
                <dependency>
                    <groupId>commons-beanutils</groupId>
                    <artifactId>commons-beanutils</artifactId>
                    <version>${beanutils.version}</version>
                </dependency>
    
                <!--jwt tool-->
                <dependency>
                    <groupId>io.jsonwebtoken</groupId>
                    <artifactId>jjwt</artifactId>
                    <version>${jwt.jjwt.version}</version>
                </dependency>
    
                <!--joda Time tool class -->
                <dependency>
                    <groupId>joda-time</groupId>
                    <artifactId>joda-time</artifactId>
                    <version>${jwt.joda.version}</version>
                </dependency>
    
                <!-- Custom item -->
                <dependency>
                    <groupId>com.czxy</groupId>
                    <artifactId>nacos-ssm-student-domain</artifactId>
                    <version>${student.version}</version>
                </dependency>
    
            </dependencies>
    
        </dependencyManagement>
    
    

1.3.2 domain project

  • Steps:

    • Step 1: create the project: Nacos SSM student domain
    • Step 2: add pom
    • Step 3: copy vo (BaseResult)
    • Step 4: copy the JavaBean
  • Step 1: create the project: Nacos SSM student domain

  • Step 2: add 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>
    
  • Step 3: copy vo

    package com.czxy.vo;
    
    import lombok.Getter;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author Uncle Tong
     * @email liangtong@itcast.cn
     */
    @Getter
    public class BaseResult<T> {
    
        //Success status code
        public static final int OK = 20000;
        //Failure status code
        public static final int ERROR = 0;
    
        //Return code
        private Integer code;
        //Return message
        private String message;
    
        //Store data
        private T data;
        //Other 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;
        }
    
        /**
         * Shortcut successful BaseResult object
         * @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 );
        }
    
        /**
         * Shortcut failed BaseResult object
         * @param message
         * @return
         */
        public static BaseResult error(String message){
            return new BaseResult(BaseResult.ERROR , message);
        }
    
        /**
         * Custom data area
         * @param key
         * @param msg
         * @return
         */
        public BaseResult append(String key , Object msg){
            other.put(key , msg);
            return this;
        }
    
    }
    
  • Step 4: copy the 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)Entity class
       *
       * @author Uncle Tong
       */
      @Table(name = "tb_city")
      @Data
      public class City implements Serializable {
          private static final long serialVersionUID = 660498290955870873L;
          /**
           * City ID
           */
          @Id
          @Column(name = "c_id")
          private String cid;
          /**
           * City name
           */
          @Column(name = "city_name")
          private String cityName;
          /**
           * Parent 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 Uncle Tong
       * @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;       //Class name
      
          @Column(name = "teacher1_id")
          private Integer teacher1Id;       //Instructor
      
          @Column(name = "teacher2_id")
          private Integer teacher2Id;       //Assistant teacher
      
          @Column(name = "teacher3_id")
          private Integer teacher3Id;       //Counselor teacher
      }
      
    • Course

      package com.czxy.domain;
      
      import lombok.Data;
      
      import javax.persistence.Column;
      import javax.persistence.Id;
      import javax.persistence.Table;
      
      /**
       * @author Uncle Tong
       * @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 Uncle Tong
       * @email liangtong@itcast.cn
       */
      @Table(name = "tb_student")
      @Data
      public class Student {
      
          @Id
          @Column(name = "s_id")
          private Integer sid;         //Student ID
      
          @Column(name = "sname")
          private String sname;         //full name
      
          @Column(name = "age")
          private Integer age;         //Age
      
          @Column(name = "birthday")
          @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
          private Date birthday;         //birthday
      
          @Column(name = "gender")
          private String gender;      //Gender
      
          @Column(name = "c_id")
          private Integer cid;         //Class foreign key
      
          @Column(name = "city_ids")
          private String cityIds;    //city
      
      
          private List<City> cityList;    //Selected city
      
          @Transient
          private Classes classes;    //Class object
      
          @Transient
          private Integer courseCount;        //Number of courses selected
      
          @Transient
          private List<Course> courseList = new ArrayList<>();    //Course selection details
      
          @Transient
          private List<Integer> courseIds = new ArrayList();      //Course selection id
      
      }
      
      
    • Teacher

      package com.czxy.domain;
      
      import lombok.Data;
      
      import javax.persistence.Column;
      import javax.persistence.Id;
      import javax.persistence.Table;
      
      /**
       * @author Uncle Tong
       * @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;       //Teacher name
      
          @Column(name = "type")
          private Integer type;       //Teacher type: 1 Instructor, 2 Assistant teacher, 3 Counselor teacher
      }
      
    • User

      package com.czxy.domain;
      
      import lombok.Data;
      
      import javax.persistence.Column;
      import javax.persistence.Id;
      import javax.persistence.Table;
      
      /**
       * @author Uncle Tong
       * @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 number ',
        `user_name` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT 'User name ',
        `password` VARCHAR(32) DEFAULT NULL COMMENT 'Password ',
        `gender` BIT(1) DEFAULT NULL COMMENT 'Gender, 1 for male, 0 for female ',
        `image` VARCHAR(50) UNIQUE DEFAULT NULL COMMENT ''Avatar picture'
      );
       */
      
      

1.3. 3 gateway: 10010

  • Steps:

    • Step 1: create a project, the Nacos SSM student gateway

    • Step 2: add coordinates

    • Step 3: configure the file application yml

    • Step 4: copy the global cross domain configuration class GlobalGatewayCorsConfig

    • Step 5: start the GatewayApplication class

  • Step 1: create a project, the Nacos SSM student gateway

  • Step 2: add coordinates

        <dependencies>
            <!-- gateway -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
            <!-- nacos Service discovery -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
    
    
            <!--JavaBean Tool class for JavaBean Data encapsulation-->
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
            </dependency>
    
            <!--jwt tool-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
            </dependency>
    
            <!--joda Time tool class -->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
            </dependency>
    
    
        </dependencies>
    
  • Step 3: Profile

    #Port number
    server:
      port: 10010
    spring:
      application:
        name: student-gateway
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848   #nacos service address
        gateway:
          discovery:
            locator:
              enabled: true               #Turn on the function of service registration and discovery, automatically create a router, and forward the request path starting with the service name to the corresponding service
              lowerCaseServiceId: true    #Configure the service name on the request path to lowercase
    
    
  • Step 4: copy the global cross domain configuration class

    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 Uncle Tong
     * @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);
            };
        }
    
    }
    
    
  • Step 5: start class

    package com.czxy;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    /**
     * @author Uncle Tong
     * @email liangtong@itcast.cn
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    public class GatewayApplication {
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    }
    
    

1.3. 4 Student Services: 9000

  • Steps:

    • Step 1: create a project: Nacos SSM student service student
    • Step 2: add pom
    • Step 3: write yml
    • Step 4: write the startup class, StudentServiceApplication
    • Step 5: copy Swagger configuration class, Swagger2ConfigurationV3
  • Step 1: create a project: Nacos SSM student service student

  • Step 2: add pom

    <dependencies>
            <!--web Start dependence-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- nacos client -->
            <dependency>
                <groupId>com.alibaba.nacos</groupId>
                <artifactId>nacos-client</artifactId>
            </dependency>
    
            <!-- nacos Service discovery -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
    
            <!-- mybatis starter -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <!-- currency Mapper starter -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
            </dependency>
            <!-- Paging assistant launcher -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
            </dependency>
            <!-- mysql drive -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!-- Druid Connection pool -->
            <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 Remote call -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            <!-- Custom item -->
            <dependency>
                <groupId>com.czxy</groupId>
                <artifactId>nacos-ssm-student-domain</artifactId>
            </dependency>
        </dependencies>
    
  • Step 3: write yml

    #Port number
    server:
      port: 9000
    
    spring:
      application:
        name: student-service          #service name
      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 connection pool configuration
          initial-size: 1       #Initialize connection pool size
          min-idle: 1           #Minimum number of connections
          max-active: 20        #maximum connection
          test-on-borrow: true  #Verification when obtaining connections will affect performance
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848   #nacos service address
        sentinel:
          transport:
            dashboard: 127.0.0.1:8080
    
  • Step 4: write the startup class

    package com.czxy.student;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    /**
     * @author Uncle Tong
     * @email liangtong@itcast.cn
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    public class StudentServiceApplication {
        public static void main(String[] args) {
            SpringApplication.run(StudentServiceApplication.class, args );
        }
    }
    
    
  • Step 5: copy Swagger2ConfigurationV3 configuration class

    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 Configuration class,
     * Access path: swagger UI html
     * Automatic registration:
     *     Location: Resources / meta-inf / spring factories
     *     Content:
     *        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
     *          com.czxy.config.Swagger2Configuration
     */
    @Configuration
    @EnableSwagger2
    public class Swagger2ConfigurationV3 {
    
        @Bean
        public Docket createRestApi() {
            // 1 determine the Swagger version of the document
            Docket docket = new Docket(DocumentationType.SWAGGER_2);
            // 2. Setting api basic information
            docket.apiInfo(apiInfo());
            // 3. Set custom loading path
            docket = docket.select()
                    .apis(RequestHandlerSelectors.basePackage("com.czxy"))
                    .paths(PathSelectors.any())
                    .build();
            //4 set permissions
            docket.securitySchemes(securitySchemes());
            docket.securityContexts(securityContexts());
    
            return docket;
        }
    
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("API")
                    .description("be based on swagger Interface documentation")
                    .contact(new Contact("Liang Tong","http://www.javaliang.com","liangtong@itcast.cn"))
                    .version("1.0")
                    .build();
        }
    
        private List<ApiKey> securitySchemes() {
            List<ApiKey> list = new ArrayList<>();
            // Name is the parameter name. Keyname is the keyname displayed on the page. Name is used in swagger authentication
            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 front end environment

1.4. 1 create project

vue create nacos-student-spa

1.4. 2 install axios

cnpm install axios --save

1.4. 3 extraction axios

  • Installation dependency

    npm i element-ui --save
    
  • Create tool Src / utils / request js

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'

// Method 1: set basic path
// axios.defaults.baseURL='http://localhost:10010/api'

// Method 2: create an axios instance and set the basic path
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 => {
    // Append token in request header
    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 exception prompt information (path information, data)
      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, 'Login again confirmation box', {
        confirmButtonText: 'Login again',
        cancelButtonText: 'cancel',
        type: 'warning'
      }).then(() => {
        // Delete token
        localStorage.removeItem('token')
        location.reload()
      })
    } else {
      Message({
        message: error.message,
        type: 'error',
        duration: 5 * 1000
      })
    }
    return Promise.reject(error)
  }
)

export default service

  • Using the tool, create Src / API / student. XML js

// Import tool request js
import axios from '@/utils/request.js'

// Writing function method
export function condition(studentPage, studentVo) {
    return axios.post(`/student-service/student/condition/${studentPage.pageSize}/${studentPage.pageNum}`, studentVo)
}

1.4. 4 start

npm run serve

1.4. 5 access

http://localhost:8080/

1.4. 6. Modify the entry page

<template>
  <div>
    <router-link to="/classes_list">Class management</router-link> | 
    <router-link to="/student_list">Student management</router-link> | 
    <router-link to="/user_register">register</router-link> | 
    <router-link to="/user_login">Sign in</router-link> | 
    <hr>
    <!-- View display area -->
    <router-view/>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

1.4. 7 Optimization: Copy Editor configuration file

  • Create file 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. Student management

2.1 query all backend:

2.1. 1 demand

  • Query all students, including conditional query and paging query

2.1. 2 interface

POST http://localhost:10010/student-service/student/condition/3/1
{
  "code": 20000,
  "message": "query was successful",
  "data": {
    "records": [
      {
        "sid": 1,
        "sname": "Zhao San 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 back end implementation

  • Step 1: copy configuration class (Swagger configuration class)

  • Step 2: create a conditional query encapsulation class: StudentVo

  • Step 3: write Mapper

  • Step 4: write the service interface and implementation class

  • Step 5: write controller

  • Step 6: Test

  • Step 1: copy configuration class (Swagger configuration class)

  • Step 2: create a conditional query encapsulation class: StudentVo

    package com.czxy.student.vo;
    
    import lombok.Data;
    
    /**
     * @author Uncle Tong
     * @email liangtong@itcast.cn
     */
    @Data
    public class StudentVo {
        private String cid;     //class
        private String sname;       //full name
        private String startAge;    //Starting age
        private String endAge;      //End age
    }
    
  • Step 3: write Mapper

  • Step 4: write a service

    • Interface

    • Implementation class

  • Step 5: write controller

  • Step 6: Test

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

2.2 query: front end

2.2. 1 query all

  • Requirements: display student list

  • Steps:

    • Step 1: determine the access path
    • Step 2: write a route
    • Step 3: query all
  • Step 1: determine the access path

  • Step 2: write a route

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/student_list',
        name: 'Student list',
        component: () => import('../views/StudentList.vue')
      }
    ]
    
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    
    export default router
    
    
  • Step 3: query all

    <template>
      <div>
        <router-link to="/student_add">Add student</router-link>
    
        <!-- Query list -->
        <table id="tid" border="1" width="800">
          <tr>
            <td>student ID</td>
            <td>class ID</td>
            <td>Student name</td>
            <td>Age</td>
            <td>birthday</td>
            <td>Gender</td>
            <td>operation</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 ? "male" : "female"}}</td>
            <td>
              <a>modify</a>
              <a>delete</a>
            </td>
          </tr>
        </table>
    
      </div>
    </template>
    
    <script>
    import {condition} from '@/api/student.js'
    
    export default {
      data() {
        return {
          pageInfo: {       //Paging object
            pageSize: 2,
            pageNum: 1
          },
          studentVo: {          //Condition form object
            cid: ''
          },
        }
      },
      mounted() {
        // Query all
        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 condition all

  • Requirements:

  • step

    • Step 1: add a conditional query form
    • Step 2: improve the conditionFn function
  • Step 1: add a conditional query form

    <!-- query criteria -->
        <table>
          <tr>
            <td>class</td>
            <td>
              <select v-model="studentVo.cid">
                <option value="">--Select class--</option>
                <option value="1">Java12 class</option>
                <option value="2">Java34 class</option>
                <option value="3">Java56 class</option>
              </select>
            </td>
            <td>full name:</td>
            <td>
              <input type="text" placeholder="Please enter your name" v-model="studentVo.sname" size="10">
            </td>
            <td>Age:</td>
            <td>
              <input type="text" placeholder="Please enter the starting age" v-model="studentVo.startAge" size="10">
              --
              <input type="text" placeholder="Please enter the end age" v-model="studentVo.endAge" size="10">
            </td>
            <td><input type="button" value="query" @click="conditionFn(1)"></td>
          </tr>
        </table>
    
  • Step 2: improve the conditionFn function

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

  • Requirements:

  • step

    • Step 1: add paging information
    • Step 2: write jump function
  • Step 1: add paging information

        <!-- Paging bar -->
        <div id="pageId">
          each page
          <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>Article,
    
          <a href="#" v-for="index in pageInfo.pages" :key="index" @click.prevent="conditionFn(index)" >{{index}}</a>
          ,Jump to page <input type="text" v-model="pageInfo.pageNum" size="5" @keydown.enter="go" />page
        </div>
    
  • Step 2: write jump function

        go() {
          if(parseInt(this.pageInfo.pageNum) == this.pageInfo.pageNum) {
            this.conditionFn()
          }
        },
    

Topics: Spring Back-end Spring Cloud Microservices