手把手教你從零開始搭建SpringBoot后端項目框架


原料

新鮮的IntelliJ IDEA、一雙手、以及電腦一台。

搭建框架

新建項目

打開IDE,點擊File -> New Project。在左側的列表中的選擇Maven項目,點擊Next。

填寫GroupId和ArtifactId

什么是GroupId和ArtifactId?大家可以參考一下google出來的定義,可以參考一下。

GroupID是項目組織唯一的標識符,實際對應JAVA的包的結構,是main目錄里java的目錄結構。

ArtifactID就是項目的唯一的標識符,實際對應項目的名稱,就是項目根目錄的名稱

簡單理解一下,可以理解為GroupId就是你的Github賬號,而ArtifactId就是你的具體某個項目,例如這個例子的源碼,SpringBootDemo,detectiveHLH/springbootdemo
detectiveHLH就是GroupId,而ArtifactId就是后面的項目名稱。

所以,這里應該填寫如下(僅供參考)。

GroupId: com.detectivehlh.test
ArtifactId: parent

test為項目的名稱。ArtifactId代表父類,所以就寫parent了。點擊Next。

設置Project Name和Project Location

ProjectName就寫項目的名稱就好。Project Location就是項目在你本地的真實路徑。填好之后,點擊Next。

然后可以看到IDE已經新建好了項目。

.
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   └── test
│       └── java
└── test.iml

然后右下角會彈出Maven projects need to be imported,選擇右邊的Enable Auto-Imported.然后刪除src目錄。

新建模塊

本次項目的框架一共有四層結構,也可以說是有四個模塊。分別是api、core、data、domain.我們從底層開始,自底向上開始構建模塊。

domain

存放實體類

點擊File -> New -> Module,在左側的列表中選擇Maven,點擊Next。在ArtifactId處填 domain,一路Next。

data模塊

主要是做一些對數據庫的操作

點擊File -> New -> Module,在左側的列表中選擇Maven,點擊Next。在ArtifactId處填 data,一路Next。在模塊中其實是存在相互依賴關系的。
data模塊依賴domain模塊的實體。所以要在data文件的配置文件中實現對domain的依賴。

打開data目錄中的pom.xml文件。在 下,添加如下代碼。

<dependencies>
    <dependency>
        <groupId>com.detectivehlh.test</groupId>
        <artifactId>domain</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

core模塊

后端主要的業務邏輯都會在core模塊中。

點擊File -> New -> Module,在左側的列表中選擇Maven,點擊Next。在ArtifactId處填 core,一路Next。同上,此處也需要配置依賴關系。
core模塊的中的service會依賴data模塊中的數據。

打開core目錄下的pom.xml文件。在 下,添加如下代碼。

<dependencies>
    <dependency>
        <groupId>com.detectivehlh.test</groupId>
        <artifactId>data</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

api模塊

主要是存放供前端調用的接口。

點擊File -> New -> Module,在左側的列表中選擇Maven,點擊Next。在ArtifactId處填 api,一路Next。此處的api模塊依賴core中的service服務。

打開api目錄下的pom.xml文件。在 下,添加如下代碼。

<dependencies>
    <dependency>
        <groupId>com.detectivehlh.test</groupId>
        <artifactId>core</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

讓項目"走兩步"

到此,框架算是搭建好了,下一步就是要讓項目"走兩步"來看看。此時的項目的目錄如下。

.
├── api
│   ├── api.iml
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   └── resources
│       └── test
│           └── java
├── core
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   └── resources
│       └── test
│           └── java
├── data
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   └── resources
│       └── test
│           └── java
├── domain
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   └── resources
│       └── test
│           └── java
├── pom.xml
└── test.iml

定位到/api/src/main/java,在java目錄下新建package,名字為你之前定義的groupid再加上模塊名,舉個例子。我這的名字就應該為com.detectivehlh.test.api,然后
在該包下新建名為Application的class。然后將代碼替換成如下代碼。

package com.detectivehlh.test.api;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

此時會報錯,是因為springboot的各項依賴,都還沒有引入項目的dependences。打開根目錄下的pom.xml文件,添加如下依賴。

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

