[尚庭公寓]08-项目初始化

新建数据库

创建数据库

 在MySQL中创建一个`lease`数据库,建库语句如下

CREATE DATABASE lease CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

导入数据库脚本

将资料中的`lease.sql`脚本导入`lease`数据库,其中包含了建表语句和少量的原始数据。

新建项目

按照如下目录结构创建一个多模块的Maven工程。

  1. 依赖关系说明:
  • web模块依赖common和model模块
  1. 工程创建步骤:

  1. 在web模块中依赖common和model
<?xml version="1.0" encoding="UTF-8"?>
<project>

    <dependencies>
        <dependency>
            <groupId>com.atguigu</groupId>
            <artifactId>common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.atguigu</groupId>
            <artifactId>model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

SpringBoot配置

pom文件配置

  1. 在**父工程**的pom.xml文件中增加如下内容
<!-- 继承Spring Boot父项目 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.5</version>
</parent>

<!-- 注意:直接替换pom文件中原有的properties -->
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
    <swagger.version>2.9.2</swagger.version>
    <jwt.version>0.11.2</jwt.version>
    <easycaptcha.version>1.6.2</easycaptcha.version>
    <minio.version>8.2.0</minio.version>
    <knife4j.version>4.1.0</knife4j.version>
    <aliyun.sms.version>2.0.23</aliyun.sms.version>
</properties>

<!--配置dependencyManagement统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--mybatis-plus-->
        <!--官方文档:https://baomidou.com/pages/bab2db/ -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!--knife4j文档-->
        <!--官方文档:https://doc.xiaominfo.com/docs/quick-start -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>${knife4j.version}</version>
        </dependency>

        <!--JWT登录认证相关-->
        <!--官方文档:https://github.com/jwtk/jjwt#install-jdk-maven -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>${jwt.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <scope>runtime</scope>
            <version>${jwt.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <scope>runtime</scope>
            <version>${jwt.version}</version>
        </dependency>

        <!--图形验证码-->
        <!--官方文档:https://gitee.com/ele-admin/EasyCaptcha -->
        <dependency>
            <groupId>com.github.whvcse</groupId>
            <artifactId>easy-captcha</artifactId>
            <version>${easycaptcha.version}</version>
        </dependency>

        <!--对象存储,用于存储图像等非结构化数据-->
        <!--官方文档:https://min.io/docs/minio/linux/developers/minio-drivers.html?ref=docs#java-sdk -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>${minio.version}</version>
        </dependency>

        <!--阿里云短信客户端,用于发送短信验证码-->
        <!--官方文档:https://help.aliyun.com/document_detail/215759.html?spm=a2c4g.215759.0.0.49f32807f4Yc0y -->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>dysmsapi20170525</artifactId>
            <version>${aliyun.sms.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>
  1. 在**web模块**的pom.xml文件中增加如下内容
<!--包含spring web相关依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--包含spring test相关依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<!-- Spring Boot Maven插件,用于打包可执行的JAR文件 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

创建application.yml文件

  1. 在**web-admin模块**的`src/main/resources`目录下创建`application.yml`配置文件,内容如下:
server:
  port: 8080

创建SpringBoot启动类

  1. 在**web-admin模块**下创建`com.atguigu.lease.AdminWebApplication`类,内容如下:
@SpringBootApplication
public class AdminWebApplication {
    public static void main(String[] args) {
        SpringApplication.run(AdminWebApplication.class, args);
    }
}

Mybatis-Plus配置

Mybatis-Plus为公用工具,故将其配置于**common模块**。具体配置可参考其[官方文档](https://baomidou.com/pages/bab2db/#release)。

  1. 在**common模块**的pom.xml文件中增加如下内容:
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!--mysql驱动-->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>
  1. 在**model模块**的pom.xml文件中增加如下内容:

因为**model模块**下的实体类中需要配置Mybatis-Plus相关注解,故也需引入Mybatis-Plus依赖

<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
  1. 在**web-admin模块**的`application.yml`文件增加如下内容:
server:
  port: 8080
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:mysql://192.168.101.101:3306/lease?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2b8
    username: root
    password: Atguigu.123
    hikari:
      connection-test-query: SELECT 1 # 自动检测连接
      connection-timeout: 60000 #数据库连接超时时间,默认30秒
      idle-timeout: 500000 #空闲连接存活最大时间,默认600000(10分钟)
      max-lifetime: 540000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
      maximum-pool-size: 12 #连接池最大连接数,默认是10
      minimum-idle: 10 #最小空闲连接数量
      pool-name: SPHHikariPool # 连接池名称

#用于打印框架生成的sql语句,便于调试
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

*注意**:需根据实际情况修改`hostname`、`port`、`database`、`username`、`password`。

  1. 在**common模块**下创建`com.atguigu.lease.common.mybatisplus.MybatisPlusConfiguration`类,内容如下:
@Configuration
@MapperScan("com.atguigu.lease.web.*.mapper")
public class MybatisPlusConfiguration {
  
}

**注意**:`@MapperScan()`的包路径需要根据实际情况进行修改。

Knife4j配置

在**web模块**的pom.xml文件添加如下内容

因为**web-app**模块同样需要Knife4j依赖,故在两个的父工程引入依赖即可

 <!-- Knife4j -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>

在**model模块**的pom.xml文件添加上述内容

因为**model模块**下的实体类需要配置Knife4j相关注解,故也需引入Knife4j依赖

<!-- Knife4j -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>

后台管理系统和移动端的接口配置并不相同,所以需各自编写一个配置类。在**web-admin模块**下创建`com.atguigu.lease.web.admin.custom.config.Knife4jConfiguration`类,内容如下:

@Configuration
public class Knife4jConfiguration {

    @Bean
    public OpenAPI customOpenAPI() {

        return new OpenAPI().info(
                new Info()
                        .title("后台管理系统API")
                        .version("1.0")
                        .description("后台管理系统API"));
    }
    
    @Bean
    public GroupedOpenApi systemAPI() {

        return GroupedOpenApi.builder().group("系统信息管理").
                pathsToMatch(
                        "/admin/system/**"
                ).
                build();
    }

    @Bean
    public GroupedOpenApi loginAPI() {

        return GroupedOpenApi.builder().group("后台登录管理").
                pathsToMatch(
                        "/admin/login/**",
                        "/admin/info"
                ).
                build();
    }
    
    @Bean
    public GroupedOpenApi apartmentAPI() {

        return GroupedOpenApi.builder().group("公寓信息管理").
                pathsToMatch(
                        "/admin/apartment/**",
                        "/admin/room/**",
                        "/admin/label/**",
                        "/admin/facility/**",
                        "/admin/fee/**",
                        "/admin/attr/**",
                        "/admin/payment/**",
                        "/admin/region/**",
                        "/admin/term/**",
                        "/admin/file/**"
                ).build();
    }
    @Bean
    public GroupedOpenApi leaseAPI() {
        return GroupedOpenApi.builder().group("租赁信息管理").
                pathsToMatch(
                        "/admin/appointment/**",
                        "/admin/agreement/**"
                ).build();
    }
    @Bean
    public GroupedOpenApi userAPI() {
        return GroupedOpenApi.builder().group("平台用户管理").
                pathsToMatch(
                        "/admin/user/**"
                ).build();
    }
}

**注意**:`pathsToMatch`参数需要根据实际情况进行配置。

生成或导入基础代码

在完成上述配置后,便可使用一些逆向工具自动生成基础代码了(例如实体类、mapper、service等),在使用Mybatis-Plus作为存储层框架时,推荐使用IDEA中的[Mybatis X](https://baomidou.com/pages/ba5b24/)插件。除了可自动生成这些代码,也可直接导入资料中提供的代码。推荐大家直接导入。

导入的代码和目标位置如下:

知识点:

  1. 实体类中的公共字段(例如`id`、`create_time`、`update_time`、`is_deleted`)抽取到一个基类,进行统一管理,然后让各实体类继承该基类。

  1. 实体类中的状态字段(例如`status`)或类型字段(例如`type`),全部使用枚举类型。
  • 状态(类型)字段,在数据库中通常用一个数字表示一个状态(类型)。例如:订单状态(1:待支付,2:待发货,3:待收货,4:已收货,5:已完结)。若实体类中对应的字段也用数字类型,例如`int`,那么程序中就会有大量的如下代码:
order.setStatus(1);

if (order.getStatus() == 1) {
  order.setStatus(2);
}    
  • 这些代码后期维护起来会十分麻烦,所以本项目中所有的此类字段均使用枚举类型。例如上述订单状态可定义为以下枚举:
public enum Status {
  
   CANCEL(0, "已取消"),
   WAIT_PAY(1, "待支付"),
   WAIT_TRANSFER(2, "待发货"),
   WAIT_RECEIPT(3, "待收货"),
   RECEIVE(4, "已收货"),
   COMPLETE(5, "已完结");
   
   private final Integer value;
   private final String desc;
    
   public Integer value() {
        return value;
   }
   public String desc() {
         return desc;
   }
}
  • 订单实体类中的状态字段定义为`Status`类型:
@Data
public class Order{
     private Integer id;
     private Integer userId;
     private Status status;
     ...
}
  • 这样上述代码便可调整为如下效果,后期维护起来会容易许多。
order.setStatus(Status.WAIT_PAY);

  1. 所有的实体类均实现了`Serializable`接口,方便对实体对象进行缓存。
  2. 所有的`Mapper`接口均没有使用`@Mapper`注解,而是使用`@MapperScan`注解统一扫描。

导入接口定义代码

资料中提供了所有的Controller代码,并且Controller中定义好了每个接口(只有定义,没有实现),大家可直接导入接口定义相关的代码,然后只专注于接口逻辑的实现。

导入完成后,便可启动SpringBoot项目,并访问接口文档了,Knife4j文档的url为:http://localhost:8080/doc.html。

知识点

  1. vo(View Object):用于封装或定义接口接收及返回的数据的结构。
  2. 统一接口返回数据结构:为方便前端对接口数据进行处理,统一接口返回数据结构是一个良好的习惯。
以下是所有接口统一返回的数据结构
{
      "code": 200,
      "message": "正常",
      "data": {
          "id": "1",
          "name": "zhangsan",
          "age": 10
      }
  }
以下是与上述结构相对应的Java类
 @Data
public class Result<T> {
    
        //返回码
        private Integer code;
    
        //返回消息
        private String message;
    
        //返回数据
        private T data;
    
        public Result() {
        }
    
        private static <T> Result<T> build(T data) {
            Result<T> result = new Result<>();
            if (data != null)
                result.setData(data);
            return result;
        }
    
        public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
            Result<T> result = build(body);
            result.setCode(resultCodeEnum.getCode());
            result.setMessage(resultCodeEnum.getMessage());
            return result;
        }
    
        public static <T> Result<T> ok(T data) {
            return build(data, ResultCodeEnum.SUCCESS);
        }
    
        public static <T> Result<T> ok() {
            return Result.ok(null);
        }
    
        public static <T> Result<T> fail() {
            return build(null, ResultCodeEnum.FAIL);
        }
        
        public static <T> Result<T> fail(Integer code, String message) {
            Result<T> result = build(null);
            result.setCode(code);
            result.setMessage(message);
            return result;
        }
}
  1. ResultCodeEnum: 为方便管理,可将返回码`code`和返回消息`message`封装到枚举类。
@Getter
    public enum ResultCodeEnum {
    
        SUCCESS(200, "成功"),
        FAIL(201, "失败"),
        PARAM_ERROR(202, "参数不正确"),
        SERVICE_ERROR(203, "服务异常"),
        DATA_ERROR(204, "数据异常"),
        ILLEGAL_REQUEST(205, "非法请求"),
        REPEAT_SUBMIT(206, "重复提交"),
        DELETE_ERROR(207, "请先删除子集"),
    
        ADMIN_ACCOUNT_EXIST_ERROR(301, "账号已存在"),
        ADMIN_CAPTCHA_CODE_ERROR(302, "验证码错误"),
        ADMIN_CAPTCHA_CODE_EXPIRED(303, "验证码已过期"),
        ADMIN_CAPTCHA_CODE_NOT_FOUND(304, "未输入验证码"),
    
    
        ADMIN_LOGIN_AUTH(305, "未登陆"),
        ADMIN_ACCOUNT_NOT_EXIST_ERROR(306, "账号不存在"),
        ADMIN_ACCOUNT_ERROR(307, "用户名或密码错误"),
        ADMIN_ACCOUNT_DISABLED_ERROR(308, "该用户已被禁用"),
        ADMIN_ACCESS_FORBIDDEN(309, "无访问权限"),
    
        APP_LOGIN_AUTH(501, "未登陆"),
        APP_LOGIN_PHONE_EMPTY(502, "手机号码为空"),
        APP_LOGIN_CODE_EMPTY(503, "验证码为空"),
        APP_SEND_SMS_TOO_OFTEN(504, "验证法发送过于频繁"),
        APP_LOGIN_CODE_EXPIRED(505, "验证码已过期"),
        APP_LOGIN_CODE_ERROR(506, "验证码错误"),
        APP_ACCOUNT_DISABLED_ERROR(507, "该用户已被禁用"),
    
    
        TOKEN_EXPIRED(601, "token过期"),
        TOKEN_INVALID(602, "token非法");
    
    
        private final Integer code;
    
        private final String message;
    
        ResultCodeEnum(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    }
  1. 注意: 由于`Result`和`ResultCodeEnum`中使用`@Data`、`@Getter`注解,因此需要再**common模块**中引入`lombok`依赖。
  <!-- lombok-->
  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
  </dependency>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值