近期学习了一下基于springboot的三层架构的搭建方法,为了能起到举一反三的效果和作用,现在对springboot的三层架构的设计思路进行一个大概的总结,主要分为六个步骤(简称六脉神剑),所记如下。

一、建moudle

项目开始时使用IDEA创建maven工程,为了更加契合分布式微服务架构的搭建,这里建立聚合类型的maven工程。工程目录如下。
在这里插入图片描述
从目录中可以看到过滤掉了.idea文件和.iml文件(可以理解为隐藏了起来),可以通过setting->Editor->File Types中的Ignore files and folders中填入*.idea、*.iml实现,具体图片如下:
在这里插入图片描述

二、改Pom

IDEA的工程工作空间建立完毕以后,首先需要修改pom.xml文件中的配置,导入项目搭建过程中可能使用到的坐标依赖(如果不确定,眉毛胡子一把抓,把常用的坐标依赖都导进去)。

1、父类工程的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>

  <groupId>com.atguigu.springcloud</groupId>
  <artifactId>cloud2020</artifactId>
  <version>1.0-SNAPSHOT</version>
  <modules>
    <module>cloud-provider-payment8001</module>
  </modules>
  <packaging>pom</packaging>


  <!--统一管理jar包版本-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <junit.version>4.12</junit.version>
    <log4j.version>1.2.17</log4j.version>
    <lombok.version>1.16.18</lombok.version>
    <mysql.version>8.0.19</mysql.version>
    <druid.version>1.1.16</druid.version>
    <spring.boot.version>2.2.2.RELEASE</spring.boot.version>
    <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
    <spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version>
    <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
  </properties>

  <!--子模块继承后,提供作用:锁定版本+子module不用groupId和version-->
  <dependencyManagement>
    <dependencies>
      <!--springboot 2.2.2-->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring.boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--Spring cloud Hoxton.SR1-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring.cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--Spring cloud alibaba 2.1.0.RELEASE-->
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring.cloud.alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
      </dependency>
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
      </dependency>
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <fork>true</fork>
          <addResources>true</addResources>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <!--第三方maven私服-->
  <repositories>
    <repository>
      <id>nexus-aliyun</id>
      <name>Nexus aliyun</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
</project>

2、子类工程的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">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment8001</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

三、写yml(或properties)

maven环境依赖配置完毕以后,接下来配置后续在项目代码编写过程中需要使用到的springboot配置,这里列举了最基本的常用配置,包括:(1)端口配置 (2)数据库连接配置 (3)Mybatis配置。代码如下:

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service #服务名称
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  #当前数据源操作类型
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
    username: root
    password: root

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities #所有entity别名所在包

四、主启动

在直接建立maven工程的情况下需要自己编写主启动类(主启动类运行,服务器打开),具体代码如下:

package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PaymentMain8001 {

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

五、业务类(三层架构)

前面所做的一切都是为了业务类能够顺利编写和运行,磨刀不误砍柴工,倘若前面的配置都能顺利的完成,接下来代码的编写就如鱼得水了。三层架构的搭建主要使用自里向外的编程思维,整个流程包括:
1、mysql数据库表格的搭建
2、数据库表格对应的实体类及json封装的实体类的搭建(entities)
3、数据交互层的搭建(Dao)
4、业务逻辑层的搭建(service)
5、表现层的搭建(controller)

1、mysql数据库表格的搭建

直接在mysql图形界面中输入对应的sql语句生成对应的表格,推荐使用SQLyog工具。这里作为演示使用一个非常简单的表格,代码如下:

CREATE DATABASE cloud;
CREATE TABLE `payment`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `serial` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '支付流水号',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = INNODB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '支付表' ROW_FORMAT = DYNAMIC;

生成的表格配置如下图所示:
在这里插入图片描述

2、数据库表格对应的实体类及json封装的实体类的搭建(entities)

(1)根据数据表格的变量名称编写对应的Payment实体类,代码如下:

package com.atguigu.springcloud.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
//这里使用lombok注解配置的方式替代Getter、Setter等习惯用方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
    private Long id;
    private String serial;
}

(2)编写json封装的实体类,因为现在前后端分离是大势所趋,因此在后端工作人员业务操作完毕后,把需要显示的数据以json的格式传输给前端进行显示,为了前后端工作人员的更好的协调沟通,对返回的json格式进行了一定的规范,以code、message、data为变量的实体类格式返回,相对应的CommonResult实体类代码如下:

package com.atguigu.springcloud.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {

    private Integer code;
    private String message;
    private T data;

    public CommonResult(Integer code, String message) {
        this(code, message, null);
    }
}
3、数据交互层的搭建(Dao)

数据交互层使用mybatis框架进行搭建,这里使用xml的方式进行数据库访问,因此主要包括接口程序的编写以及对应xml映射文件的编写。
(1)PaymentDao接口程序的编写

package com.atguigu.springcloud.dao;
import com.atguigu.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface PaymentDao {
    /**
     * 插入数据
     * @param payment
     * @return
     */
    public int create(Payment payment);
    /**
     * 根据id查找数据
     * @param id
     * @return
     */
    public Payment getPaymentById(@Param("id") Long id);
}

(2)PaymentMapper.xml映射文件的编写(编写过程中需要注意映射的包路径是否正确以及xml文件所在位置是否与yml配置的位置一致)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.springcloud.dao.PaymentDao">
    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) VALUES (#{serial})
    </insert>
    <resultMap id="BaseResultMap" type="com.atguigu.springcloud.entities.Payment">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="serial" property="serial" jdbcType="VARCHAR"/>
    </resultMap>
   
    <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        SELECT * from payment WHERE id=#{id}
    </select>
</mapper>
4、业务逻辑层的搭建(service)

(1)PaymentService接口程序

package com.atguigu.springcloud.service;

import com.atguigu.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Param;
public interface PaymentService {
    /**
     * 插入数据
     * @param payment
     * @return
     */
    public int create(Payment payment);

    /**
     * 根据id查找数据
     * @param id
     * @return
     */
    public Payment getPaymentById(Long id);
}

(2)PaymentServiceImpl实现类程序

package com.atguigu.springcloud.service;

import com.atguigu.springcloud.dao.PaymentDao;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class PaymentServiceImpl implements PaymentService {

    @Resource // 这里也可以使用@Autowired进行注入
    PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }
}

5、表现层的搭建(controller)

其中api使用restful设计风格,同时引入slf4j日志进行记录。

package com.atguigu.springcloud.Controller;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Controller
@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;
    
    //接收表单数据
    @PostMapping("/payment/create")
    public CommonResult create(Payment payment){
        int result = paymentService.create(payment);
        log.info("****插入结果" + result);
        if (result > 0) {
            return new CommonResult(200, "插入数据成功", result);
        } else {
            return new CommonResult(444, "插入数据识别", null);
        }
    }
    @GetMapping("/payment/getPaymentById/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("****查找结果" + payment);
        if (payment != null) {
            return new CommonResult(200, "查找对象成功", payment);
        } else {
            return new CommonResult(444, "查找对象失败", null);
        }
    }
    //使用@RequestBody注解接受json格式的数据
    @PostMapping("/payment/json")
    public CommonResult jsonCreate(@RequestBody  Payment payment){
        int result = paymentService.create(payment);
        log.info("****插入结果" + result);
        if (result > 0) {
            return new CommonResult(200, "插入数据成功", result);
        } else {
            return new CommonResult(444, "插入数据识别", null);
        }
    }

}

六、测试

在前后端分离的情况下,返回的是CommonResult类对应的json格式。主启动类运行后,可以用eolinker(或postman)工具进行测试。
(1)post方法提交表单数据请求的响应
在这里插入图片描述
(2)get方法请求的响应
在这里插入图片描述
(3)post方法提交json数据请求的响应
在这里插入图片描述
操作完毕后的数据库表格如下图:
在这里插入图片描述
以上基于springboot的三层架构设计完毕,编写的接口可供前端的工作员调用,设计出高大上的软件界面。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