然后打開api目錄下的pom.xml文件。在dependencies標簽中添加如下依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

此時Application中就不會報錯了。然后就可以啟動項目了。打開Application這個類,在SpringBootApplication注解下有個綠色的啟動鍵,點擊即可啟動項目。之后可在右上方啟動。

啟動之后,打開http://localhost:8080,如果頁面顯示

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Sep 18 19:01:11 CST 2018
There was an unexpected error (type=Not Found, status=404).
No message available

那么一個簡單的springboot應用就可以啟動成功了。

實現controller層

com.detectivehlh.test.api包下,新建一個名為controller的包。然后新建名為HelloController的class。
將其全部替換為如下代碼(包名根據你的項目命名自行修改)。

package com.detectivehlh.test.api.controller;

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

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello, SpringBoot";
    }
}

重新啟動項目,訪問http://localhost:8080/hello,就可以看到頁面顯示如下信息。

Hello, SpringBoot

@RestController注解比較適用於Restful風格的API,如果接口只關心數據,不做server render,就可以使用@RestController注解。
如果接口需要返回模版頁面,則需要使用@Controller注解。

@GetMapping注解,是將HTTP Get請求映射到我們自定義的hello方法上。

實現service層

新建CoreConfiguration

定位到/core/src/main/java,在java目錄下新建名為com.detectivehlh.test.core的包。然后在該包新建名為CoreConfiguration的Class。
將其全部替換為如下代碼(包名根據你的項目命名自行修改)。

package com.detectivehlh.test.core;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author detectiveHLH
 * @date 2018/09/13
 */
@ComponentScan
@Configuration
public class CoreConfiguration {

}

引入依賴

此時會報錯,同樣是因為依賴沒有引入。在core的pom.xml文件中的dependencies標簽中添加如下依賴。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

稍等片刻,就不會有報錯提示了。

新建Interface

在com.detectivehlh.test.core包下新建一個名為service的包。在service包下新建一個Class,
名字為HelloService,類型選擇Interface。然后修改代碼如下(包名根據你的項目命名自行修改)。

package com.detectivehlh.test.core.service;

public interface HelloService {
    String sayHello();
}

新建實現類

在service目錄下新建名為impl的包。然后在impl下新建名為HelloServiceImpl的類。修改代碼如下(包名根據你的項目命名自行修改)。

package com.detectivehlh.test.core.service.impl;

import com.detectivehlh.test.core.service.HelloService;
import org.springframework.stereotype.Service;

@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello() {
        return "Hello, SpringBoot";
    }
}

調用實現類

修改HelloController中的 hello 方法的代碼如下(包名根據你的項目命名自行修改)。

package com.detectivehlh.test.api.controller;

import com.detectivehlh.test.core.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * RestController
 * 定義為Restful風格的API控制器
 */
@RestController
public class HelloController {
    @Autowired
    private HelloService helloService;
    
    @GetMapping("/hello")
    public String hello() {
        return helloService.sayHello();
    }
}

此時helloService會報錯,這是因為我們沒有將HelloService這個添加到Bean容器中來。修改Application類代碼如下(包名根據你的項目命名自行修改)。

package com.detectivehlh.test.api;

