Grain College day02

1, Front and rear end separation concept

  2, Develop the back end of instructor management module

1. Database design

Create a database. Take yytryproject as an example

  2. Create table

CREATE TABLE `edu_teacher` (
  `id` char(19) NOT NULL COMMENT 'lecturer ID',
  `name` varchar(20) NOT NULL COMMENT 'Lecturer name',
  `intro` varchar(500) NOT NULL DEFAULT '' COMMENT 'Trainer Introduction ',
  `career` varchar(500) DEFAULT NULL COMMENT 'Lecturer qualifications,One sentence explains the instructor',
  `level` int(10) unsigned NOT NULL COMMENT 'Title 1 senior lecturer 2 chief lecturer',
  `avatar` varchar(255) DEFAULT NULL COMMENT 'Lecturer portrait',
  `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'sort',
  `is_deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Logical deletion 1( true)Deleted, 0( false)Not deleted',
  `gmt_create` datetime NOT NULL COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL COMMENT 'Update time',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='lecturer';

Insert a few pieces of data into it:

INSERT INTO `yytryproject`.`edu_teacher`(`id`, `name`, `intro`, `career`, `level`, `avatar`, `sort`, `is_deleted`, `gmt_create`, `gmt_modified`) VALUES ('1', 'Tester 1', 'Introduction to general lecturers', 'General lecturer qualifications', 1, 'www.baidu.com', 1, 0, '2019-09-03 13:45:00', '2020-09-03 13:45:18');

3. Database design specification

The following specifications are only for this module. For more comprehensive documents, please refer to Alibaba Java Development Manual:
1. The library name shall be consistent with the application name as much as possible

2. Table names and field names must use lowercase letters or numbers, and the beginning of numbers is prohibited,

3. Plural nouns are not used in table names

4. It is better to add "business name" to the name of the table_ The role of the table. For example, edu_teacher_

5. Three required fields in the table: id, gmt_create, gmt_modified

explain:
The id must be the primary key, the type must be bigint unsigned, and the step size must be 1.
(if the cluster deployment by database and table is used, the id type is verchar, which is not self increment, and the distributed id generator is used in the business)
gmt_ create, gmt_ The type of modified is datetime. The former indicates active creation in the present tense, and the latter indicates being created in the past participle
Dynamic update.

6. Only when the number of rows in a single table exceeds 5 million or the capacity of a single table exceeds 2GB, it is recommended to separate the database and table. Note: if the estimated amount in three years
The data can't reach this level at all. Please don't divide databases and tables when creating tables.
guli_edu.sql 1

7. The field expressing the concept of yes or no must use is_ The data type is unsigned tinyint (1 means yes, 0 means table)
No).
Note: if any field is non negative, it must be unsigned.
Note: any boolean variable in POJO class should not be prefixed with is. The database represents the value of yes or no, and the tinyint class is used
Type, persistence is_ The naming method of XXX is to clarify its value meaning and value range.
Positive example: field name is expressing logical deletion_ Deleted, 1 means deleted, 0 means not deleted.

8. The decimal type is decimal, and float and double are prohibited. Note: when storing float and double, there is precision loss
The problem of missing is likely to get incorrect results in the comparison of values. If the stored data range exceeds the decimal range, it is recommended to
Divide the data into integers and decimals and store them separately.

9. If the stored strings are almost equal in length, use the char fixed length string type.

10. varchar is a variable length string. It does not pre allocate storage space. The length should not exceed 5000. If the storage length is greater than this value, it is fixed
The semantic field type is text. A separate table is used to correspond with the primary key to avoid affecting the index efficiency of other fields.

11. The unique index name is uk_ Field name; The normal index name is idx_ Field name.
Description: uk_ unique key; idx_ The abbreviation of index

12. Foreign keys and cascading are not allowed. All foreign key concepts must be solved at the application layer. Foreign keys and cascaded updates are suitable for single machine with low concurrency and are not suitable
Combined distributed and highly concurrent clusters; Cascade update is a strong blocking, and there is a risk of database update storm; Foreign keys affect the insertion speed of the database.
 

