【SpringBoot-1】面向小白编程:从0开始创建一个SpringBoot项目
本文将从0开始,创建一个SpringBoot项目,实现数据查询功能。如果你是一个新手,不要慌,先跟着博文操作去实现,知其然而后知其所以然。
项目的功能很简单,将数据库数据读取封装并返回(数据库造数据SQL在文章末尾),效果如下:
数据库数据:
id |
name |
type |
price |
size |
status |
description |
---|---|---|---|---|---|---|
1 |
iphone |
国产 |
9000 |
10 |
有货 |
爱疯你值得拥有 |
2 |
电磁炉 |
进口 |
200 |
30 |
有货 |
非洲进口 |
3 |
空调 |
国产 |
3000 |
15 |
缺货 |
爱疯你值得拥有 |
4 |
洗衣机 |
进口 |
1200 |
17 |
有货 |
健身型全手动洗衣机 |
5 |
电冰箱 |
国产 |
1800 |
20 |
有货 |
加热小能手 |
6 |
吸顶灯 |
国产 |
3600 |
12 |
缺货 |
黑洞制造者 |
接口响应数据:
{
"msg": "操作成功!",
"code": "0",
"data": [
{
"size": 10,
"price": 9000.0,
"name": "iphone",
"description": "爱疯值得拥有",
"id": 1,
"type": "国产",
"status": "有货"
},
{
"size": 30,
"price": 200.0,
"name": "电磁炉",
"description": "非洲进口",
"id": 2,
"type": "进口",
"status": "有货"
},
{
"size": 15,
"price": 3000.0,
"name": "空调",
"description": "你的温度管家",
"id": 3,
"type": "国产",
"status": "缺货"
},
{
"size": 17,
"price": 1200.0,
"name": "洗衣机",
"description": "健身型全手动洗衣机",
"id": 4,
"type": "进口",
"status": "有货"
},
{
"size": 20,
"price": 1800.0,
"name": "电冰箱",
"description": "加热小能手",
"id": 5,
"type": "国产",
"status": "有货"
}
],
"count": 6
}
如果配合前端效果是这个样子,具体实现请见:https://blog.csdn.net/mu_wind/article/details/97519334
1 环境配置
各组件版本信息如下:
- SpringBoot版本:2.0
- JDK版本:1.8
- 开发工具:IntelliJ IDEA
- 构建工具:maven-3.5.0
构建工具是一个把源代码生成可执行应用程序的自动化工具,Java 领域中主要有三大构建工具:Ant、Maven 和 Gradle。
- Ant(AnotherNeatTool)的核心是由 Java 编写,采用 XML 作为构建脚本,这样就允许你在任何环境下运行构建。Ant 是 Java 领域最早的构建工具,不过因为操作复杂,慢慢的已经被淘汰了。
- Maven,Maven 发布于 2004 年,目的是解决程序员使用 Ant 所带来的一些问题,它的好处在于可以将项目过程规范化、自动化、高效化以及强大的可扩展性。
- Gradle,Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化建构工具。它使用一种基于 Groovy 的特定领域语言来声明项目设置,而不是传统的 XML。结合了前两者的优点,在此基础之上做了很多改进,它具有 Ant 的强大和灵活,又有 Maven 的生命周期管理且易于使用。
2 创建项目
创建项目前,配置编码格式,这是一个容易忽略的点,IDEA 中,仍然依次打开 File -> Settings,搜索“Encoding”,配置本地的编码信息,如下图所示:
2.1 使用IDEA构建项目
首先,打开IDEA,点击File–New–Project:
选择Spring Initializr,点击Next:
这一步有Group和Artifact两个选项,需要填入GroupId和ArtifactId。那么,什么是GroupId和ArtifactId? GroupId和ArtifactId被统称为“坐标”,是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找。 GroupId一般分为多个段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。举个apache公司的tomcat项目例子:这个项目的groupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,ArtifactId是tomcat。
选择项目名称和保存目录
点击Finish,再自行创建包和类,完成项目的创建:
project
+-src
+- main
+- java
+- com.example.demo
+- config
+- controller
+- dao
+- model
+- service
+- utils
+- Application.java
+- resources
+- static
+- templates
+- application.yml
+- test
+-pom.xml
创建好的项目结构如上图,可以看到自己创建了一些包,说下它们的作用:
- config:放置配置类
- controller:放置对外暴露接口的类
- dao:与数据库交互,命名为mapper更加规范,看个人习惯
- model:主要用于实体(Entity)与数据访问层(Repository)
- service:主要是业务类代码
- utils:工具类
resources 目录下:
- static:目录存放 web 访问的静态资源,如 js、css、图片等; templates 目录存放页面模板;
- application.yml:存放项目的配置信息。
- test:目录存放单元测试的代码;
- pom.xml:用于配置项目依赖包,以及其他配置。
2.2 pom文件介绍
pom.xml 文件主要描述了项目包的依赖和项目构建时的配置,在默认的 pom.xml 包中分为四大块。完整的pom.xml文件在文章末尾。
第一部分为项目的描述信息:
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
groupId:项目的包路径; artifactId:项目名称; version:项目版本号; packaging:一般有两个值:jar、war,表示使用 Maven 打包时构建成 Jar 包还是 War 包; name:项目名称; description:项目描述。
第二部分为项目的依赖配置信息:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- parent:标签内配置 Spring Boot 父级版本 spring-boot-starter-parent,Maven 支持项目的父子结构,引入父级后会默认继承父级的配置;
- dependencies:标签内配置项目所需要的依赖包,Spring Boot 体系内的依赖组件不需要填写具体版本号,spring-boot-starter-parent 维护了体系内所有依赖包的版本信息。
第三部分为构建时需要的公共变量:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<fastjson.version>1.2.47</fastjson.version>
<druid.version>1.1.9</druid.version>
<mybatis.version>1.3.2</mybatis.version>
</properties>
上面配置了项目构建时所使用的编码,输出所使用的编码,最后指定了项目使用的 JDK 版本和其他第三方jar包的版本。
第四部分为构建配置:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
使用 Maven 构建 Spring Boot 项目必须依赖于 spring-boot-maven-plugin 组件,spring-boot-maven-plugin 能够以 Maven 的方式为应用提供 Spring Boot 的支持,即为 Spring Boot 应用提供了执行 Maven 操作的可能。spring-boot-maven-plugin 能够将 Spring Boot 应用打包为可执行的 jar 或 war 文件,然后以简单的方式运行 Spring Boot 应用。
2.3 application.yml配置文件
项目自动生成的配置文件是.properties文件,个人习惯使用更加简洁直观的.yml格式,文件中配置了项目的端口号和数据库连接信息:
server:
port: 8088
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=true
username: root
password:
serverTimezone=UTC要放在第一个位置,如果没有这个属性,可能出现以下异常: Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC
2.4 各层详解
上面项目结构图中,我们自行创建了很多层级,它们各自发挥作用,共同构成一个项目,下面分别详解一下各层级的作用。
2.4.1 controller
这部分的作用是对外提供接口。一个标准的controller
类如下:
package mudemo.controller;
import com.alibaba.fastjson.JSONObject;
import mudemo.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
@RequestMapping(value = "/goodsList", method = RequestMethod.GET)
public JSONObject getGoodsList(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize) {
return goodsService.getGoodsList(pageNum, pageSize);
}
@RequestMapping(value = "/updateGood", method = RequestMethod.POST)
public JSONObject updateGood(@RequestBody JSONObject request) {
return goodsService.updateGood(request);
}
}
首先我们看一下其中用到的几个注解:
-
@RestController
:MVC中应用非常频繁的一个注解,也是 SpringBoot 新增的一个注解,可以看作是 @Controller 和 @ResponseBody 的结合体,作用是返回JSON格式的数据 -
@RequestMapping
:一个用来处理请求地址映射的注解,它可以用于类上,也可以用于方法上。用于类上的注解会将一个特定请求或者请求模式映射到一个控制器之上,表示类中的所有响应请求的方法都是以该地址作为父路径;方法的级别上注解表示进一步指定到处理方法的映射关系。该注解有 6 个属性,一般在项目中比较常用的有 3 个属性:value、method 和 produces。-
value
属性:指定请求的实际地址,value 可以省略不写。 -
method
属性:指定请求的类型,主要有GET、PUT、POST、DELETE,默认为 GET。 -
produces
属性:指定返回内容类型。
-
-
@RequestParam("id")
:获取请求参数,例如从http://localhost:8080/student?id=1
中获取id的值 -
@RequestBody
:也是获取请求的参数,但不同的是,@RequestBody
是获取JSON格式的参数
2.4.2 service
service层是项目的逻辑实现层。一般包含service接口类和它的实现类。本项目中,接口类如下:
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
@Service
public interface GoodsService {
// 查询
JSONObject getGoodsList(int pageNum, int pageSize);
// 更新
JSONObject updateGood(JSONObject request);
}
可以看到,接口类中只定义了一系列的方法,并没有具体实现,具体实现由其实现类完成:
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import mudemo.dao.GoodsMapper;
import mudemo.model.Good;
import mudemo.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service(value = "GoodsService")
public class GoodsServiceImpl implements GoodsService {
@Autowired
private GoodsMapper goodsMapper;
@Override
public JSONObject getGoodsList(int pageNum, int pageSize) {
JSONObject result = new JSONObject();
try {
PageHelper.startPage(pageNum, pageSize);
PageInfo<Good> pageInfo = new PageInfo(goodsMapper.getGoodsList());
result.put("code", "0");
result.put("msg", "操作成功!");
result.put("data", pageInfo.getList());
result.put("count", pageInfo.getTotal());
} catch (Exception e) {
result.put("code", "500");
result.put("msg", "查询异常!");
}
return result;
}
@Override
public JSONObject updateGood(JSONObject request) {
JSONObject result = new JSONObject();
try {
goodsMapper.updateGood(request);
result.put("code", "0");
result.put("msg", "操作成功!");
} catch (Exception e) {
result.put("code", "500");
result.put("msg", "修改商品异常!");
}
return result;
}
}
阅读代码可知,这个类实现了从数据库获取数据并封装的逻辑。其中关键所在是goodsMapper.getGoodsList()
,它是dao层中的一个方法,我们去看一下里面有何玄机。
2.4.3 dao
dao层中是与数据库交互的类,也可以理解为写SQL的地方,比如下面这个类中,一个方法对应着一个SQL,调用方法就会执行SQL并将SQL的结果封装到预定的数据结构中。
import com.alibaba.fastjson.JSONObject;
import mudemo.model.Good;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface GoodsMapper {
@Select("SELECT * FROM 58test.goods")
List<Good> getGoodsList();
@Update("UPDATE mutest.goods SET type=#{type},name=#{name},price=#{price},size=#{size},status=#{status},description=#{description} WHERE id=#{id}")
void updateGood(JSONObject request);
}
2.4.4 启动类
启动类中没有太多内容,只有@MapperScan(value = "com.mudemo.dao")
为自行添加,目的是表明数据库交互层的路径。
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = "com.mudemo.dao")
public class MudemoApplication {
public static void main(String[] args) {
SpringApplication.run(MudemoApplication.class, args);
}
}
项目创建完成,在启动类上右键点击Run MudemoApplication,即可启动项目。然后按controller中的信息,去请求一下接口:
3 附录
3.1 演示数据
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`price` decimal(10,0) DEFAULT NULL,
`size` double DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES ('1', 'iphone', '国产', '9000', '10', '有货', '爱疯值得拥有');
INSERT INTO `goods` VALUES ('2', '电磁炉', '进口', '200', '30', '有货', '非洲进口');
INSERT INTO `goods` VALUES ('3', '空调', '国产', '3000', '15', '缺货', '你的温度管家');
INSERT INTO `goods` VALUES ('4', '洗衣机', '进口', '1200', '17', '有货', '健身型全手动洗衣机');
INSERT INTO `goods` VALUES ('5', '电冰箱', '国产', '1800', '20', '有货', '加热小能手');
INSERT INTO `goods` VALUES ('6', '吸顶灯', '国产', '3600', '12', '缺货', '黑洞制造者');
3.2 完整pom.xml
下面附上完整的pom文件,包括了几个常用的依赖(mysql、lombak等),可以自行删除,另外,注意根据自己的项目进行修改groupId、artifactId、name等:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>mudemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mudemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<swagger.version>2.8.0</swagger.version>
<google.guava>23.0</google.guava>
<fastjson.version>1.2.47</fastjson.version>
<druid.version>1.1.9</druid.version>
<poi.version>3.17</poi.version>
<jwt.version>0.9.0</jwt.version>
<mybatis.version>1.3.2</mybatis.version>
</properties>
<dependencies>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!--连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 如何写好一篇漏洞报告(国外篇)
- hbase源码系列(八)从Snapshot恢复表
- hbase源码系列(七)Snapshot的过程
- CVE-2017-3085:Adobe Flash泄漏Windows用户凭证
- hbase源码系列(九)StoreFile存储格式
- 如何确定恶意软件是否在自己的电脑中执行过?
- Carbondata源码系列(二)文件格式详解
- 挖洞经验 | 记一次针对Twitter(Periscope)API 的有趣挖洞经历
- 设计模式学习(二): 观察者模式 (C#)
- Carbondata源码系列(一)文件生成过程
- BoopSuite:基于Python编写的无线安全审计套件
- 设计模式学习(一):多用组合少用继承(C#)
- 在asp.net web api 2 (ioc autofac) 使用 Serilog 记录日志
- hbase源码系列(十三)缓存机制MemStore与Block Cache
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- C++核心准则T.121:模板元编程主要用于模仿概念
- C++核心准则T.122:使用模板在编译时计算类型
- C++核心准则T.123:使用常量表达式函数在编译时求值
- Java基础 【类之间的关系】
- MySql 学习之路-基础
- (有趣的)项目实战:Java实现计算机自动关机
- 猜生日 Java小游戏
- KDD Cup 2020多模态召回比赛亚军方案与搜索业务应用
- 一文快速入门分库分表(必修课)
- MySQL · 物理备份 · XtraBackup备份原理
- Cortex: 高可用和水平扩展Prometheus监控系统
- 从0开始聊聊自动化静态代码审计工具
- WebSphere XXE 漏洞分析(CVE-2020-4643)
- 专项行动的意外收获—— 2020 年 9 月墨子(Mozi)僵尸网络分析报告
- React 17.0.0-rc.2带来全新的JSX转换