import com.detectivehlh.test.core.CoreConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import(CoreConfiguration.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

此時再訪問http://localhost:8080/hello,就可以看到如下正常的輸出了。

Hello, SpringBoot

打通數據庫

實現了簡單的service,下一步就是要連接數據庫。假設現在在你本地已經有了mysql服務。有名為test的數據庫,該數據庫下有名為user_role的表。表結構如下。

數據庫表名和表數據

column_name column_value
id 用戶id
name 用戶名

並且有了數據

column_name column_value
id name
1 detectiveHLH

新建實體類

定位到/domain/src/main/java,在java目錄下新建名為com.detectivehlh.test.domain的包。在該包下新建entity包。
在entity下新建名為BaseEntity的抽象類。修改代碼如下。

package com.detectivehlh.test.domain.entity;

public abstract class BaseEntity {

    private long createdAt;

    private String createdBy;

    private long updatedAt;

    private String updatedBy;

    public long getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(long createdAt) {
        this.createdAt = createdAt;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public long getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(long updatedAt) {
        this.updatedAt = updatedAt;
    }

    public String getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }
}

在entity下新建名為UserRole的類。代碼如下。

package com.detectivehlh.test.domain.entity;

public class UserRole extends BaseEntity {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

新建dao層

實現與數據庫交互的mapper。

定位到/data/src/main/java,在java目錄下新建名為com.detectivehlh.test.data的包。在該包下新建名為dao的包和名為
DataConfiguration的類。然后在dao包下新建名為UserRoleMapper的類。DataConfiguration代碼如下。

package com.detectivehlh.test.data;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author duzhengkang
 * @date 2018/6/25
 */
@ComponentScan
@Configuration
@MapperScan("com.detectivehlh.test.data.dao")
public class DataConfiguration {

}

將UserRoleMapper的代碼修改為如下。

package com.detectivehlh.test.data.dao;

import com.detectivehlh.test.domain.entity.UserRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface UserRoleMapper {
    /**
     * 查詢所有的用戶角色
     * @return
     */
    List<UserRole> all();
}

此時代碼會報錯,同樣的依賴原因。打開根目錄下的pom.xml文件。添加如下依賴。

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>

添加如上依賴,稍等片刻,就不會報錯了。但是此時運行項目依舊會報錯。是因為我們引入了mybatis但是卻沒有配置文件。以及沒有將mapper注入到容器中去。

修改Application中的代碼如下。

package com.detectivehlh.test.api;

import com.detectivehlh.test.core.CoreConfiguration;
import com.detectivehlh.test.data.DataConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import({CoreConfiguration.class, DataConfiguration.class})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

mapper就被注入到容器中去了。下一步需要添加配置文件。定位到/api/src/main/resources,新建application.yaml文件。
修改代碼如下。

spring:
  application:
    name: test
# 數據庫配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 9687Luohongwei
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
# mapper文件配置
mybatis:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

修改完畢后,啟動項目,訪問http://localhost:8080/hello,就可以看到正常輸出了。

實現mapper

定位到/data/src/main/resources,新建名為mapper的包。在mapper包下新建名為UserRoleMapper的xml文件。修改代碼如下。

<?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.detectivehlh.test.data.dao.UserRoleMapper">
    <!--用於與數據庫字段作一一對應-->
    <resultMap id="userRoleMap" type="com.detectivehlh.test.domain.entity.UserRole">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
    </resultMap>

    <!--查詢下方列出的所有列-->
    <sql id="allColumns">
        id, name
    </sql>

    <!--定義表名-->
    <sql id="tableName">
        user_role
    </sql>

    <select id="all" resultMap="userRoleMap">
        SELECT
        <include refid="allColumns"/>
        FROM
        <include refid="tableName"/>
        ORDER BY id DESC
    </select>

</mapper>

一定注意namespace是否准確。

調用mapper

修改實現類HelloServiceImpl代碼如下。

package com.detectivehlh.springbootdemo.core.service.impl;

import com.detectivehlh.springbootdemo.core.service.HelloService;
import com.detectivehlh.springbootdemo.data.dao.UserRoleMapper;
import com.detectivehlh.springbootdemo.domain.entity.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class HelloServiceImpl implements HelloService {
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public List<UserRole> createToken(String key) {
        List<UserRole> data = userRoleMapper.all();
        return data;
    }
}

此時會報錯,是因為實現類中的返回類型已經變成了List ,而接口中的返回值還是String類型的。所以只需要修改HelloService代碼如下即可。

package com.detectivehlh.test.core.service;

import com.detectivehlh.test.domain.entity.UserRole;
import java.util.List;

public interface HelloService {
    List<UserRole> sayHello();
}

讓我們回到controller中,我們發現在HelloController中也有報錯。這個錯誤同樣也是因為返回類型不一致的原因,修改代碼如下。

package com.detectivehlh.test.api.controller;

import com.detectivehlh.test.core.service.HelloService;
import com.detectivehlh.test.domain.entity.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * RestController
 * 定義為Restful風格的API控制器
 */
@RestController
public class HelloController {
    @Autowired
    private HelloService helloService;

    @GetMapping("/hello")
    public List<UserRole> hello() {
        return helloService.sayHello();
    }
}

然后啟動項目,訪問http://localhost:8080/hello。就可以看到,接口返回了user_role表中的所有數據。

[
    {
        "createdAt": 0,
        "createdBy": null,
        "updatedAt": 0,
        "updatedBy": null,
        "id": 1,
        "name": "Tom"
    }
]

此時雖然能夠正常訪問,但是會在控制台報如下警告。

Tue Sep 18 20:40:22 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

在com.detectivehlh.test.api包下新建config包,在config包中新建DbConfig文件。代碼如下。

package com.detectivehlh.test.api.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
 * DbConfig
 *
 * @author detectiveHLH
 * @date 2018-07-27 10:35
 **/
@Configuration
@ConfigurationProperties
@EnableTransactionManagement
public class DbConfig {
    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }
    @Bean
    public PlatformTransactionManager transactionManager(){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource());
        return dataSourceTransactionManager;
    }
}

重啟啟動項目,訪問接口時就不會有警告了。

最后的代碼目錄結構如下。

.
├── api
│   ├── api.iml
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── detectivehlh
│   │   │   │           └── test
│   │   │   │               └── api
│   │   │   │                   ├── Application.java
│   │   │   │                   ├── config
│   │   │   │                   │   └── DbConfig.java
│   │   │   │                   └── controller
│   │   │   │                       └── HelloController.java
│   │   │   └── resources
│   │   │       └── application.yml
│   │   └── test
│   │       └── java
│   └── target
│       ├── classes
│       │   ├── application.yml
│       │   └── com
│       │       └── detectivehlh
│       │           └── test
│       │               └── api
│       │                   ├── Application.class
│       │                   ├── config
│       │                   │   └── DbConfig.class
│       │                   └── controller
│       │                       └── HelloController.class
│       └── generated-sources
│           └── annotations
├── core
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── detectivehlh
│   │   │   │           └── test
│   │   │   │               └── core
│   │   │   │                   ├── CoreConfiguration.java
│   │   │   │                   └── service
│   │   │   │                       ├── HelloService.java
│   │   │   │                       └── impl
│   │   │   │                           └── HelloServiceImpl.java
│   │   │   └── resources
│   │   └── test
│   │       └── java
│   └── target
│       ├── classes
│       │   └── com
│       │       └── detectivehlh
│       │           └── test
│       │               └── core
│       │                   ├── CoreConfiguration.class
│       │                   └── service
│       │                       ├── HelloService.class
│       │                       └── impl
│       │                           └── HelloServiceImpl.class
│       └── generated-sources
│           └── annotations
├── data
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── detectivehlh
│   │   │   │           └── test
│   │   │   │               └── data
│   │   │   │                   ├── DataConfiguration.java
│   │   │   │                   └── dao
│   │   │   │                       └── UserRoleMapper.java
│   │   │   └── resources
│   │   │       └── mapper
│   │   │           └── UserRoleMapper.xml
│   │   └── test
│   │       └── java
│   └── target
│       ├── classes
│       │   ├── com
│       │   │   └── detectivehlh
│       │   │       └── test
│       │   │           └── data
│       │   │               ├── DataConfiguration.class
│       │   │               └── dao
│       │   │                   └── UserRoleMapper.class
│       │   └── mapper
│       │       └── UserRoleMapper.xml
│       └── generated-sources
│           └── annotations
├── domain
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── detectivehlh
│   │   │   │           └── test
│   │   │   │               └── domain
│   │   │   │                   └── entity
│   │   │   │                       ├── BaseEntity.java
│   │   │   │                       └── UserRole.java
│   │   │   └── resources
│   │   └── test
│   │       └── java
│   └── target
│       ├── classes
│       │   └── com
│       │       └── detectivehlh
│       │           └── test
│       │               └── domain
│       │                   └── entity
│       │                       ├── BaseEntity.class
│       │                       └── UserRole.class
│       └── generated-sources
│           └── annotations
├── pom.xml
└── test.iml

寫在后面

寫的比較詳細,如果有不對的地方,大佬盡管懟。本項目的源碼在 這里

個人博客在 這里

Github在 這里,歡迎star或follow。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM