社区项目-项目介绍环境搭建

news2025/1/20 6:00:20

文章目录

    • 1.技术选型
    • 2.原型设计
        • 1.安装AxureRP
        • 2.进行汉化
        • 3.载入元件库
        • 4.基本设计
    • 3.元数建模
        • 1.安装元数建模软件
        • 2.新建项目
        • 3.新增一个刷题模块主题域
        • 4.新增数据表 subject_category
        • 5.新增关系图,将表拖过来
        • 6.新增题目标签表
        • 7.新增题目信息表
        • 8.新增单选表、多选表、判断题、简答题
        • 9.新增分类、标签、题目关联表
        • 10.关系图预览
    • 4.项目架构分析
        • 1.现有的架构
        • 2.ddd架构
    • 5.mysql采用docker版的主从复制(之前配置过)
        • 1.docker的启动命令
        • 2.IDEA测试连接
        • 3.主MySQL的连接信息
        • 4.创建数据库sun_club,然后创建表
    • 6.集成Gitee
        • 1.新建仓库
        • 2.克隆到IDEA
    • 7.新建一个sun-club-subject作为父模块
        • 1.新建父模块
        • 2.删除src目录
        • 3.设置整个项目的编码为utf-8
        • 4.在maven的配置部分指定编译版本为java8
        • 5.在maven的插件配置中指定maven打包的配置
    • 8.新建子模块
        • 1.新建api子模块
        • 2.为子模块的parent部分加上relativePath标签(不要加,只有在需要双继承的时候才需要)
        • 3.在maven的配置部分指定编译版本为java8以及maven的打包插件(每个子模块都要加的)
        • 2.新建application子模块
        • 3.跟上面两个一样的常规配置
        • 4.分别新建common、domain、infra、starter模块并进行常规配置
        • 5.各层次目录结构
          • 1.api层
          • 2.starter层
          • 3.infra层
          • 4.domain层![image-20240523154525211](https://img-blog.csdnimg.cn/img_convert/3f12fa1b06453bc80ee1dd82ada22d9b.png)
          • 5.common层
          • 6.application层
            • 新建三个子模块并加上常规配置
          • 7.整体结构一览
        • 6.目录结构调整
          • 1.sun-club-subject-api
          • 2.sun-club-starter
          • 3.sun-club-infra
          • 4.sun-club-domain
          • 5.sun-club-common
          • 6.sun-club-application
    • 9.集成SpringBoot
        • 1.编辑sun-club-subject的pom.xml引入SpringBoot2并配置maven仓库
        • 2.编辑sun-club-starter的pom.xml引入SpringBoot的starter-web
        • 3.sun-club-starter模块编写启动类SubjectApplication.java
        • 4.启动测试
        • 5.sun-club-starter模块创建application.yml对项目进行调整
          • 1.文件内容
          • 2.重启测试
    • 10.集成SpringMVC
        • 1.sun-club-application-controller 引入SpringBoot的starter-web
        • 2.编写SubjectController.java
        • 3.sun-club-starter引入sun-club-application-controller模块,使其启动时可以找到
        • 4.测试访问
    • 11.集成MySQL,Druid,MyBatis
        • 1.sun-club-infra模块添加依赖
        • 2.EasyCode插件,生成CRUD
          • 1.安装插件
          • 2.选择表,右键选择EasyCode
          • 3.选择代码生成的位置,和需要的文件
          • 4.查看生成的代码
          • 5.删除与Pageable有关的代码
            • 1.SubjectCategoryDao.java
            • 2.SubjectCategoryService.java
            • 3.SubjectCategoryServiceImpl.java
        • 3.sun-club-starter引入sun-club-infra
        • 4.sun-club-starter启动类配置MapperScan,扫描基础设施层的包
        • 5.sun-club-starter配置数据源和监控
        • 6.测试
          • 1.sun-club-application-controller 引入sun-club-infra
          • 2.sun-club-application-controller编写SubjectController.java测试
          • 3.启动测试,成功!
        • 7.使用druid对application.yml中的密码进行加密
          • 1.sun-club-infra编写DruidEncryptUtil.java进行加解密
          • 2.sun-club-starter修改application.yml
        • 8.准备apipost测试工具
          • 1.新建目录
          • 2.刷题模块目录
          • 3.再添加一个题目分类的目录
          • 4.添加一个接口
    • 12.分层架构的业务开发演示
        • 1.引入依赖
          • 1.sun-club-common引入lombok和mapstruct,注意lombok必须放到mapstruct前面
          • 2.sun-club-infra引入sun-club-common
        • 2.sun-club-domain层
          • 1.引入sun-club-infra的依赖
          • 2.创建SubjectCategoryBO.java(只关注业务)
          • 3.service层
            • 1.SubjectCategoryDomainService.java
            • 2.由于需要将BO转换为eneity,所以需要转换器SubjectCategoryConverter.java
            • 3.SubjectCategoryDomainServiceImpl.java
        • 3.sun-club-application-controller层
          • 1.引入sun-club-domain的依赖
          • 2.转换器将DTO转换为BO SubjectCategoryDTOConverter.java
          • 3.sun-club-common包中封装统一响应
            • 1.ResultCodeEnum.java
            • 2.Result.java
          • 4.SubjectCategoryController.java
          • 5.测试
        • 4.打印日志
          • 1.sun-club-common引入log4j2和fastjson
          • 2.SubjectCategoryController.java打印日志
          • 3.SubjectCategoryDomainServiceImpl.java
          • 4.SubjectCategoryServiceImpl.java
          • 5.sun-club-starter 引入log4j2-spring.xml
          • 6.sun-club-starter的application.yml配置日志
          • 7.启动会报错
            • 1.报错信息
            • 2.使用Maven Helper查看依赖
            • 3.排除掉springboot-starter-web的log
            • 4.再次测试
        • 5.参数校验
          • 1.使用guava
            • 1.sun-club-common引入依赖
            • 2.sun-club-application-controller引入公共包
            • 3.Preconditions.checkNotNull没有生效,说明guava依赖有问题,clean一下maven,发现报错
            • 4.把所有relativePath全删除,因为并没有双继承,用不上,再次clean,成功!
            • 5.sun-club-application-controller编写SubjectCategoryController.java
            • 6.端口换成3010
          • 2.测试

1.技术选型

image-20240523103709944

2.原型设计

1.安装AxureRP

image-20240523105343084

2.进行汉化

image-20240523105703905

3.载入元件库

image-20240523105759647

image-20240523105923775

4.基本设计

image-20240523110733594

3.元数建模

1.安装元数建模软件

image-20240523111228529

2.新建项目

image-20240523111627437

3.新增一个刷题模块主题域

image-20240523111754467

4.新增数据表 subject_category

image-20240523111946145

image-20240523112335889

5.新增关系图,将表拖过来

image-20240523112425927

image-20240523112456605

6.新增题目标签表

image-20240523112643132

image-20240523113215837

7.新增题目信息表

image-20240523113428035

image-20240523114411374

8.新增单选表、多选表、判断题、简答题

image-20240523115006075

image-20240523115408987

image-20240523115650835

image-20240523120015541

9.新增分类、标签、题目关联表
10.关系图预览

image-20240523131742982

4.项目架构分析

1.现有的架构

image-20240523132552332

2.ddd架构

image-20240523132620853

5.mysql采用docker版的主从复制(之前配置过)

1.docker的启动命令
docker run -p 3307:3306 --name mysql-master \
-v /mysql5.7/mysql-master/log:/var/log/mysql \
-v /mysql5.7/mysql-master/data:/var/lib/mysql \
-v /mysql5.7/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=******** \
-d mysql:5.7
2.IDEA测试连接
3.主MySQL的连接信息
4.创建数据库sun_club,然后创建表

6.集成Gitee

1.新建仓库

image-20240523145508623

2.克隆到IDEA

image-20240523145552481

7.新建一个sun-club-subject作为父模块

1.新建父模块

image-20240523150655253

2.删除src目录

image-20240523150851198

3.设置整个项目的编码为utf-8

4.在maven的配置部分指定编译版本为java8
    <!-- maven的配置 -->
    <!-- 解决java: -source 1.5 中不支持 diamond 运算符 问题 -->
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
5.在maven的插件配置中指定maven打包的配置
    <!-- maven打包常规配置 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

image-20240523152517520

8.新建子模块

1.新建api子模块

image-20240523151042356

2.为子模块的parent部分加上relativePath标签(不要加,只有在需要双继承的时候才需要)

image-20240523151631395

3.在maven的配置部分指定编译版本为java8以及maven的打包插件(每个子模块都要加的)
  <!-- maven的配置 -->
  <!-- 解决java: -source 1.5 中不支持 diamond 运算符 问题 -->
  <properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <!-- maven打包常规配置 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

image-20240523152618538

2.新建application子模块

3.跟上面两个一样的常规配置

image-20240523152926046

4.分别新建common、domain、infra、starter模块并进行常规配置

image-20240523153517433

image-20240523153529088

5.各层次目录结构
1.api层

image-20240523154009996

2.starter层

image-20240523154114961

3.infra层

image-20240523154337689

4.domain层image-20240523154525211
5.common层

image-20240523154631912

6.application层
新建三个子模块并加上常规配置

image-20240523155100663

image-20240523155416269

7.整体结构一览

image-20240523155532124

6.目录结构调整
1.sun-club-subject-api

image-20240523160121211

2.sun-club-starter

image-20240523160137202

3.sun-club-infra

image-20240523160342709

4.sun-club-domain

image-20240523160504939

5.sun-club-common

image-20240523160820466

6.sun-club-application

image-20240523161236957

9.集成SpringBoot

1.编辑sun-club-subject的pom.xml引入SpringBoot2并配置maven仓库
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.4.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>central</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <layout>default</layout>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

image-20240523162246282

2.编辑sun-club-starter的pom.xml引入SpringBoot的starter-web
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.4.2</version>
        </dependency>
    </dependencies>

image-20240523163020302

3.sun-club-starter模块编写启动类SubjectApplication.java
package com.sunxiansheng.subject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

/**
 * Description: 刷题微服务启动类
 * @Author sun
 * @Create 2024/5/23 16:30
 * @Version 1.0
 */
@SpringBootApplication
@ComponentScan("com.sunxiansheng") // 扫描当前模块下的所有包
public class SubjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(SubjectApplication.class, args);
    }
}

