当前位置: 首页 > news >正文

从0到1项目搭建-框架搭建(附源码)

前言

大家好,本文是基于 SpringBoot 从0搭建一个企业级开发项目,基于SpringBoot 的项目,并集成MyBatis-Plus、Druid、Logback 等主流技术。希望对大家有所帮助~

目录

    • 前言
    • 一、概述
    • 二、创建统一的依赖管理
      • 2.1、统一的依赖管理工程创建
      • 2.2、Maven托管
    • 三、创建通用模块
      • 3.1、创建通用模块工程
      • 3.2、Maven托管
      • 3.3、完善目录结构
      • 3.4、定义通用类库
        • 3.4.1、返回状态码
        • 3.4.2、通用返回结果
        • 3.4.3、通用工具类
    • 四、创建项目服务模块
      • 4.1、创建项目服务模块工程
      • 4.2、Maven托管
      • 4.3、完善目录结构
      • 4.4、创建 Application
      • 4.5、整合 Logback
      • 4.6、整合 Druid 数据库连接池
    • 五、创建代码生成模块
      • 5.1、创建代码生成模块工程
      • 5.2、Maven托管
      • 5.3、完善目录结构
      • 5.4、测试代码生成
      • 5.5、测试生成效果
      • 5.6、测试 Controller 层
    • 六、源码获取

一、概述

随着技术栈的不断更新迭代,我们需要快速的在企业中搭建一个项目,并使用市面上前沿且稳定的技术栈。本期将跟大家一起从0到1搭建一个基于SpringBoot 的项目,并集成MyBatis-Plus、Druid、Logback 等主流技术。后续也会整合 Docker,自定义构建 Docker 项目,实现 Docker Compose 部署。源码附在文末。

二、创建统一的依赖管理

2.1、统一的依赖管理工程创建

创建一个名称为 my-project-dependencies的项目,该项目负责统一的依赖管理

pom.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
    </parent>

    <groupId>com.micromaple</groupId>
    <artifactId>my-project-dependencies</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>my-project-dependencies</name>

    <properties>
        <!-- Environment Settings -->
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring Settings -->
        <spring-boot-alibaba-druid.version>1.2.11</spring-boot-alibaba-druid.version>
        <spring-boot-mybatis-plus.version>3.5.2</spring-boot-mybatis-plus.version>

        <!-- Environment Setting -->
        <mysql.version>8.0.30</mysql.version>
        <lombok.version>1.18.18</lombok.version>
        <guava.version>25.1-jre</guava.version>
        <jackson.version>2.11.4</jackson.version>
        <apache-httpclient.version>4.5.5</apache-httpclient.version>
        <collections.version>3.2.1</collections.version>

        <!-- Common Setting-->
        <poi.version>3.10-FINAL</poi.version>
        <hutool.version>5.3.7</hutool.version>
        <velocity.version>2.3</velocity.version>
        <hibernate-validator.version>6.0.15.Final</hibernate-validator.version>
        <!-- log4j2 -->
        <log4j2.version>2.16.0</log4j2.version>

        <!-- mybatis-plus-generator -->
        <mybatis-plus-generator.version>3.5.1</mybatis-plus-generator.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot Starter Begin -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${spring-boot-alibaba-druid.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${spring-boot-mybatis-plus.version}</version>
            </dependency>
            <!-- Spring Boot Starter End -->

            <!-- Environment Begin -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${collections.version}</version>
            </dependency>
            <!-- Environment End -->

            <!-- Apache Http Begin -->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>${apache-httpclient.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>fluent-hc</artifactId>
                <version>${apache-httpclient.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpmime</artifactId>
                <version>${apache-httpclient.version}</version>
            </dependency>
            <!-- Apache Http End -->

            <!-- Common Begin -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>
            <!-- Common End -->

            <!--mybatis-plus代码生成器-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>${mybatis-plus-generator.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!-- Compiler 插件, 设定 JDK 版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>

            <!-- 打包 jar 文件时,配置 manifest 文件,加入 lib 包的 jar 依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <configuration>
                            <archive>
                                <manifest>
                                    <!-- Add directory entries -->
                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                                    <addClasspath>true</addClasspath>
                                </manifest>
                            </archive>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- resource -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
            </plugin>

            <!-- install -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
            </plugin>

            <!-- clean -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
            </plugin>

            <!-- ant -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
            </plugin>

            <!-- dependency -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <!-- Java Document Generate -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- YUI Compressor (CSS/JS压缩) -->
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>yuicompressor-maven-plugin</artifactId>
                    <version>1.5.1</version>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>compress</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <encoding>UTF-8</encoding>
                        <jswarn>false</jswarn>
                        <nosuffix>true</nosuffix>
                        <linebreakpos>30000</linebreakpos>
                        <force>true</force>
                        <includes>
                            <include>**/*.js</include>
                            <include>**/*.css</include>
                        </includes>
                        <excludes>
                            <exclude>**/*.min.js</exclude>
                            <exclude>**/*.min.css</exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

        <!-- 资源文件配置 -->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>
</project>

2.2、Maven托管

将其交给Maven托管
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、创建通用模块

3.1、创建通用模块工程

创建一个名称为 my-project-common的项目,该项目负责通用的类库以及工具类

pom.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.micromaple</groupId>
        <artifactId>my-project-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../my-project-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>my-project-common</artifactId>
    <packaging>jar</packaging>

    <name>my-project-common</name>

    <dependencies>
        <!-- Commons Begin-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!-- Commons End-->

        <!-- Environment Begin -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </dependency>
        <!-- Environment End -->

        <!-- Apache Http Begin -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>fluent-hc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
        </dependency>
        <!-- Apache Http End -->
    </dependencies>
</project>

3.2、Maven托管

可以使用右侧的Maven+ 号来进行项目的托管。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3、完善目录结构

创建 src/main/java 目录后,创建包名,包名为:com.micromaple.my.project.common

此工程是放一些通用的类库或者是工具类之类的。

3.4、定义通用类库

3.4.1、返回状态码

创建常量包constant

通用常量返回状态码HttpStatus

package com.micromaple.my.project.common.constant;

/**
 * 返回状态码
 * Title: HttpStatus
 * Description:
 *
 * @author Micromaple
 */
public class HttpStatus {
    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功,但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;
}

3.4.2、通用返回结果

创建数据传输包dto

通用数据传输返回结果BaseResult

package com.micromaple.my.project.common.dto;

import com.micromaple.my.project.common.constant.HttpStatus;

import java.util.HashMap;

/**
 * 返回结果
 * Title: BaseResult
 * Description:
 *
 * @author Micromaple
 */
public class BaseResult extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    public static final String CODE_TAG = "code";

    /**
     * 返回内容
     */
    public static final String MSG_TAG = "msg";

    /**
     * 数据对象
     */
    public static final String DATA_TAG = "data";

    /**
     * 初始化一个新创建的 BaseResult 对象,使其表示一个空消息。
     */
    public BaseResult() {
    }

    /**
     * 初始化一个新创建的 BaseResult 对象
     *
     * @param code 状态码
     * @param msg  返回内容
     */
    public BaseResult(int code, String msg) {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }

    /**
     * 初始化一个新创建的 BaseResult 对象
     *
     * @param code 状态码
     * @param msg  返回内容
     * @param data 数据对象
     */
    public BaseResult(int code, String msg, Object data) {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        super.put(DATA_TAG, data);
    }

    /**
     * 返回成功消息
     *
     * @return 成功消息
     */
    public static BaseResult success() {
        return BaseResult.success("操作成功");
    }

    /**
     * 返回成功数据
     *
     * @return 成功消息
     */
    public static BaseResult success(Object data) {
        return BaseResult.success("操作成功", data);
    }

    /**
     * 返回成功消息
     *
     * @param msg 返回内容
     * @return 成功消息
     */
    public static BaseResult success(String msg) {
        return BaseResult.success(msg, null);
    }

    /**
     * 返回成功消息
     *
     * @param msg  返回内容
     * @param data 数据对象
     * @return 成功消息
     */
    public static BaseResult success(String msg, Object data) {
        return new BaseResult(HttpStatus.SUCCESS, msg, data);
    }

    /**
     * 返回错误消息
     *
     * @return
     */
    public static BaseResult error() {
        return BaseResult.error("操作失败");
    }

    /**
     * 返回错误消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static BaseResult error(String msg) {
        return BaseResult.error(msg, null);
    }

    /**
     * 返回错误消息
     *
     * @param msg  返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static BaseResult error(String msg, Object data) {
        return new BaseResult(HttpStatus.ERROR, msg, data);
    }

    /**
     * 返回错误消息
     *
     * @param code 状态码
     * @param msg  返回内容
     * @return 警告消息
     */
    public static BaseResult error(int code, String msg) {
        return new BaseResult(code, msg, null);
    }
}

3.4.3、通用工具类

创建工具类包utils

通用Jackson工具类MapperUtils

package com.micromaple.my.project.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Jackson 工具类
 * Title: MapperUtils
 * Description:
 *
 * @author Micromaple
 */
public class MapperUtils {
    private final static ObjectMapper objectMapper = new ObjectMapper();

    public static ObjectMapper getInstance() {
        return objectMapper;
    }

    /**
     * 转换为 JSON 字符串
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2json(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 转换为 JSON 字符串,忽略空值
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2jsonIgnoreNull(Object obj) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsString(obj);
    }

    /**
     * 转换为 JavaBean
     *
     * @param jsonString
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T json2pojo(String jsonString, Class<T> clazz){
        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        try{
            return objectMapper.readValue(jsonString, clazz);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 字符串转换为 Map<String, Object>
     *
     * @param jsonString
     * @return
     * @throws Exception
     */
    public static <T> Map<String, Object> json2map(String jsonString){
        if(StringUtils.isBlank(jsonString)) return null;
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        try {
            return mapper.readValue(jsonString, Map.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 深度转换 JSON 成 Map
     *
     * @param json
     * @return
     */
    public static Map<String, Object> json2mapDeeply(String json) throws Exception {
        return json2MapRecursion(json, objectMapper);
    }

    /**
     * 把 JSON 解析成 List,如果 List 内部的元素存在 jsonString,继续解析
     *
     * @param json
     * @param mapper 解析工具
     * @return
     * @throws Exception
     */
    private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        }

        List<Object> list = mapper.readValue(json, List.class);

        for (Object obj : list) {
            if (obj != null && obj instanceof String) {
                String str = (String) obj;
                if (str.startsWith("[")) {
                    obj = json2ListRecursion(str, mapper);
                } else if (obj.toString().startsWith("{")) {
                    obj = json2MapRecursion(str, mapper);
                }
            }
        }

        return list;
    }

    /**
     * 把 JSON 解析成 Map,如果 Map 内部的 Value 存在 jsonString,继续解析
     *
     * @param json
     * @param mapper
     * @return
     * @throws Exception
     */
    private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        }

        Map<String, Object> map = mapper.readValue(json, Map.class);

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Object obj = entry.getValue();
            if (obj != null && obj instanceof String) {
                String str = ((String) obj);

                if (str.startsWith("[")) {
                    List<?> list = json2ListRecursion(str, mapper);
                    map.put(entry.getKey(), list);
                } else if (str.startsWith("{")) {
                    Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
                    map.put(entry.getKey(), mapRecursion);
                }
            }
        }

        return map;
    }

    /**
     * 将 JSON 数组转换为集合
     *
     * @param jsonArrayStr
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
        return list;
    }


    /**
     * 获取泛型的 Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * 将 Map 转换为 JavaBean
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T map2pojo(T map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }

    /**
     * 将 Map 转换为 JSON
     *
     * @param map
     * @return
     */
    public static String mapToJson(Map map) {
        try {
            return objectMapper.writeValueAsString(map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 将 JSON 对象转换为 JavaBean
     *
     * @param obj
     * @param clazz
     * @return
     */
    public static <T> T obj2pojo(Object obj, Class<T> clazz) {
        return objectMapper.convertValue(obj, clazz);
    }
}

HttpClient 工具类

package com.micromaple.my.project.common.utils;

import com.google.common.collect.Maps;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

/**
 * HttpClient 工具类
 * Title: HttpClientUtils
 * Description:
 *
 * @author Micromaple
 */
public class HttpClientUtils {

    public static final String GET = "get";
    public static final String POST = "post";

    public static final String REQUEST_HEADER_CONNECTION = "keep-alive";
    public static final String REQUEST_HEADER_CONTENTTYPE = "application/json;charset=UTF-8";
    public static final String REQUEST_HEADER_CONSUMES = "application/json";

    //设置连接超时时间,单位毫秒。
    public static final int CONNECTTIMEOUT = 18000;
    //请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。
    public static final int SOCKETTIMEOUT = 60000;
    //设置从connect Manager获取Connection 超时时间,单位毫秒
    public static final int CONNECTIONREQUESTTIMEOUT = 18000;


    /**
     * GET 请求
     *
     * @param url 请求地址
     * @return
     */
    public static String doGet(String url) {
        return createRequest(url, GET, null, false, null, 0);
    }

    /**
     * GET 请求 - 代理
     *
     * @param url       请求地址
     * @param useProxy  是否需要代理
     * @param proxyHost 代理地址
     * @param proxyPort 代理端口
     * @return
     */
    public static String doGet(String url, boolean useProxy, String proxyHost, int proxyPort) {
        return createRequest(url, GET, null, useProxy, proxyHost, proxyPort);
    }

    /**
     * GET 请求
     *
     * @param url    请求地址
     * @param cookie cookie
     * @return
     */
    public static String doGet(String url, String cookie) {
        return createRequest(url, GET, cookie, false, null, 0);
    }

    /**
     * POST 请求
     *
     * @param url    请求地址
     * @param params 请求参数(可选)
     * @return
     */
    public static String doPost(String url, BasicNameValuePair... params) {
        return createRequest(url, POST, null, false, null, 0, params);
    }

    /**
     * POST 请求 - 代理
     *
     * @param url       请求地址
     * @param useProxy  是否需要代理
     * @param proxyHost 代理地址
     * @param proxyPort 代理端口
     * @param params    请求参数(可选)
     * @return
     */
    public static String doPost(String url, boolean useProxy, String proxyHost, int proxyPort, BasicNameValuePair... params) {
        return createRequest(url, POST, null, useProxy, proxyHost, proxyPort, params);
    }

    /**
     * POST 请求
     *
     * @param url    请求地址
     * @param cookie cookie
     * @param params 请求参数(可选)
     * @return
     */
    public static String doPost(String url, String cookie, BasicNameValuePair... params) {
        return createRequest(url, POST, cookie, false, null, 0, params);
    }

    /**
     * POST 请求 - 文本 方式
     *
     * @param url            请求地址
     * @param jsonBodyParams 请求参数 (JSON 格式)
     * @return
     */
    public static String doPostForRow(String url, String jsonBodyParams) {
        return createRequestForRow(url, jsonBodyParams, false, null, 0);
    }

    /**
     * POST 请求 - 文本 方式 - 代理
     *
     * @param url            请求地址
     * @param jsonBodyParams 请求参数
     * @param useProxy       是否需要代理
     * @param proxyHost      代理地址
     * @param proxyPort      代理端口
     * @return
     */
    public static String doPostForRow(String url, String jsonBodyParams, boolean useProxy, String proxyHost, int proxyPort) {
        return createRequestForRow(url, jsonBodyParams, useProxy, proxyHost, proxyPort);
    }

    /**
     * POST 请求
     *
     * @param url       请求地址
     * @param pMap      请求参数
     * @param useProxy  是否需要代理
     * @param proxyHost 代理地址
     * @param proxyPort 代理端口
     * @return
     */
    public static Map<String, Object> doPost(String url, Map<String, String> pMap, boolean useProxy, String proxyHost, int proxyPort) {
        String str = HttpClientUtils.doPost(url, useProxy, proxyHost, proxyPort, generatNameValuePair(pMap));
        Map<String, Object> rtnMap = Maps.newHashMap();
        try {
            rtnMap = MapperUtils.json2map(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rtnMap;
    }

    /**
     * 创建请求
     *
     * @param url           请求地址
     * @param requestMethod 请求方式 GET/POST
     * @param cookie        cookie
     * @param useProxy      是否需要代理
     * @param proxyHost     代理地址
     * @param proxyPort     代理端口
     * @param params        请求参数 仅限于 POST 请求用
     * @return
     */
    private static String createRequest(String url, String requestMethod, String cookie, boolean useProxy, String proxyHost, int proxyPort, BasicNameValuePair... params) {
        //创建 HTTPClient 客户端
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = getHttpClient(useProxy, proxyHost, proxyPort);
        String result = null;

        try {
            //请求结果
            result = null;

            //请求方式
            HttpGet httpGet = null;
            HttpPost httpPost = null;

            //响应
            CloseableHttpResponse httpResponse = null;

            // GET 请求
            if (GET.equals(requestMethod)) {
                httpGet = new HttpGet(url);
                httpGet.setHeader("Connection", REQUEST_HEADER_CONNECTION);
                httpGet.setHeader("Cookie", cookie);

                httpResponse = httpClient.execute(httpGet);
            }

            // POST 请求
            else if (POST.equals(requestMethod)) {
                httpPost = new HttpPost(url);
                httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
                httpPost.setHeader("Cookie", cookie);

                //有参数进来
                if (params != null && params.length > 0) {
                    httpPost.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), "UTF-8"));
                }

                httpResponse = httpClient.execute(httpPost);
            }

            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * 创建 ROW POST 请求
     *
     * @param url           请求地址
     * @param jsonBodyParam 请求参数 (JSON 格式)
     * @param useProxy      是否需要代理
     * @param proxyHost     代理地址
     * @param proxyPort     代理端口
     * @return
     */
    private static String createRequestForRow(String url, String jsonBodyParam, boolean useProxy, String proxyHost, int proxyPort) {
        //创建 HTTPClient 客户端
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = getHttpClient(useProxy, proxyHost, proxyPort);
        String result = null;
        try {
            //请求结果
            result = null;

            //请求方式
            HttpPost httpPost = null;

            //响应
            CloseableHttpResponse httpResponse = null;

            httpPost = new HttpPost(url);
            httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
            httpPost.setHeader("Content-Type", REQUEST_HEADER_CONTENTTYPE);
            httpPost.setHeader("consumes", REQUEST_HEADER_CONSUMES);

            httpPost.setEntity(new StringEntity(jsonBodyParam, "UTF-8"));

            httpResponse = httpClient.execute(httpPost);

            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }


    /**
     * 创建 HttpClient 客户端
     *
     * @param useProxy  是否代理
     * @param proxyHost 代理地址
     * @param proxyPort 代理端口
     * @return
     */
    private static CloseableHttpClient getHttpClient(boolean useProxy, String proxyHost, int proxyPort) {
        CloseableHttpClient httpClient = null;
        if (useProxy) {
            //设置代理IP、端口、协议
            HttpHost proxy = new HttpHost(proxyHost, proxyPort, "http");

            //把代理设置到请求配置
            //setConnectTimeout:设置连接超时时间,单位毫秒。
            //setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
            //setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECTTIMEOUT)
                    .setSocketTimeout(SOCKETTIMEOUT)
                    .setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)
                    .setProxy(proxy)
                    .build();

            //创建 HTTPClient 客户端
            httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        } else {
            //setConnectTimeout:设置连接超时时间,单位毫秒。
            //setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
            //setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECTTIMEOUT)
                    .setSocketTimeout(SOCKETTIMEOUT)
                    .setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)
                    .build();

            //创建 HTTPClient 客户端
            httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        }

        return httpClient;
    }

    /**
     * MAP类型数组转换成BasicNameValuePair类型
     *
     * @param properties MAP类型数组
     * @return BasicNameValuePair类型数组
     */
    private static BasicNameValuePair[] generatNameValuePair(Map<String, String> properties) {
        BasicNameValuePair[] basicNameValuePairs = new BasicNameValuePair[properties.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : properties.entrySet()) {
            basicNameValuePairs[i++] = new BasicNameValuePair(entry.getKey(), entry.getValue());
        }
        return basicNameValuePairs;
    }
}

创建好后,目录结构效果如下:
在这里插入图片描述

四、创建项目服务模块

4.1、创建项目服务模块工程

创建一个名称为 my-project-server的项目,该项目负责实现具体业务,以及提供服务。

pom.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.micromaple</groupId>
        <artifactId>my-project-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../my-project-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>my-project-server</artifactId>
    <packaging>jar</packaging>

    <name>my-project-server</name>

    <dependencies>
        <!-- Project Begin -->
        <dependency>
            <groupId>com.micromaple</groupId>
            <artifactId>my-project-common</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <!-- Project End -->

        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Environment Begin -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- Environment End -->
        <!-- Common Begin -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
        <!-- Common End -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass></mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

4.2、Maven托管

可以使用右侧的Maven+ 号来进行项目的托管。

4.3、完善目录结构

创建 src/main/javasrc/main/resource 目录

src/main/java 目录下创建包名,包名为:com.micromaple.my.project.server

src/main/resource 目录下创建application.yml,内容如下:

# Spring配置
spring:
  jackson:
    #时间戳统一转换为指定格式
    date-format: yyyy-MM-dd HH:mm:ss
    # 时区修改为东8区
    time-zone: GMT+8
server:
  port: 8899

4.4、创建 Application

这里使用 Spring 提供的 MyBatis 包扫面注解

package com.micromaple.my.project.server;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(value = "com.micromaple.my.project.server.mapper")
public class MyProjectServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyProjectServerApplication.class, args);
    }
}

pom.xml 中的 mainClass 指定该 Application

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.micromaple.my.project.server.MyProjectServerApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

4.5、整合 Logback

src/main/resource 目录下创建logback-spring.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <substitutionProperty name="logBase" value="./logs/" />
    <substitutionProperty name="logName" value="my-project-server" />
    <substitutionProperty name="logPatternExp" value="%date{YYYY-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{9999} %L -=> %msg%n" />

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${logPatternExp}</pattern>
        </encoder>
    </appender>

    <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logBase}${logName}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logBase}${logName}-%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
            <maxHistory>180</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>30MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>${logPatternExp}</pattern>
        </encoder>
    </appender>

    <!-- project default level -->
    <logger name="com.micromaple.my.project.server" level="DEBUG" />
    <logger name="org.springframework" level="ERROR" />

    <!-- root -->
    <root level="DEBUG">
        <appender-ref ref="console" />
        <appender-ref ref="rollingFile" />
    </root>
</configuration>

application.yml增加配置:

logging:
  config: classpath:logback-spring.xml

4.6、整合 Druid 数据库连接池

src/main/resource 目录下创建application-druid.yml,内容如下:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.110.135:3306/my-project?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123456
    druid:
      #连接池配置 初始化连接池的连接数量 大小,最小,最大
      initial-size: 5
      min-idle: 5
      max-active: 20
      #配置获取连接等待超时的时间
      max-wait: 60000
      #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 30000
      validation-query: SELECT 1 FROM DUAL
      test-while-idle: true
      test-on-borrow: true
      test-on-return: false
      # 是否缓存preparedStatement,也就是PSCache  官方建议MySQL下建议关闭   个人建议如果想用SQL防火墙 建议打开
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      filter:
        stat:
          merge-sql: true
          slow-sql-millis: 5000
      #3.基础监控配置
      web-stat-filter:
        enabled: true
        url-pattern: /*
        #设置不统计哪些URL
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
        session-stat-enable: true
        session-stat-max-count: 100
      stat-view-servlet:
        enabled: true
        # 数据监控访问路径
        url-pattern: /druid/*
        reset-enable: true
        #设置监控页面的登录名和密码
        login-username: admin
        login-password: admin
        allow: 127.0.0.1

application.yml 增加配置,内容如下:

# Spring配置
spring:
  # 启用指定配置文件
  #(文件名需满足application-{profile}.yml的格式)
  profiles:
    active: druid

application.yml 完整配置如下:

# Spring配置
spring:
  jackson:
    #时间戳统一转换为指定格式
    date-format: yyyy-MM-dd HH:mm:ss
    # 时区修改为东8区
    time-zone: GMT+8
  # 启用指定配置文件
  #(文件名需满足application-{profile}.yml的格式)
  profiles:
    active: druid
server:
  port: 8899
logging:
  config: classpath:logback-spring.xml

最终项目效果图如下:
在这里插入图片描述

五、创建代码生成模块

5.1、创建代码生成模块工程

创建一个名称为 my-project-generator的项目,该项目负责通过数据库自动生成通用的增删改查。

pom.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.micromaple</groupId>
        <artifactId>my-project-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../my-project-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>my-project-generator</artifactId>
    <packaging>jar</packaging>

    <name>my-project-generator</name>

    <dependencies>
        <!-- Project Begin -->
        <dependency>
            <groupId>com.micromaple</groupId>
            <artifactId>my-project-common</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <!-- Project End -->

        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Environment Begin -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <!-- Environment End -->

        <!-- MP  代码生成工具需要的依赖1 velocity-engine-core 2 slf4j-api   3slf4j-log4j12 -->
        <!-- Apache velocity -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
        </dependency>

        <!--freemarker模板-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>
        <!-- Common End -->

        <!--mybatis-plus代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
        </dependency>
    </dependencies>
</project>

5.2、Maven托管

可以使用右侧的Maven+ 号来进行项目的托管。

5.3、完善目录结构

创建 src/main/javasrc/main/resource 目录

src/main/java 目录下创建包名,包名为:com.micromaple.my.project.generator

创建代码生成类,内容如下:

package com.micromaple.my.project.generator;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;

import java.util.Collections;

/**
 * 代码生成
 * Title: GeneratorApplication
 * Description:
 *
 * @author Micromaple
 */