3, Build project (parent project)

1. Introduction to engineering structure

2. Module description  

Guli parent: online teaching root directory (parent project), management of four sub modules: canal client: canal database table synchronization module (statistical synchronization data) common: public module parent node

Common util: tool class module. All modules can depend on it

Service base: the base package of the service, which contains the public configuration class of the service. All service modules depend on it. Spring security: authentication and authorization module. Service services requiring authentication and authorization depend on it

infrastructure: parent node of basic service module

api gateway: api gateway service

Service: api interface service parent node

Service ACL: User Authority Management api interface service (user management, role management, authority management, etc.) service CMS: cms api interface service

Service edu: teaching related api interface serviceservice MSM: SMS api interface serviceservice order: order related api interface serviceservice OSS: Alibaba cloud oss api interface service

Service statistics: statistical report api interface service service UCenter: member api interface service service VOD: VOD api interface service

3. Create parent project

1. Create the sprigboot project Guli parent (my own is YY)_ parent)

Delete the src file below the file

2. Configuration pom file

<artifactId>   Add pom type after node

  3. Add dependency

Delete in pom.xml  < Dependencies > content

<!--The following is the deleted content-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

add to  < Properties > determine the dependent version

To the project   version control

<properties>
        <java.version>1.8</java.version>
        <guli.version>0.0.1-SNAPSHOT</guli.version>
        <mybatis-plus.version>3.0.5</mybatis-plus.version>
        <velocity.version>2.0</velocity.version>
        <swagger.version>2.7.0</swagger.version>
        <aliyun.oss.version>3.1.0</aliyun.oss.version>
        <jodatime.version>2.10.1</jodatime.version>
        <poi.version>3.17</poi.version>
        <commons-fileupload.version>1.3.1</commons-fileupload.version>
        <commons-io.version>2.6</commons-io.version>
        <httpclient.version>4.5.1</httpclient.version>
        <jwt.version>0.7.0</jwt.version>
        <aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version>
        <aliyun-sdk-oss.version>3.1.0</aliyun-sdk-oss.version>
        <aliyun-java-sdk-vod.version>2.15.2</aliyun-java-sdk-vod.version>
        <aliyun-java-vod-upload.version>1.4.11</aliyun-java-vod-upload.version>
        <aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version>
        <fastjson.version>1.2.28</fastjson.version>
        <gson.version>2.8.2</gson.version>
        <json.version>20170516</json.version>
        <commons-dbutils.version>1.7</commons-dbutils.version>
        <canal.client.version>1.1.0</canal.client.version>
        <docker.image.prefix>zx</docker.image.prefix>
        <cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version>
        <hutool-version>5.5.8</hutool-version>
    </properties>

to configure  < dependencyManagement>   Lock dependent version

It will not be imported directly here. It will only be imported after later projects are imported

<!--Dependency management-->
    <dependencyManagement>
        <dependencies>
            <!--Spring Cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mybatis-plus Persistent layer-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!-- velocity template engine, Mybatis Plus Code generator needs -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>

            <!--swagger-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <!--swagger ui-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <!--aliyunOSS-->
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun.oss.version}</version>

            </dependency>
            <!--Date time tool-->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>${jodatime.version}</version>
            </dependency>
            <!--xls-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!--xlsx-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!--File upload-->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons-fileupload.version}</version>
            </dependency>
            <!--commons-io-->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons-io.version}</version>
            </dependency>
            <!--httpclient-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>${httpclient.version}</version>
            </dependency>
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>${gson.version}</version>
            </dependency>
            <!-- JWT -->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <!--aliyun-->
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
                <version>${aliyun-java-sdk-core.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun-sdk-oss.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-vod</artifactId>
                <version>${aliyun-java-sdk-vod.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-vod-upload</artifactId>
                <version>${aliyun-java-vod-upload.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-sdk-vod-upload</artifactId>
                <version>${aliyun-sdk-vod-upload.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>${json.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-dbutils</groupId>
                <artifactId>commons-dbutils</artifactId>
                <version>${commons-dbutils.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba.otter</groupId>
                <artifactId>canal.client</artifactId>
                <version>${canal.client.version}</version>
            </dependency>

            <!--implement SQL Analysis printing-->
            <dependency>
                <groupId>p6spy</groupId>
                <artifactId>p6spy</artifactId>
                <version>3.9.1</version>
            </dependency>

            <!--hutool tool kit-->
            <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool-version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

Note: the   

aliyun-java-vod-upload                aliyun-sdk-vod-upload

The two dependencies cannot be downloaded because they are not open source and need to be downloaded manually

Link: https://pan.baidu.com/s/1zRu3tA0zWL3WArHe0UIB6Q  
Extraction code: idea  


After downloading, enter the corresponding jar package file and enter cmd

Aliyun SDK VOD upload

  Execution code:

mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.12 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.11.jar

aliyun-java-vod-upload    Execution code:

mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-java-vod-upload -Dversion=1.4.11 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.11.jar

The officially downloaded version needs to be changed. The version needs to be modified in pom and in the execution code. Here, take 1.4.11 as an example

 

4, Build service module

1. Build service module

1. In parent project YY_ Create a module service under Parent

 

  And delete the src file

  2. The added module type is pom

3. Add dependencies required by the project  

   <dependencies>
<!--    <dependency>-->
<!--        <groupId>org.springframework.cloud</groupId>-->
<!--        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>-->
<!--    </dependency>-->
<!--    &lt;!&ndash;hystrix Dependency, mainly with @HystrixCommand &ndash;&gt;-->
<!--    <dependency>-->
<!--        <groupId>org.springframework.cloud</groupId>-->
<!--        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>-->
<!--    </dependency>-->
<!--    &lt;!&ndash;Service registration&ndash;&gt;-->
<!--    <dependency>-->
<!--        <groupId>org.springframework.cloud</groupId>-->
<!--        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
<!--    </dependency>-->
<!--    &lt;!&ndash;Service call&ndash;&gt;-->
<!--    <dependency>-->
<!--        <groupId>org.springframework.cloud</groupId>-->
<!--        <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!--    </dependency>-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--mybatis-plus-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- velocity template engine, Mybatis Plus Code generator needs -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
    </dependency>
    <!--swagger-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>
    <!--lombok Used to simplify entity classes: need to install lombok plug-in unit-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--xls-->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
    </dependency>
    <!--httpclient-->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>
    <!--commons-io-->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
    </dependency>
    <!--gson-->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
    </dependency>

    <!-- JWT -->
    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    </dependency>

    <!--aliyun-->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
    </dependency>
    <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-vod</artifactId>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-vod-upload</artifactId>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-sdk-vod-upload</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-dbutils</groupId>
        <artifactId>commons-dbutils</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.otter</groupId>
        <artifactId>canal.client</artifactId>
    </dependency>
        <!--aliyunOSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>

        </dependency>
        <!--Date time tool-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>

        <dependency>
            <groupId>com.yy</groupId>
            <artifactId>service_base</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>


        <!--implement SQL Analysis printing-->
        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
        </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    </dependencies>

The first three dependencies don't need to be released first, otherwise the front code can't run

2. Build service edu module

1. Create a sub module service edu under the parent project service module

 

  5, Instructor management module configuration

1. Create a new yml file

 

#Port number
server:
  port: 8001
#service name
spring:
  application:
    name: service-edu
#Environment configuration
  profiles:
    active: dev

    #Database connection
  datasource:
    url: jdbc:p6spy:mysql://localhost:3306/yytryproject?serverTimeZone=GMT%2B8
    username: root
    password: root
    # Execute sql analysis
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    validation-query: SELECT 1

mybatis-plus journal
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2. Create MP code generator

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

//Code generator 
public class CodeGenerator {
    /**
     * <p>
     * Read console content
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("Please enter" + tip + ": ");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("Please enter the correct" + tip + "!");
    }

    public static void main(String[] args) {
        // Code generator 
        AutoGenerator mpg = new AutoGenerator();

        // Global configuration
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/service/service_edu/src/main/java");
        gc.setAuthor("Yuan Yu");
        gc.setOpen(false);
        // set name
        gc.setControllerName("%sController");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setMapperName("%sDao");
        gc.setXmlName("%sDao");
        // Set resultMap
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        // gc.setSwagger2(true);  Entity attribute Swagger2 annotation
        mpg.setGlobalConfig(gc);
        gc.setIdType(IdType.ID_WORKER_STR); //Primary key policy
        gc.setDateType(DateType.ONLY_DATE);//Defines the date type in the generated entity class
        gc.setSwagger2(true);//Turn on Swagger2 mode


        // Data source configuration
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/yytryproject?serverTimeZone=GMT%2B8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // Package configuration
        PackageConfig pc = new PackageConfig();
//        pc.setModuleName(scanner("module name");
        pc.setParent("com.yy");
        //Build package: com.achang.controller
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // Custom configuration
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // If the template engine is freemaker
//        String templatePath = "/templates/mapper.xml.ftl";
        // If the template engine is velocity
         String templatePath = "/templates/mapper.xml.vm";

        // Custom output configuration
        List<FileOutConfig> focList = new ArrayList<>();
        // Custom configuration will be output first
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // Customize the output file name. If you set the Prefix suffix for Entity, note that the name of xml will change!!
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // Configuration template
        TemplateConfig templateConfig = new TemplateConfig();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // Policy configuration
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // Public fields written in the parent class
//        strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("Table name, separated by multiple English commas").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new VelocityTemplateEngine());

        mpg.execute();
    }
}

 

This vo folder is built later

6, Write background management api interface

1. Write controller code

@RestController
@RequestMapping("/eduService/teacher")
public class EduTeacherController {

    @Autowired
    private EduTeacherService eduTeacherService;

    //Query all data of the lecturer table
    @GetMapping("/findAll")
    public List<EduTeacher> list(){
        return eduTeacherService.list(null);
    }

}

2. Create SpringBoot configuration class

Create the config package under the edu package and create MyBatisPlusConfig.java

@Configuration
@EnableTransactionManagement
@MapperScan("com.yy.service.mapper")
public class MyBatisPlusConfig {
}

3. Configure SQL execution performance analysis plug-in

Configure under MyBatisPlusConfig

/**
     * SQL Execute performance analysis plug-in
     * It is not recommended to use the development environment online. maxTime refers to the maximum sql execution time
     */
    @Bean
    @Profile({"dev","test"})// Set dev test environment on
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(1000);//ms. if the ms set here is exceeded, sql will not be executed
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

4. Create a SpringBoot startup class

Create the startup class EduApplication.java, and pay attention to the creation location of the startup class

  Directly enter main in it and press enter

  Start configuration class; Enter on the web page http://localhost:8001/eduService/teacher/findAll

  6. Unified returned json time format

 

7, Instructor logical deletion function

1. EduTeacherController add delete method

//Delete instructor logically
@DeleteMapping("{id}")
public boolean deleteTeacherById(@PathVariable String id){
    return eduTeacherService.removeById(id);
}

2. Configure logical deletion plug-ins

Configuration in MyBatisPlusConfig

@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}

3. Corresponding annotation on entity class

@TableLogic
private Boolean isDeleted;

  If it is changed to 1 in the database, this data will not appear during query

 

8, Cross domain configuration

1. What is cross domain

When a browser requests the resources of another domain name from the web page of one domain name, the domain name, port and protocol are all cross domain. In the development of front-end and back-end separation, we need to consider the problem of ajax cross domain.
Here we can solve this problem from the server

2. Disposition

Add the annotation @ CrossOrigin on the Controller class

9, Configure Swagger2 to generate API interface documents

1. Swagger2 introduction

In the front end and back-end separation development mode, api documents are the best way to communicate.
Swagger is a normative and complete framework for generating, describing, invoking, and visualizing RESTful Web services.

  Generate online interface document

Convenient interface test

  1. Timeliness (timely and accurately notify relevant front and rear end developers after interface changes)
  2. Standardization (and ensure the standardization of the interface, such as interface address, request mode, parameters, response format and error information)
  3. Consistency (the interface information is consistent, and there will be no differences due to the inconsistent document versions obtained by the developers)
  4. Testability (test directly on the interface document to facilitate business understanding)

2. Configure Swagger2

1) Create a common module so that all modules can be used

 

2) . introduce related dependencies into common  

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <scope>provided </scope>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <scope>provided </scope>
</dependency>
<!--lombok Used to simplify entity classes: need to install lombok plug-in unit-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided </scope>
</dependency>
<!--swagger-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <scope>provided </scope>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <scope>provided </scope>
</dependency>
<!-- redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- spring2.X integrate redis what is needed common-pool2
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.6.0</version>
        </dependency>-->

3) Create a sub module service base under common

 

  4) In the module service base, create the configuration class of swagger

Create package com.achang.yy.swagger  , Create the class SwaggerConfig.java

package com.yy.swagger;

import com.google.common.base.Predicates;
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.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket webApiConfig(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")
                .apiInfo(webApiInfo())
                .select()
                .paths(Predicates.not(PathSelectors.regex("/admin/.*")))
                .paths(Predicates.not(PathSelectors.regex("/error.*")))
                .build();
    }


    private ApiInfo webApiInfo(){
        return new ApiInfoBuilder()
                .title("website-Course Center API file")
                .description("This document describes the microservice interface definition of the course center")
                .version("1.0")
                .contact(new Contact("yy", "http://yy.com",
                        "1226988781@qq.com"))
                .build();
    }
}

5) . introduce service base into the service module

The coordinates of the service base are introduced into service/pom.xml

<dependencies>
    <dependency>
        <artifactId>service-base</artifactId>
        <groupId>com.achang</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

6) . add comments on the service edu startup class

@ComponentScan(basePackages = "com.yy") to scan the SwaggerConfig class

@SpringBootApplication
@ComponentScan(basePackages = {"com.yy"})
public class EduApplication {

    public static void main(String[] args) {
        SpringApplication.run(EduApplication.class, args);
    }
}

7) Testing

visit: http://localhost:8001/swagger-ui.html

 

8) API model, so that swagger has more tips

You can add some custom settings, such as:

 

 

 

10, Unified return result object
1. Unified return data format, Jason
In the project, we will package the response into json return. Generally, we will unify the data format of all interfaces to make the data operation of the front end (IOS, Android, web) more consistent and easy.

Generally, the unified return data format has no fixed format, as long as it can clearly describe the returned data status and the specific data to be returned.

However, it usually includes status code, return message and data

Our definition unifies the results:
 

{
"success": Boolean, //Is the response successful
"code": number, //Response code
"message": character string, //Return message
"data": HashMap //Return data in key value pairs
}

2. Create a unified result return class

1) . create a sub module common utils under the common module

2) Create interface definition return code

Create the package com.achang.commonutils, create the interface ResultCode.java, and extract the status code for later modification

package com.achang.commonutils;

public interface ResultCode {
    //Status code: successful
    public static Integer SUCCESS = 20000;
    //Status code: failed
    public static Integer ERROR = 20001;
}

3) , create result class

package com.yy.commonUtils;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class R {
    @ApiModelProperty("Is it successful")
    private boolean success;
    @ApiModelProperty("Response code")
    private Integer code;

    @ApiModelProperty("Return information")
    private String message;

    @ApiModelProperty("Return data")
    private Map<String, Object> data = new HashMap<String, Object>();

    public R() {
    }

    //Successful static method
    public static R ok(){
        R r = new R();
        r.setCode(ResultCode.SUCCESS);
        r.setMessage("success");
        r.setSuccess(true);
        return r;
    }

    //Successful static method
    public static R error(){
        R r = new R();
        r.setCode(ResultCode.ERROR);
        r.setMessage("fail");
        r.setSuccess(false);
        return r;
    }

    public R success(Boolean success){
        this.setSuccess(success);
        return this;
    }

    public R code(Integer code){
        this.setCode(code);
        return this;
    }

    public R message(String message){
        this.setMessage(message);
        return this;
    }

    public R data(String key,Object value){
        this.data.put(key,value);
        return this;
    }

    public R data(Map<String,Object> map){
        this.setData(map);
        return this;
    }

}

3. Unified use of returned results

1) . add dependencies in the service module

<dependency>
    <groupId>com.achang</groupId>
    <artifactId>common-utils</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

2) . modify the returned results in the Controller

The returned result of modification is R

 

11, Development of paging and multi condition query interface

1. Pagination

1) . configure paging plug-in in MyBatisPlusConfig

/**
* Paging plug-in
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}

2) . paging Controller method

  //3. Paging query lecturer function
    @ApiOperation("Paging query instructor function")
    @GetMapping("pageTeacher/{current}/{limit}")
    public R pageTeacher(@PathVariable Long current,@PathVariable Long limit){

        Page<EduTeacher> pageTeacher = new Page<>(limit,current);
        IPage<EduTeacher> teacherPageList = eduTeacherService.page(pageTeacher, null);
        List<EduTeacher> records = teacherPageList.getRecords();
        long total = teacherPageList.getTotal();
        Map<String,Object> data = new HashMap();
        data.put("total",total);
        data.put("rows",records);
        return R.ok().data(data);
    }

3) Test in Swagger

 

 

2. Multi condition combined query with paging


According to lecturer name, lecturer Title level and lecturer residence time gmt_create query

1) . create query object

Create service_ The com.achang.eduservice.entity.vo package in edu creates a TeacherQuery.java query object

@Data
public class TeacherQuery {

    private Long current;
    private Long limit;
    @ApiModelProperty(value = "Teacher name,Fuzzy query")
    private String name;

    @ApiModelProperty(value = "Title 1 General lecturer 2 senior lecturer 3 super lecturer")
    private Integer level;

    @ApiModelProperty(value = "Query start time", example = "2019-01-01 10:10:10")
    private String begin;//Note that the String type is used here, and the data passed from the front end does not need type conversion
//    private Date begin;

    @ApiModelProperty(value = "Query end time", example = "2019-12-01 10:10:10")
    private String end;
//    private Date end;
}

The properties of TeacherQuery are set according to the query criteria required by the front end
@RequestBody(required = false) indicates that the parameter TeacherQuery teacherQuery is added, which is not required

 //4. Conditional query with paging method
    @ApiOperation("Conditional query with paging method")
    @PostMapping("pageTeacherCondition")
    public R pageTeacherCondition(@RequestBody(required = false) TeacherQuery teacherQuery){
        Long current = teacherQuery.getCurrent();
        Long limit = teacherQuery.getLimit();

        IPage<EduTeacher> teacherPageList = eduTeacherService.pageList(current,limit,teacherQuery);
        List<EduTeacher> records = teacherPageList.getRecords();
        long total = teacherPageList.getTotal();
        Map<String,Object> data = new HashMap<>();
        data.put("tatol", total);
        data.put("rows", records);
        return R.ok().data(data);

    }

2),service

public interface EduTeacherService extends IService<EduTeacher> {

    IPage<EduTeacher> pageList(Long current, Long limit, TeacherQuery teacherQuery);
}

2) . implementation class impl

@Service
public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherDao, EduTeacher> implements EduTeacherService {


    public IPage<EduTeacher> pageList(Long current, Long limit, TeacherQuery teacherQuery) {
        Integer level = teacherQuery.getLevel();
        String name = teacherQuery.getName();
        String begin = teacherQuery.getBegin();
        String end = teacherQuery.getEnd();
        LambdaQueryWrapper<EduTeacher> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(level!=null, EduTeacher::getLevel,level)
                .like(StringUtils.isNotBlank(name),EduTeacher::getName,name)
                .ge(begin!=null,EduTeacher::getGmtCreate,begin)
                .le(end!=null, EduTeacher::getGmtModified,end);
        return this.page(new Page<>(current,limit), queryWrapper);
    }
}

12, Add and modify instructor interface development

1. Auto fill package

Add automatic filling and encapsulation function of new time and modification time to new data and modified data

1) . add in the service base module

Create the package MyMetaObjectHandler and create the autofill class MyMetaObjectHandler

@Component
public class MyMetaObjectHandler implements MetaObjectHandler{

    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("gmtCreate",new Date(),metaObject);
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }

    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }
}

2) Add auto fill annotation in entity class

 

2. controller method definition

1) . NEW

    //5. New teachers
    @ApiOperation("New teacher interface")
    @PostMapping("addTeacher")
    public R addTeacher(@RequestBody EduTeacher eduTeacher){
        boolean save = eduTeacherService.save(eduTeacher);
        return save?R.ok():R.error().message("Failed to add. Please contact the administrator");
    }

2) . query by id

    //6.1 new teachers
    @ApiOperation("according to id Query teacher")
    @GetMapping("getById/{id}")
    public R getById(@PathVariable String id){
        EduTeacher teacherInfo = eduTeacherService.getById(id);
        return teacherInfo!=null?R.ok().data("data", teacherInfo):R.error().message("Teacher does not exist");
    }

3) . modify lecturer

@ApiOperation("according to id Modify teacher information")
    @PostMapping("updateById")
    public R updateById(@RequestBody EduTeacher eduTeacher){
        EduTeacher teacherInfo = eduTeacherService.getById(eduTeacher.getId());
        if (teacherInfo==null){
            return R.error().message("Teacher does not exist");
        }
        boolean updateStatus = eduTeacherService.updateById(eduTeacher);
        return updateStatus?R.ok():R.error().message("Modification failed");
    }

13, Unified exception handling

1. Unified exception handling

1) , create a unified exception handler

Introduce dependency: because you want to use the return class R in common utils

  In service_ Create a unified exception handling class exceptionHandler/GlobalExceptionHandler.java in base:

@ControllerAdvice
public class GlobalExceptionHandler {
    //Global exception handling
    @ExceptionHandler(Exception.class)
    //Because he's not here. There is no @ RestController, so the data will not be returned. You need to add @ ResponseBody to return the data
    @ResponseBody
    public R error(Exception e){
        e.printStackTrace();
        return R.error().message("Global exception executed");
    }
}

2) , test

2. Handling specific exceptions

1) . add exception handling method

Added in exceptionHandler/GlobalExceptionHandler.java

    //Specifies that the exception will execute this method
    @ExceptionHandler(ArithmeticException.class)  //Execute the specified exception first. If no exception is specified, a global exception will be thrown
    //Because he's not here. There is no @ RestController, so the data will not be returned. You need to add @ ResponseBody to return the data
    @ResponseBody
    public R error(ArithmeticException e){
        e.printStackTrace();
        return R.error().message("The specified exception was executed");
    }

2) , test

3. Custom exception

1) Create a custom exception class

 

2) . throw an AchangException at the required position in the business

Throw custom exception classes directly where needed

 

3) . add exception handling method

Add a handler to exceptionHandler/GlobalExceptionHandler to handle this exception

    //The custom exception executes this method
    @ExceptionHandler(RRException.class)  //The system will not process it and needs to output it manually
    //Because he's not here. There is no @ RestController, so the data will not be returned. You need to add @ ResponseBody to return the data
    @ResponseBody
    public R error(RRException e){
        e.printStackTrace();
        return R.error().code(e.getCode()).message(e.getMsg());
    }

4) , test

Tags: Java Spring intellij-idea

Posted on Wed, 08 Sep 2021 01:59:00 -0400 by jackson4me90