image-20240523163512007

4.启动测试

image-20240523163533835

5.sun-club-starter模块创建application.yml对项目进行调整
1.文件内容

2.重启测试

image-20240523163739595

10.集成SpringMVC

1.sun-club-application-controller 引入SpringBoot的starter-web
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.4.2</version>
        </dependency>
    </dependencies>

image-20240523164014670

2.编写SubjectController.java
package com.sunxiansheng.subject.application.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description: 刷题微服务控制器
 * @Author sun
 * @Create 2024/5/23 16:42
 * @Version 1.0
 */
@RestController
public class SubjectController {

    @GetMapping("/test")
    public String test() {
        return "Hello, World!";
    }
}

image-20240523165332899

3.sun-club-starter引入sun-club-application-controller模块,使其启动时可以找到
        <!-- 引入sun-club-application-controller的依赖,则启动这个模块,就能找到 -->
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-application-controller</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240523165449763

4.测试访问

image-20240523165506077

11.集成MySQL,Druid,MyBatis

1.sun-club-infra模块添加依赖
    <dependencies>
        <!-- jdbcStarter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.4.2</version>
        </dependency>
        <!-- druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <!-- mybatisplus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
    </dependencies>

image-20240523170254690

2.EasyCode插件,生成CRUD
1.安装插件

image-20240523185842998

2.选择表,右键选择EasyCode

image-20240523190445627

3.选择代码生成的位置,和需要的文件

image-20240523190627854

4.查看生成的代码

image-20240523192932850

5.删除与Pageable有关的代码
1.SubjectCategoryDao.java

image-20240523191827530

2.SubjectCategoryService.java

image-20240523191858191

3.SubjectCategoryServiceImpl.java

image-20240523191929408

3.sun-club-starter引入sun-club-infra
        <!-- 引入sun-club-infra -->
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-infra</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240523192617622

4.sun-club-starter启动类配置MapperScan,扫描基础设施层的包

image-20240523193811911

5.sun-club-starter配置数据源和监控
  • 这里没有配置扫描Mapper.xml的原因是:Mapper和Mapper.xml的名字相同并且位于常规位置,MyBatis会自动扫描
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: 
    username: 
    password: 
    type: com.alibaba.druid.pool.DruidDataSource # druid连接池
    druid:
      initial-size: 20 # 初始化连接数
      min-idle: 20 # 最小连接数
      max-active: 100 # 最大连接数
      max-wait: 60000 # 最大等待时间,单位毫秒
      stat-view-servlet:
        enabled: true # 是否开启监控
        url-pattern: /druid/* # 监控路径
        login-username: # 登录用户名
        login-password: # 登录密码
      filter:
        stat:
          enabled: true # 是否开启慢sql监控
          slow-sql-millis: 2000 # 慢sql阈值,单位毫秒
          log-slow-sql: true # 是否打印慢sql
        wall:
          enabled: true # 是否开启防火墙

6.测试
1.sun-club-application-controller 引入sun-club-infra
        <!-- 引入sun-club-infra -->
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-infra</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240523195248619

2.sun-club-application-controller编写SubjectController.java测试

image-20240523195659126

3.启动测试,成功!

image-20240523200243396

7.使用druid对application.yml中的密码进行加密
1.sun-club-infra编写DruidEncryptUtil.java进行加解密
package com.sunxiansheng.subject.infra.basic.utils;

import com.alibaba.druid.filter.config.ConfigTools;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/**
 * Description: 使用druid对配置文件中的密码进行加密
 * @Author sun
 * @Create 2024/5/23 20:22
 * @Version 1.0
 */
public class DruidEncryptUtil {

    private static String publicKey;

    private static String privateKey;

    static {
        try {
            String[] keyPair = ConfigTools.genKeyPair(512);
            privateKey = keyPair[0];
            System.out.println("privateKey:" + privateKey);
            publicKey = keyPair[1];
            System.out.println("publicKey:" + publicKey);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
    }

    public static String encrypt(String plainText) throws Exception {
        String encrypt = ConfigTools.encrypt(privateKey, plainText);
        System.out.println("encrypt:" + encrypt);
        return encrypt;
    }

    public static String decrypt(String encryptText) throws Exception {
        String decrypt = ConfigTools.decrypt(publicKey, encryptText);
        System.out.println("decrypt:" + decrypt);
        return decrypt;
    }

    public static void main(String[] args) throws Exception {
        String encrypt = encrypt("");
        System.out.println("encrypt:" + encrypt);
    }

}


2.sun-club-starter修改application.yml
8.准备apipost测试工具
1.新建目录

image-20240523210503359

2.刷题模块目录

image-20240523210528522

3.再添加一个题目分类的目录

image-20240523210638230

4.添加一个接口

image-20240523212045274

12.分层架构的业务开发演示

1.引入依赖
1.sun-club-common引入lombok和mapstruct,注意lombok必须放到mapstruct前面
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.4.2.Final</version>
        </dependency>

image-20240524085305340

2.sun-club-infra引入sun-club-common
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240524085626235

2.sun-club-domain层
1.引入sun-club-infra的依赖
        <!-- 引入sun-club-infra -->
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-infra</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240524090625626

2.创建SubjectCategoryBO.java(只关注业务)
package com.sunxiansheng.subject.domain.entity;

import lombok.Data;

/**
 * Description:
 * @Author sun
 * @Create 2024/5/24 9:09
 * @Version 1.0
 */
@Data
public class SubjectCategoryBO {
    private static final long serialVersionUID = -66163713173399755L;
    /**
     * 主键
     */
    private Long id;
    /**
     * 分类名称
     */
    private String categoryName;
    /**
     * 分类类型
     */
    private Integer categoryType;
    /**
     * 图标连接
     */
    private String imageUrl;
    /**
     * 父级id
     */
    private Long parentId;

}

image-20240524091100109

3.service层
1.SubjectCategoryDomainService.java
package com.sunxiansheng.subject.domain.service;

import com.sunxiansheng.subject.domain.entity.SubjectCategoryBO;

/**
 * Description:
 * @Author sun
 * @Create 2024/5/24 9:03
 * @Version 1.0
 */
public interface SubjectCategoryDomainService {
    void add(SubjectCategoryBO subjectCategoryBO);
}

2.由于需要将BO转换为eneity,所以需要转换器SubjectCategoryConverter.java
package com.sunxiansheng.subject.domain.convert;

import com.sunxiansheng.subject.domain.entity.SubjectCategoryBO;
import com.sunxiansheng.subject.infra.basic.entity.SubjectCategory;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

/**
 * Description:
 * @Author sun
 * @Create 2024/5/24 9:18
 * @Version 1.0
 */
@Mapper // mapstruct的注解
public interface SubjectCategoryConverter {
    // INSTANCE是一个SubjectCategoryConverter的静态实例,可以直接通过SubjectCategoryConverter.INSTANCE调用内部的方法
    SubjectCategoryConverter INSTANCE= Mappers.getMapper(SubjectCategoryConverter.class);
    // 将SubjectCategoryBO转换为SubjectCategory
    SubjectCategory convertBoToSubjectCategory(SubjectCategoryBO subjectCategoryBO);
}

image-20240524092625918

3.SubjectCategoryDomainServiceImpl.java
package com.sunxiansheng.subject.domain.service.impl;

import com.sunxiansheng.subject.domain.convert.SubjectCategoryConverter;
import com.sunxiansheng.subject.domain.entity.SubjectCategoryBO;
import com.sunxiansheng.subject.domain.service.SubjectCategoryDomainService;
import com.sunxiansheng.subject.infra.basic.entity.SubjectCategory;
import com.sunxiansheng.subject.infra.basic.service.SubjectCategoryService;

import javax.annotation.Resource;

/**
 * Description:
 * @Author sun
 * @Create 2024/5/24 9:03
 * @Version 1.0
 */
@Service
public class SubjectCategoryDomainServiceImpl implements SubjectCategoryDomainService {
    @Resource
    private SubjectCategoryService subjectCategoryService;

    @Override
    public void add(SubjectCategoryBO subjectCategoryBO) {
        SubjectCategory subjectCategory = SubjectCategoryConverter.INSTANCE.convertBoToSubjectCategory(subjectCategoryBO);
        subjectCategoryService.insert(subjectCategory);
    }
}

3.sun-club-application-controller层
1.引入sun-club-domain的依赖
        <!-- 引入sun-club-domain -->
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-domain</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240524093157459

2.转换器将DTO转换为BO SubjectCategoryDTOConverter.java
package com.sunxiansheng.subject.application.convert;

import com.sunxiansheng.subject.application.dto.SubjectCategoryDTO;
import com.sunxiansheng.subject.domain.entity.SubjectCategoryBO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

/**
 * Description:
 * @Author sun
 * @Create 2024/5/24 9:40
 * @Version 1.0
 */
@Mapper
public interface SubjectCategoryDTOConverter {
    SubjectCategoryDTOConverter INSTANCE= Mappers.getMapper(SubjectCategoryDTOConverter.class);

    SubjectCategoryBO convertDTOToSubjectCategory(SubjectCategoryDTO subjectCategoryDTO);
}

image-20240524094752234

3.sun-club-common包中封装统一响应
1.ResultCodeEnum.java
package com.sunxiansheng.subject.common.enums;

import lombok.Getter;

/**
 * Description: 返回结果枚举
 * @Author sun
 * @Create 2024/5/24 9:53
 * @Version 1.0
 */
@Getter
public enum ResultCodeEnum {
    SUCCESS(200, "成功"),
    FAIL(500, "失败");

    public int code;
    public String desc;

    ResultCodeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    /**
     * 根据code获取枚举
     * @param code
     * @return
     */
    public static ResultCodeEnum getByCode(int code) {
        for (ResultCodeEnum value : values()) {
            if (value.code == code) {
                return value;
            }
        }
        return null;
    }
}

2.Result.java
package com.sunxiansheng.subject.common.eneity;

import com.sunxiansheng.subject.common.enums.ResultCodeEnum;
import lombok.Data;

/**
 * Description:
 * @Author sun
 * @Create 2024/5/24 9:48
 * @Version 1.0
 */
@Data
public class Result<T> {

    private Boolean success;

    private Integer code;

    private String message;

    private T data;

    /**
     * 成功返回结果
     * @return
     */
    public static Result ok() {
        Result result = new Result();
        result.setSuccess(true);
        result.setCode(ResultCodeEnum.SUCCESS.getCode());
        result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
        return result;
    }

    /**
     * 成功返回结果,携带数据
     * @param data
     * @return
     * @param <T>
     */
    public static <T> Result ok(T data) {
        Result result = new Result();
        result.setSuccess(true);
        result.setCode(ResultCodeEnum.SUCCESS.getCode());
        result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
        result.setData(data);
        return result;
    }

    /**
     * 失败返回结果
     * @return
     */
    public static Result fail() {
        Result result = new Result();
        result.setSuccess(false);
        result.setCode(ResultCodeEnum.FAIL.getCode());
        result.setMessage(ResultCodeEnum.FAIL.getDesc());
        return result;
    }

    /**
     * 失败,携带数据
     * @param data
     * @return
     * @param <T>
     */
    public static <T> Result fail(T data) {
        Result result = new Result();
        result.setSuccess(false);
        result.setCode(ResultCodeEnum.FAIL.getCode());
        result.setMessage(ResultCodeEnum.FAIL.getDesc());
        result.setData(data);
        return result;
    }

}

4.SubjectCategoryController.java
package com.sunxiansheng.subject.application.controller;

import com.alibaba.fastjson.JSON;
import com.sunxiansheng.subject.application.convert.SubjectCategoryDTOConverter;
import com.sunxiansheng.subject.application.dto.SubjectCategoryDTO;
import com.sunxiansheng.subject.common.eneity.Result;
import com.sunxiansheng.subject.domain.entity.SubjectCategoryBO;
import com.sunxiansheng.subject.domain.service.SubjectCategoryDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * Description: 题目分类控制器
 * @Author sun
 * @Create 2024/5/24 9:33
 * @Version 1.0
 */
@RestController
@RequestMapping("/subject/category")
public class SubjectCategoryController {
    @Resource
    private SubjectCategoryDomainService subjectCategoryDomainService;

    @PostMapping("/add")
    public Result<Boolean> add(@RequestBody SubjectCategoryDTO subjectCategoryDTO) {
        try {
            SubjectCategoryBO subjectCategoryBO = SubjectCategoryDTOConverter.INSTANCE.convertDTOToSubjectCategory(subjectCategoryDTO);
            subjectCategoryDomainService.add(subjectCategoryBO);
            return Result.ok(true);
        } catch (Exception e) {
            return Result.fail();
        }
    }
}

image-20240524105641724

5.测试

image-20240524101631593

4.打印日志
1.sun-club-common引入log4j2和fastjson
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>2.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.24</version>
        </dependency>

image-20240524102109158

2.SubjectCategoryController.java打印日志
  • 这里判断是否开启日志的原因是:如果不判断,则即使没开启日志,JSON还是会序列化,影响性能
            if (log.isInfoEnabled()) {
                log.info("SubjectCategoryController add SubjectCategoryDTO, subjectCategoryDTO:{}", JSON.toJSONString(subjectCategoryDTO));
            }

image-20240524102957593

3.SubjectCategoryDomainServiceImpl.java

image-20240524103208321

4.SubjectCategoryServiceImpl.java

image-20240524103344499

5.sun-club-starter 引入log4j2-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="INFO" monitorInterval="5">
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!--变量配置-->
    <Properties>
        <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
        <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
        <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} %X{PFTID} [%thread] %-5level %logger{36} - %msg%n" />
        <!-- 定义日志存储的路径 -->
        <property name="FILE_PATH" value="../log" />
        <property name="FILE_NAME" value="jcClub.log" />
    </Properties>

    <!--https://logging.apache.org/log4j/2.x/manual/appenders.html-->
    <appenders>

        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>

        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <File name="fileLog" fileName="${FILE_PATH}/temp.log" append="false">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <appender-ref ref="fileLog"/>
        </root>
    </loggers>

</configuration>
6.sun-club-starter的application.yml配置日志

image-20240524103748300

7.启动会报错
1.报错信息

image-20240524103854701

2.使用Maven Helper查看依赖

image-20240524104809749

3.排除掉springboot-starter-web的log

image-20240524104842840

4.再次测试

image-20240524105731421

5.参数校验
1.使用guava
1.sun-club-common引入依赖
        <!-- guava进行参数校验 -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>

image-20240524110320126

2.sun-club-application-controller引入公共包
        <!-- 引入sun-club-common -->
        <dependency>
            <groupId>com.sun.club</groupId>
            <artifactId>sun-club-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

image-20240524110819200

3.Preconditions.checkNotNull没有生效,说明guava依赖有问题,clean一下maven,发现报错

