前言


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

一、构建项目

使用STS构建Spring Starter项目

pom.xml中添加依赖:

                <!-- 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映射类:

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类:

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:分页结果承载

代码如下:

/**
* 操作执行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;
} }

  

/**
* 分页查询参数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;
} }

  

/**
* 分页结果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

代码如下:

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,代码如下:

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入口类:

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

  

最后配置参数application.properties:

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

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

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

spring boot + vue + element-ui全栈开发入门——spring boot后端开发的更多相关文章

  1. 分享一个自搭的框架,使用Spring boot+Vue+Element UI

    废弃,新的:https://www.cnblogs.com/hackyo/p/10453243.html 特点:前后端分离,可遵循restful 框架:后端使用Spring boot,整合了aop.a ...

  2. 新书上线:《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》,欢迎大家买回去垫椅子垫桌脚

    新书上线 大家好,笔者的新书<Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统>已上线,此书内容充实.材质优良,乃家中必备垫桌脚 ...

  3. koa+mysql+vue+socket.io全栈开发之数据访问篇

    后端搭起大体的框架后,接着涉及到的就是如何将数据持久化的问题,也就是对数据库进行 CURD 操作. 关于数据库方案, mongodb 和 mysql 都使用过,但我选用的是 mysql,原因: 目前为 ...

  4. 实习模块vue+java小型全栈开发(三)

    实习模块vue+java小型全栈开发(三) --dx 背景 首先,先给自己一个答案:这篇博客我定义为(三),因为之前的两个模块页面,内容都是一样的,但是被改了几次需求,就一直拖着没有上传. 今天是真正 ...

  5. 基于vue(element ui) + ssm + shiro 的权限框架

    zhcc 基于vue(element ui) + ssm + shiro 的权限框架 引言 心声 现在的Java世界,各种资源很丰富,不得不说,从分布式,服务化,orm,再到前端控制,权限等等玲琅满目 ...

  6. Vue + Element UI 实现权限管理系统

    Vue + Element UI 实现权限管理系统 前端篇(一):搭建开发环境 https://www.cnblogs.com/xifengxiaoma/p/9533018.html

  7. vue + element ui 实现实现动态渲染表格

    前言:之前需要做一个页面,能够通过表名动态渲染出不同的表格,这里记录一下.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9786326.html 网站地址:我的 ...

  8. vue + element ui 表格自定义表头,提供线上demo

    前言:工作中用到 vue+element ui 的前端框架,需要使用自定义表头,需要使用 re.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9710826.h ...

  9. vue+element ui 的上传文件使用组件

    前言:工作中用到 vue+element ui 的前端框架,使用到上传文件,则想着封装为组件,达到复用,可扩展.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9 ...

  10. vue+element ui 的表格列使用组件

    前言:工作中用到 vue+element ui 的前端框架,有这个场景:很多表格的列有许多一样的,所以考虑将列封装为组件.转载请注明出处:https://www.cnblogs.com/yuxiaol ...

随机推荐

  1. 69. x 的平方根

    问题描述 实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: ...

  2. Unity项目导入的error

    5.6.3error 如下:An assembly with the same name `UnityEngine.UI' has already been imported. Consider re ...

  3. java单链表反转(花了半个多小时的作品)

    欢迎光临............... 首先我们要搞清楚链表是啥玩意儿?先看看定义: 讲链表之前我们先说说Java内存的分配情况:我们new对象的时候,会在java堆中为对象分配内存,当我们调用方法的 ...

  4. react-native-splash-screen 插件 android 系统app崩溃问题

    问题 react-native版本 0.53.3 react-native-splash-screen版本 3.0.6 一切配置妥当后出现如下问题: 在android studio里的调试报错为and ...

  5. 如何根据checkbox的值进行勾选!例:我要勾选value等于scanbuy,terminal的复选框!

    微商城 随手购 自助购 <div class="controls" id="client"> <input id="mall&quo ...

  6. 3.2station

    题意火车进入,然后要求以最大字典序输出 解题思路:先用一个数组储存当前位置之后最大的数字是什么,然后把已经进站的最后一节火车和还没进站的车的最大值,哪个更大,如果已经进站的更大,那么就先出站,否则就先 ...

  7. ElasticSearch 一

    一:elasticSearch的目录结构的分类 /bin 运行ElasticSearch实例和管理插件呢的一些脚本 /config 配置文件 路径,包含elasticsearch.yml /data ...

  8. 19 ArcGIS Server 备份与恢复

    一.备份过程 1.找到已经安装的arcgis server安装目录,并找到备份工具: 2.快捷键win + R启动cmd,将备份工具文件拖入cmd窗口,enter 3. 通过backup.py脚本进行 ...

  9. html表格以pdf格式导出到本地

    引入插件 jsPdf.js 以及 html2canvas.js,具体文件可上github找,实测可行html2canvas(document.getElementById("downBox& ...

  10. 一篇搞懂python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)

           关于文件操作的几种常用方式,网上已有很多解说,内容很丰富,但也因此有些杂乱复杂.今天,我就以我个人的学习经验写一篇详细又易懂的总结文章,希望大家看完之后会有所收获. 一.核心功能 ‘r’ ...