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

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

文章目录

    • 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.Driverurl: 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 # 是否打印慢sqlwall: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转换为SubjectCategorySubjectCategory 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 {@Resourceprivate SubjectCategoryService subjectCategoryService;@Overridepublic 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 {@Resourceprivate 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

相关文章:

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

文章目录 1.技术选型2.原型设计1.安装AxureRP2.进行汉化3.载入元件库4.基本设计 3.元数建模1.安装元数建模软件2.新建项目3.新增一个刷题模块主题域4.新增数据表 subject_category5.新增关系图&#xff0c;将表拖过来6.新增题目标签表7.新增题目信息表8.新增单选表、多选表、判…...

【论文阅读】-- Omnisketch:高效的多维任意谓词高速流分析

Omnisketch&#xff1a;高效的多维任意谓词高速流分析 摘要1 引言2 预备知识及相关工作3 OMNISKETCH&#xff1a;使用任意谓词估计频率3.1 Sketch S0&#xff1a;Count-Min with rid-sets 用于估计带有谓词的查询3.2 Sketch S1 &#xff08;OmniSketch&#xff09;&#xff1a;…...

【ajax核心03】封装底层axios函数

目录 一&#xff1a;步骤总结 二&#xff1a;获取数据需求&#xff1a; 三&#xff1a;查找数据需求&#xff1a; 四&#xff1a;发送数据需求&#xff1a; 一&#xff1a;步骤总结 定义myAxios函数&#xff0c;接收配置对象&#xff0c;返回Promise对象发送XHR请求&#…...

python科学计算

文章目录 一、科学计算介绍二、NumPy2.1、NumPy是什么2.2、NumPy使用场景2.3、NumPy特点2.4、NumPy如何使用 三、数组3.1、数组介绍3.2、创建数组3.3、数组的大小3.4、通过索引访问数组3.5、变换数组的形态3.6、常用的ufunc运算 一、科学计算介绍 python语言提供了array模块&am…...

Leetcode - 132双周赛

目录 一、3174. 清除数字 二、3175. 找到连续赢 K 场比赛的第一位玩家 三、3176. 求出最长好子序列 I 四、3177. 求出最长好子序列 II 一、3174. 清除数字 本题可以使用栈来模拟&#xff0c;遇到数字弹出栈顶元素&#xff0c;遇到字母入栈。 代码如下&#xff1a; //使用字…...

Mongodb在UPDATE操作中使用$push向数组中插入数据

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第69篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…...

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 锐化效果

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 锐化效果 核心代码完整代码在线示例ArcGIS Maps SDK for JavaScript 从 4.29 开始增加 RenderNode 类,可以添加数据以及操作 FBO(ManagedFBO); 通过操作 FBO,可以通过后处理实现很多效果,官方提供了几个示例,…...

信息系统项目管理师 | 信息系统安全技术

关注WX&#xff1a;CodingTechWork 信息安全概念 安全属性 秘密性&#xff1a;信息不被未授权者知晓。完整性&#xff1a;信息是正确的、真实的、未被篡改的、完整无缺。可用性&#xff1a;信息可以随时正常使用。 安全分层 设备安全 设备的稳定性&#xff1a;在一定时间…...

Java数据类型与运算符

1. 变量和类型 变量指的是程序运行时可变的量&#xff0c;相当于开辟一块空间来保存一些数据。 类型则是对变量的种类进行了划分&#xff0c;不同类型的变量具有不同的特性。 1.1 整型变量&#xff08;重点&#xff09; 基本语法格式&#xff1a; int 变量名 初始值;代码示…...

网络虚拟化考题

vrrp讲过吗&#xff1f;&#xff1f;&#xff1f; d 每一层都是什么设备啊 abcd 为啥流量不可控不可视 c是啥意思 讲过吗 abc aNET网络虚拟化是啥啊 为啥&#xff1f;&#xff1f; 啥是CDN&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;...

《C++ Primer》导学系列:第 7 章 - 类

7.1 定义抽象数据类型 7.1.1 类的基本概念 在C中&#xff0c;类是用户定义的类型&#xff0c;提供了一种将数据和操作这些数据的函数&#xff08;成员函数&#xff09;组合在一起的方法。类定义了对象的属性和行为&#xff0c;通过实例化类来创建对象。 7.1.2 定义类 定义类…...

idea intellij 2023打开微服务项目部分module未在左侧项目目录展示(如何重新自动加载所有maven项目model)

项目场景&#xff1a; springcloud微服务项目,部分模块暂时不需要用到&#xff0c;就在pom.xml文件中注释掉相应的模块&#xff0c;突然有一天打开项目&#xff0c;部分项目module 在idea intellij工具左侧文件夹找不到了&#xff0c;重新file->open本地项目也还是部分模块…...

生成视频 zeroscope_v2_576w 学习笔记

目录 生成视频代码&#xff1a; 维度报错&#xff1a; 解决方法&#xff0c;修改代码&#xff1a; 已开源&#xff1a; 视频生成模型 Zeroscope开源 免费无水印 视频生成模型 Zeroscope_v2_576w 开源 - 腾讯云开发者社区-腾讯云 生成视频代码&#xff1a; import torch fro…...

H3C综合实验

实验拓扑 实验要求 1、按照图示配置IP地址 2、sw1和sw2之间的直连链路配置链路聚合 3、 公司内部业务网段为VLAN10和VLAN20; VLAN 10是市场部&#xff0c;vlan20是技术部&#xff0c;要求对VLAN进行命名以便识别&#xff1b;PC1属于vlan10&#xff0c;PC2属于vlan20&#xf…...

QThread 与QObject::moveToThread在UI中的应用

1. QThread的两种用法 第一种用法就是继承QThread&#xff0c;然后覆写 virtual void run()&#xff0c; 这种用法的缺点是不能利用信号槽机制。 第二种用法就是创建一个线程&#xff0c;创建一个对象&#xff0c;再将对象moveToThread, 这种可以充分利用信号槽机制&#xff…...

安卓逆向案例——X酷APP逆向分析

X酷APP逆向分析 这里介绍一下两种不同的挂载证书的方法。 chls.pro/ssl无法在浏览器中下载证书是什么原因解决方法&#xff1a; 法一 1. 挂载系统分区为读写 使用正确的挂载点来挂载系统分区为读写&#xff1a; su mount -o remount,rw /dev/uijISjR/.magisk/block/syste…...

创新案例|星巴克中国市场创新之路: 2025目标9000家店的挑战与策略

星巴克创始人霍华德舒尔茨&#xff1a;“为迎接中国市场的全面消费复苏&#xff0c;星巴克2025年推进9000家门店计划&#xff0c;将外卖、电商以及家享和外出场景咖啡业务纳入中国新一轮增长计划中。”在面临中国市场同店增长大幅下滑29%背景下&#xff0c;星巴克通过DTC用户体…...

计算机网络 MAC地址表管理

一、理论知识 1.MAC地址表&#xff1a;交换机使用MAC地址表来记录各MAC地址对应的端口&#xff0c;用于帧转发的目的。 2.老化机制&#xff1a;交换机会为每一条MAC地址表项设置老化时间&#xff0c;老化时间到期后未收到该MAC地址报文的表项将被删除&#xff0c;释放资源。 …...

【免费API推荐】:各类API资源免费获取【11】

欢迎来到各类API资源的免费获取世界&#xff01;幂简集成为您提供了一个集合了各种免费API接口的平台。无论您是开发者、数据分析师还是创业者&#xff0c;都可以通过我们的平台轻松免费获取所需的API资源。幂简精心整理了各类API接口&#xff0c;涵盖了不同领域的需求&#xf…...

技术驱动会展:展位导航系统的架构与实现

随着会展行业的快速发展&#xff0c;大型会展中心面临着如何提升参展者体验、提高招商效率的挑战。针对客户反馈的展馆面积大、展位查找困难等问题&#xff0c;维小帮提出一套智慧会展导航解决方案&#xff0c;旨在通过先进的室内导航技术提升会展中心的运营效率和参展者的满意…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...