本文将从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
各组件版本信息如下:
构建工具是一个把源代码生成可执行应用程序的自动化工具,Java 领域中主要有三大构建工具:Ant、Maven 和 Gradle。
创建项目前,配置编码格式,这是一个容易忽略的点,IDEA 中,仍然依次打开 File -> Settings,搜索“Encoding”,配置本地的编码信息,如下图所示:
首先,打开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
创建好的项目结构如上图,可以看到自己创建了一些包,说下它们的作用:
resources 目录下:
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>
第三部分为构建时需要的公共变量:
<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 应用。
项目自动生成的配置文件是.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
上面项目结构图中,我们自行创建了很多层级,它们各自发挥作用,共同构成一个项目,下面分别详解一下各层级的作用。
这部分的作用是对外提供接口。一个标准的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格式的参数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层中的一个方法,我们去看一下里面有何玄机。
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);
}
启动类中没有太多内容,只有@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中的信息,去请求一下接口:
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', '缺货', '黑洞制造者');
下面附上完整的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>