spring boot + vue + element-ui全栈开发入门——spring boot后端开发

前言


 

本文讲解作为后端的spring boot项目开发流程,如果您还不会配置spring boot环境,就请点击《玩转spring boot——快速开始》,如果您对spring boot还没有入门,就请点击《玩转spring boot——开篇》学习spring boot开发。

 

一、构建项目

使用STS构建Spring Starter项目

 

 

pom.xml中添加依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        <!-- web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- jpa -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- devtools -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- mysql -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>           

  

 

 

完整的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.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>spring boot 全栈开发入门系列(www.cnblogs.com/goodhelper)</description>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- commons -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
        <finalName>demo</finalName>
    </build>


</project>
pom.xml
复制代码

 

二、代码编写


 

 

JPA映射类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.example;
 
import java.util.Date;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
 
import org.hibernate.annotations.GenericGenerator;
 
import com.fasterxml.jackson.annotation.JsonFormat;
 
/**
 * 会员
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
@Entity
@Table(name = "t_member")
public class Member {
 
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(name = "member_id", length = 36)
    public String id;
 
    /**
     * 注册日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "`date`")
    public Date date;
 
    /**
     * 姓名
     */
    @Column(name = "`name`", length = 50)
    public String name;
 
    /**
     * 性别
     */
    @Column(name = "sex")
    public Integer sex;
 
    // 省略 get set
}

  

  

 

新建Repository类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example;
 
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 
/**
 * 会员Repository类
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
public interface MemberRepository extends JpaRepository<Member, String>, JpaSpecificationExecutor<Member> {
 
}

  

 

新建三个DTO类,分别是:

ExecuteDTO:操作执行的反馈

PageQueryParamDTO:分页查询参数

PageResultDTO:分页结果承载

 

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
 * 操作执行DTO
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
public class ExecuteDTO {
 
    private boolean success;
 
    private String message;
 
    private Object value;
 
    public ExecuteDTO() {
    }
 
    public ExecuteDTO(boolean success, String message, Object value) {
        this.success = success;
        this.message = message;
        this.value = value;
    }
 
    public boolean isSuccess() {
        return success;
    }
 
    public void setSuccess(boolean success) {
        this.success = success;
    }
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
 
    public Object getValue() {
        return value;
    }
 
    public void setValue(Object value) {
        this.value = value;
    }
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
 * 分页查询参数DTO
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
public class PageQueryParamDTO {
 
    /**
     * 页码
     */
    private int page;
 
    /**
     * 每页数量
     */
    private int size;
 
    /**
     * 查询条件
     */
    private Object query;
 
    public PageQueryParamDTO() {
    }
 
    public PageQueryParamDTO(int page, int size, Object query) {
        this.page = page;
        this.size = size;
        this.query = query;
    }
 
    public int getPage() {
        return page;
    }
 
    public void setPage(int page) {
        this.page = page;
    }
 
    public int getSize() {
        return size;
    }
 
    public void setSize(int size) {
        this.size = size;
    }
 
    public Object getQuery() {
        return query;
    }
 
    public void setQuery(Object query) {
        this.query = query;
    }
 
}

  

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
 * 分页结果DTO
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
public class PageResultDTO {
 
    private long total;
 
    private List<?> rows;
 
    public PageResultDTO() {
    }
 
    public PageResultDTO(long total, List<?> rows) {
        this.total = total;
        this.rows = rows;
    }
 
    public long getTotal() {
        return total;
    }
 
    public void setTotal(long total) {
        this.total = total;
    }
 
    public List<?> getRows() {
        return rows;
    }
 
    public void setRows(List<?> rows) {
        this.rows = rows;
    }
 
}

  

 

控制器:MemberController

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.example;
 
import java.util.Date;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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;
 
/**
 * 会员控制器
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
@RestController
@RequestMapping("member")
public class MemberController {
 
    @Autowired
    private MemberRepository repository;
 
    @GetMapping("get/{id}")
    public Member get(@PathVariable String id) {
        return repository.findOne(id);
    }
 
    @PostMapping("save")
    public ExecuteDTO save(@RequestBody Member entity) {
        if (entity.date == null) {
            entity.date = new Date();
        }
        repository.save(entity);
        return new ExecuteDTO(true, "保存成功", entity.id);
    }
 
    @PostMapping("loadPage")
    public PageResultDTO loadPage(@RequestBody PageQueryParamDTO params) {
 
        // 动态查询条件
        Specification<Member> spec = (root, query, cb) -> {
            if (params.getQuery() != null) {
                // 筛选 会员姓名
                query.where(cb.equal(root.get("name"), params.getQuery().toString()));
            }
 
            return null;
        };
        Pageable pageable = new PageRequest(params.getPage() - 1, params.getSize());
        Page<Member> pageResult = repository.findAll(spec, pageable);
 
        // 返回分页数据
        return new PageResultDTO(pageResult.getTotalElements(), pageResult.getContent());
    }
 
    @GetMapping("remove/{id}")
    public ExecuteDTO remove(@PathVariable String id) {
        repository.delete(id);
        return new ExecuteDTO(true, "删除成功", id);
    }
 
}

  

 

单元测试类MemberTests,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.example;
 
import static org.assertj.core.api.Assertions.*;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
 
/**
 * 单元测试
 *
 * @author 刘冬 博客出处:http://www.cnblogs.com/GoodHelper/
 *
 */
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MemberTests {
 
    @LocalServerPort
    private int port;
 
    @Autowired
    private TestRestTemplate restTemplate;
 
    @Test
    public void test() {
        String baseUrl = "http://localhost:" + port;
 
        String name = "刘冬";
 
        // 测试添加
        Member entity = new Member();
        entity.name = name;
        entity.sex = 1;
        ExecuteDTO execute = this.restTemplate.postForObject(baseUrl + "/member/save", entity, ExecuteDTO.class);
        assertThat(execute).isNotNull();
        assertThat(execute.isSuccess()).isTrue();
        assertThat(execute.getValue()).isNotNull();
 
        // 测试获取
        entity = this.restTemplate.getForObject(baseUrl + "/member/get/" + execute.getValue(), Member.class);
        assertThat(entity).isNotNull();
        assertThat(entity.id).isNotNull();
        assertThat(entity.name).isEqualTo(name);
 
        // 测试修改
        entity.name = "刘冬的博客";
        execute = this.restTemplate.postForObject(baseUrl + "/member/save", entity, ExecuteDTO.class);
        assertThat(execute).isNotNull();
        assertThat(execute.isSuccess()).isTrue();
 
        // 测试修改成功
        entity = this.restTemplate.getForObject(baseUrl + "/member/get/" + entity.id, Member.class);
        assertThat(entity).isNotNull();
        assertThat(entity.id).isNotNull();
        assertThat(entity.name).isNotEqualTo(name);
 
        // 测试查询分页
        PageQueryParamDTO param = new PageQueryParamDTO(1, 20, null);
        PageResultDTO pageResult = this.restTemplate.postForObject(baseUrl + "/member/loadPage", param,
                PageResultDTO.class);
        assertThat(pageResult).isNotNull();
        assertThat(pageResult.getRows()).isNotEmpty();
        assertThat(pageResult.getTotal()).isGreaterThan(0);
 
        // 测试删除
        execute = this.restTemplate.getForObject(baseUrl + "/member/remove/" + entity.id, ExecuteDTO.class);
        assertThat(execute).isNotNull();
        assertThat(execute.isSuccess()).isTrue();
 
        // 测试是否已删除
        entity = this.restTemplate.getForObject(baseUrl + "/member/get/" + entity.id, Member.class);
        assertThat(entity).isNull();
    }
 
}

  

 

App.class入口类:

1
2
3
4
5
6
7
@SpringBootApplication
public class App {
 
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

  

 

最后配置参数application.properties:

1
2
3
4
5
6
7
server.port=18080
 
spring.datasource.url=jdbc:mysql://localhost:3306/example
spring.datasource.username=root
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

  

把8080默认端口修改为18080,因为之前我们的前端项目的端口是8080,如果同一台电脑运行会出现端口冲突。

 

完整的项目结构如图所示:

 

运行单元测试的效果:

 

 

单元测试顺利通过

 

 

返回目录

 

git代码地址:https://github.com/carter659/spring-boot-vue-element.git

 

如果你觉得我的博客对你有帮助,可以给我点儿打赏,左侧微信,右侧支付宝。

有可能就是你的一点打赏会让我的博客写的更好:)

posted @   冬子哥  阅读(10190)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示