资讯专栏INFORMATION COLUMN

手把手教你从零开始搭建SpringBoot后端项目框架

edagarli / 1837人阅读

摘要:新建模块本次项目的框架一共有四层结构,也可以说是有四个模块。然后打开目录下的文件。此时中就不会报错了。实现定位到,新建名为的包。用于与数据库字段作一一对应查询下方列出的所有列定义表名一定注意是否准确。

原料

新鲜的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文件。在下,添加如下代码。


    
        com.detectivehlh.test
        domain
        1.0-SNAPSHOT
    
core模块

后端主要的业务逻辑都会在core模块中。

点击File -> New -> Module,在左侧的列表中选择Maven,点击Next。在ArtifactId处填 core,一路Next。同上,此处也需要配置依赖关系。
core模块的中的service会依赖data模块中的数据。

打开core目录下的pom.xml文件。在下,添加如下代码。


    
        com.detectivehlh.test
        data
        1.0-SNAPSHOT
    
api模块

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

点击File -> New -> Module,在左侧的列表中选择Maven,点击Next。在ArtifactId处填 api,一路Next。此处的api模块依赖core中的service服务。

打开api目录下的pom.xml文件。在下,添加如下代码。


    
        com.detectivehlh.test
        core
        1.0-SNAPSHOT
    
让项目"走两步"

到此,框架算是搭建好了,下一步就是要让项目"走两步"来看看。此时的项目的目录如下。

.
├── 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文件,添加如下依赖。

 
    org.springframework.boot
    spring-boot-starter-parent
    2.0.4.RELEASE
     

然后打开api目录下的pom.xml文件。在dependencies标签中添加如下依赖。


    org.springframework.boot
    spring-boot


    org.springframework.boot
    spring-boot-autoconfigure


    org.springframework.boot
    spring-boot-starter-web

此时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标签中添加如下依赖。


    org.springframework
    spring-context
    5.0.5.RELEASE

稍等片刻,就不会有报错提示了。

新建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 all();
}

此时代码会报错,同样的依赖原因。打开根目录下的pom.xml文件。添加如下依赖。


    com.alibaba
    druid
    1.1.10


    com.github.pagehelper
    pagehelper-spring-boot-starter
    1.2.5


    mysql
    mysql-connector-java
    6.0.6


    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    1.3.2

添加如上依赖,稍等片刻,就不会报错了。但是此时运行项目依旧会报错。是因为我们引入了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文件。修改代码如下。




    
    
        
        
    

    
    
        id, name
    

    
    
        user_role
    

    

一定注意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 createToken(String key) {
        List 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 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 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。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77190.html

相关文章

  • 把手教你从零搭建react局部热加载环境

    摘要:有没有办法实现就局部刷新呢当然是有第十步执行为了实现局部热加载,我们需要添加插件。 前言 用了3个多月的vue自认为已经是一名合格的vue框架api搬运工,对于vue的api使用到达了一定瓶颈,无奈水平有限,每每深入底层观赏源码时候都迷失了自己。 遂决定再找个框架学习学习看看能否突破思维局限,加上本人早已对React、RN技术垂涎已久,于是决定找找教程来学习。无奈第一步就卡在了环境搭...

    quietin 评论0 收藏0
  • 把手教你从零写一个简单的 VUE

    摘要:本系列是一个教程,下面贴下目录手把手教你从零写一个简单的手把手教你从零写一个简单的模板篇今天给大家带来的是实现一个简单的类似一样的前端框架,框架现在应该算是非常主流的前端数据驱动框架,今天我们来从零开始写一个非常简单的框架,主要是让大家 本系列是一个教程,下面贴下目录~1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 今天给大家带来的是实现一个简单...

    RebeccaZhong 评论0 收藏0
  • Java后端

    摘要:,面向切面编程,中最主要的是用于事务方面的使用。目标达成后还会有去构建微服务,希望大家多多支持。原文地址手把手教程优雅的应用四手把手实现后端搭建第四期 SpringMVC 干货系列:从零搭建 SpringMVC+mybatis(四):Spring 两大核心之 AOP 学习 | 掘金技术征文 原本地址:SpringMVC 干货系列:从零搭建 SpringMVC+mybatis(四):Sp...

    joyvw 评论0 收藏0
  • 小强开饭店-从单体应用到微服务

    摘要:本篇博客通过小强开饭店的通俗易懂的故事,带你了解后端服务是如果从单体应用演变到微服务的。小强开饭店有一天,小强为了早日奔赴小康生活,打算开一个饭店来帮他快速的实现这个目标。于是小强开始给服务尽量的无状态化,然后在一个服务器上启动了几个实例。 本篇博客通过小强开饭店的通俗易懂的故事,带你了解后端服务是如果从单体应用演变到微服务的。如果有说的不对的地方,欢迎各位大佬强势怼。 小强开饭店 有...

    shengguo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<