image-20240524112009829

4.把所有relativePath全删除,因为并没有双继承,用不上,再次clean,成功!

image-20240524112139199

5.sun-club-application-controller编写SubjectCategoryController.java
// 参数校验
Preconditions.checkNotNull(subjectCategoryDTO.getCategoryType(), "分类类型不能为空");
           Preconditions.checkArgument(!StringUtils.isBlank(subjectCategoryDTO.getCategoryName()), "分类名称不能为空");
Preconditions.checkNotNull(subjectCategoryDTO.getParentId(), "分类父级id不能为空");

image-20240524113226527

6.端口换成3010

image-20240524113342129

2.测试

image-20240524113432866

image-20240524113501078

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1847696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

姿态识别论文复现(一)安装包+下载数据

Lite-HRNet&#xff1a;轻量级高分辨率网络 简介&#xff1a;高分辨率网络Lite-HRNet&#xff0c;用于人体姿态估计 环境配置&#xff1a;该代码是在 Ubuntu 16.04 上使用 python 3.6 开发的。需要 NVIDIA GPU。使用 8 个 NVIDIA V100 GPU 卡进行开发和测试。其他平台或 GPU …

智慧园区解决方案PPT(53页)

## 1.1 智慧园区背景及需求分析 - 智慧园区的发展历程包括园区规划、经济、产业、企业、管理、理念的转变&#xff0c;强调管理模式创新&#xff0c;关注业务综合化、管理智慧化等发展。 ## 1.2 国家对智慧园区发展的政策 - 涉及多个国家部门&#xff0c;如工信部、住建部、…

uniapp公用返回组件

uniapp写一个公用的头部组件&#xff0c;包含home和返回。 页面中的引用 2.在components文件夹下&#xff0c;新建一个navBar.vue <template><view class"view-wrap"><view :style"{ height: barHeight }"></view><view cla…

EtherCAT扫盲,都是知识点

1. 什么是EtherCAT EtherCAT&#xff0c;全称Ethernet for Control Automation Technology&#xff0c;字面意思就是用于控制自动化技术的以太网。它是一种基于以太网的实时工业通信协议&#xff0c;简单说&#xff0c;就是让机器们通过网线互相聊天的高级方式。 EtherCAT 是最…

openEuler 22.03 (LTS-SP1)服务器用ntpd同步GPS时间服务器的案例

本文记录了openEuler 22.03 (LTS-SP1)的二级时间服务器用chronyd不能自动同步GPS时间服务器&#xff0c;改用ntpd同步GPS时间服务器成功的案例 一、环境简述 1、本环境中有两台GPS一级时间服务器&#xff0c;IP如下&#xff1a; 192.168.188.66 192.168.188.74 2、有一台o…

开发中遇到的错误 - @SpringBootTest 注解爆红

我在使用 SpringBootTest 注解的时候爆红了&#xff0c;ait 回车也导不了包&#xff0c;后面发现是因为没有加依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId>…

JAVA小知识28:FIle类文件对象

Java 中的 File 类是 java.io 包中的一个类&#xff0c;用于表示文件和目录路径名的抽象表示。它提供了一些方法来操作文件和目录 一、File的创建 1.1、绝对路径 绝对路径是指从文件系统的根目录开始定位文件或目录的完整路径。它通常以根目录符号开始&#xff0c;在 Window…

​Claude 3.5 最新体验:助力硕博生与科研人员高效完成论文,超越ChatGPT4o !

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 要不说AI领域的进展真的是日新月异&#xff0c;发展速度已经大大超过预期进度。娜姐本来在准备AI降重工具的测评文章&#xff08;最近好多小伙伴需要&#xff09;。 昨天晚上…

多头Attention MultiheadAttention 怎么用?详细解释

import torch import torch.nn as nn# 定义多头注意力层 embed_dim 512 # 输入嵌入维度 num_heads 8 # 注意力头的数量 multihead_attn nn.MultiheadAttention(embed_dim, num_heads)# 创建一些示例数据 batch_size 10 # 批次大小 seq_len 20 # 序列长度 query torch…

rknn转换后精度差异很大,失真算子自纠

下面是添加了详细注释的优化代码&#xff1a; import cv2 import numpy as np import onnx import onnxruntime as rt from onnx import helper, shape_inferencedef get_all_node_names(model):"""获取模型中所有节点的名称。参数:model (onnx.ModelProto): O…

【有手就会】图数据库Demo教程,实现反洗钱场景下银行转账流水数据分析

前言 星环社区版家族于近期发布了单机、30s一键启动的StellarDB图数据库&#xff0c;本篇文章将为用户介绍如何使用开发版StellarDB实现人物关系探索。 友情链接&#xff1a;白话大数据 | 关于图数据库&#xff0c;没有比这篇更通俗易懂的啦 TDH社区版本次发布StellarDB社区…

可信启动Trusted Board Boot

TBB Trusted Board Boot&#xff08;TBB&#xff09;对所有固件镜像&#xff08;包括普通世界的bootloader&#xff09;进行身份验证&#xff0c;以防止恶意固件在平台上运行。TBB使用公钥加密标准 &#xff08;PKCS&#xff09;来建立信任链&#xff08;Chain of Trust&#…

密码CTF(4)——e和phi不互素

参考 RSA中e和phi不互素 AMM算法 AMM算法简要理解 RSA系列解题研究——e与phi不互素 - 先知社区 (aliyun.com) e与phi不互素 --- 四 1 1 1道题详记-CSDN博客 总述 gcd(e,φ(n))比较小时可以考虑iroot直接开根&#xff0c;当直接开根跑不出来时&#xff0c;考虑有限域…

xargs 传参

xargs的默认命令是 echo&#xff0c;空格是默认定界符。这意味着通过管道传递给 xargs的输入将会包含换行和空白&#xff0c;不过通过 xargs 的处理&#xff0c;换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。 xargs -n1 // 一次输出一个参数到一行&#xf…

【Android面试八股文】你能说一说自定义View与ViewGroup的区别

文章目录 Android UI 组件:View 和 ViewGroupViewGroup 的职责View 的职责自定义 View 和 ViewGroup 的区别1. 继承的类不同2. 主要功能不同3. 重写方法不同4. 使用场景不同5. 事件分发方面的区别6. UI 绘制方面的区别Android UI 组件:View 和 ViewGroup 在 Android 开发中,…

Python开发日记--手撸加解密小工具(3)

目录 1.xcb-cuisor0问题解决 2.AES-CBC算法实现 2.1 信号和槽机制 2.2 开始设计算法 3.小结 1.xcb-cuisor0问题解决 继续解决该问题&#xff0c;在Ubuntu下面运行会发生这个错误。 看描述&#xff0c; 这是说要运行Qt xcb平台插件&#xff0c;需要xcb-cursor0或者libxcb-c…

舔狗日记Puls微信小程序源码

源码介绍&#xff1a; 这是一款舔狗日记Puls微信小程序源码&#xff0c;提供每日一舔的功能&#xff0c;让你舔到最后&#xff0c;什么都有&#xff01; 源码通过API获取一些舔狗日记&#xff0c;内置了100多句舔狗日记&#xff0c;让你摆脱上班摸鱼的无聊时光&#xff0c; …

Python火焰锋动力学和浅水表面波浪偏微分方程

&#x1f3af;要点 &#x1f3af;流图可视化正弦余弦矢量场 | &#x1f3af;解空间变化边界条件二维拉普拉斯方程 | &#x1f3af;解圆柱坐标系标量场 | &#x1f3af;解一维泊松方程 | &#x1f3af;解二维扩散方程 | &#x1f3af;解火焰锋的动力学偏微分方程 | &#x1f3a…

【LeetCode刷题】6. Z 字形变换

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 6. Z 字形变换 2. 题目描述 3. 解题方法 假设一串字符串"abcdefghijklmnopqrstuvwx", 会有如下排列&#xff1a; 我们再以下标来看看排列 从下标来看&#xff0c;每个下标是有规律的 每一行的下标之间的差…

一个自定义流程的平台

脚本语言使用的是C#&#xff0c;当用户发布一个新的流程时&#xff0c;会把C#的脚本编译成dll&#xff0c;然后添加到微服务中&#xff0c;因为有了硬编译&#xff0c;所以执行速度是非常快的。逻辑脚本支持调试&#xff0c;可以断点和逐行调试。平台提供了调试工具&#xff0c…