public class GeneratorApplication {

    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir");

        String finalProjectPath = projectPath + "/my-project-generator";
        // 数据源配置
        DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig
                .Builder(
                "jdbc:mysql://192.168.110.135:3306/my-project?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8",
                "root",
                "123456")
                .dbQuery(new MySqlQuery())
                .typeConvert(new MySqlTypeConvert())
                .keyWordsHandler(new MySqlKeyWordsHandler());

        new StrategyConfig.Builder()
                .serviceBuilder()
                .formatServiceFileName("%sService")
                .formatServiceImplFileName("%sServiceImp")
                .build();

        FastAutoGenerator.create(dataSourceConfig)
                .globalConfig(builder -> {
                    builder.author("Micromaple") //设置作者
                            .commentDate("yyyy-MM-dd HH:mm:ss")//注释日期
                            .outputDir(finalProjectPath + "/src/main/java"); //指定输出目录

                })
                .packageConfig(builder -> {
                    builder.parent("com.micromaple.my.project.server")
                            .moduleName("") // 设置父包模块名
                            .entity("domain") //设置entity包名
                            //.other("model.dto") // 设置dto包名
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, finalProjectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("sys_user") // 设置需要生成的表名
                            .addTablePrefix("tb_"); // 设置过滤表前缀
                    builder.entityBuilder().enableLombok();//开启 lombok 模型
                    builder.entityBuilder().enableTableFieldAnnotation();//开启生成实体时生成字段注解
                    builder.controllerBuilder().enableRestStyle();//开启生成@RestController 控制器
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();
    }
}

5.4、测试代码生成

建表语句:

CREATE TABLE `sys_user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `code` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '编号',
  `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
  `sex` varchar(2) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '性别',
  `age` int DEFAULT NULL COMMENT '年龄',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `mail` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱',
  `created_date` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_date` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表'

新增数据:

insert into `sys_user` (`code`, `name`, `sex`, `age`, `birthday`, `mail`, `created_date`, `updated_date`) values('admin','超级管理员','男','18','2004-01-01','micromaple@qq.com','2022-09-21 21:48:33',NULL);

执行 GeneratorApplication 类的 main 方法后,可以看到生成的代码,效果如下图:
在这里插入图片描述

将其拷贝到my-project-server工程模块中,完整效果如下:
在这里插入图片描述

5.5、测试生成效果

我们在 my-project-server 工程编写单元测试,测试生成的代码是否可用。

创建 src/test/java 目录,在该目录创建包 com.micromaple.my.project.server.service

接着创建测试类 SysUserServiceTest,内容如下:

package com.micromaple.my.project.server.service;

import com.micromaple.my.project.server.MyProjectServerApplication;
import com.micromaple.my.project.server.domain.SysUser;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@SpringBootTest(classes = MyProjectServerApplication.class)
@RunWith(SpringRunner.class)
public class SysUserServiceTest {

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 测试新增
     */
    @Test
    public void addTest() {
        SysUser sysUser = new SysUser();
        sysUser.setCode("user");
        sysUser.setName("用户");
        sysUser.setSex("女");
        sysUser.setAge(18);
        boolean save = sysUserService.save(sysUser);
        System.out.println(save);
        // 输出 true 代表插入成功
    }

    /**
     * 测试查询
     */
    @Test
    public void selectTest() {
        List<SysUser> sysUsers = sysUserService.getBaseMapper().selectList(null);
        for (SysUser sysUser : sysUsers) {
            System.out.println(sysUser.getName());
        }
        /**
         * 输出内容如下:
         * 超级管理员
         * 用户
         */
    }
}

5.6、测试 Controller 层

SysUserController 代码如下:

package com.micromaple.my.project.server.controller;


import com.micromaple.my.project.common.dto.BaseResult;
import com.micromaple.my.project.common.utils.MapperUtils;
import com.micromaple.my.project.server.domain.SysUser;
import com.micromaple.my.project.server.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author Micromaple
 * @since 2022-09-21 21:51:15
 */
@RestController
@RequestMapping("/sys-user")
public class SysUserController {

    @Autowired
    private ISysUserService sysUserService;

    @GetMapping("/get/all")
    public BaseResult getAll() {
        List<SysUser> sysUsers = sysUserService.getBaseMapper().selectList(null);
        return BaseResult.success(sysUsers);
    }
}

启动 MyProjectServerApplication 服务,访问地址:

http://localhost:8899/sys-user/get/all

效果如下:
在这里插入图片描述

六、源码获取

源码在 GitHub码云,持续更新中,别忘了 star 喔~

GitHub

https://github.com/micromaples/my-project

码云gitee

https://gitee.com/micromaple/my-project

读到这里,想必你已经知道了如何搭建一个Spring Boot项目,并整合其他技术栈,快跟着一起动手吧。别忘了三连支持博主呀~

我是微枫Micromaple,期待你的关注~💪💪💪

相关文章:

  • Windows 11 Insider Preview Build 22621.730/22623.730(KB5017385)发布!
  • 当图网络遇上计算机视觉!计算机视觉中基于图神经网络和图Transformer的方法和最新进展...
  • 如何通过执行SQL为低代码项目提速?
  • linux_文件跟踪查看/实时查看添加到⽂件中的内容/linux日志查看(outline)
  • CDH Kerberos启动后hue报错Couldn‘t renew kerberos ticket
  • 学Spring5源码之入门
  • Maven - 3、详解maven解决依赖问题
  • 1行代码提取6种TCGA表达矩阵和临床信息
  • 直升飞机领衔、三百辆婚车开道,三十台巨型吊车,小伟婚礼超豪华
  • 【2023秋招面经】OPPO 前端 一面(40min)
  • Nifi05 Nifi单节点、集群部署以及迁移
  • SQL server发布订阅事务复制新增表的解决方案(不重新初始化)
  • Tableau2——折线图,饼图
  • 对话腾讯天琴赵伟峰:当音乐与科技结合,会碰撞出怎样的火花?
  • codePen前端编码神器
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 〔开发系列〕一次关于小程序开发的深度总结
  • EOS是什么
  • Java新版本的开发已正式进入轨道,版本号18.3
  • JDK 6和JDK 7中的substring()方法
  • js递归,无限分级树形折叠菜单
  • pdf文件如何在线转换为jpg图片
  • Redis字符串类型内部编码剖析
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • SQLServer之创建数据库快照
  • TypeScript实现数据结构(一)栈,队列,链表
  • webgl (原生)基础入门指南【一】
  • windows下使用nginx调试简介
  • 当SetTimeout遇到了字符串
  • 对超线程几个不同角度的解释
  • 给新手的新浪微博 SDK 集成教程【一】
  • 简单数学运算程序(不定期更新)
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 使用docker-compose进行多节点部署
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 字符串匹配基础上
  • 做一名精致的JavaScripter 01:JavaScript简介
  • zabbix3.2监控linux磁盘IO
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​决定德拉瓦州地区版图的关键历史事件
  • # Java NIO(一)FileChannel
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #{}和${}的区别是什么 -- java面试
  • #14vue3生成表单并跳转到外部地址的方式
  • (2)STL算法之元素计数
  • (day6) 319. 灯泡开关
  • (LeetCode C++)盛最多水的容器
  • (libusb) usb口自动刷新
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)计算机毕业设计大学生兼职系统
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF