前端开发视角 入门springboot

> 本文章适合前端人员并且对java一直不了解甚至听到java就恐惧的前端开发人员。在前端开发很少接触后端语言,即使接触也是node一类的框架express、koa2。

> 本文就类比着前端项目来入门springboot开发。

**文章目标:**

- 对比springboot项目结构和vue-cli项目结构【大致类比,不用深究】,不论会不会java基础,按照前端开发项目的思维,一步一步也可把功能实现

- 使用springboot写一个可以供前端调通的Restful接口

- 使用springboot结合mybatis-plus连通数据库,实现动态接口

**文章中使用IntelliJ IDEA初始化创建工程,使用springboot2.7版本。**

# SpringBoot介绍

SpringBoot是用java编写javaEE企业级别后端开发框架,类似与前端中的react、vue是使用javascript编写的前端开发框架。

## 使用IDEA初始化创建工程

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673062413304-2161adeb-47c4-418f-bd67-1fa3a97920b2.png#averageHue=%233f4245&clientId=ud458621a-3226-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=629&id=u77ef1703&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1258&originWidth=1578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=242767&status=done&style=none&taskId=u9497a01e-8840-4389-9fad-fd1a739f138&title=&width=789)

点击next,选择springboot的版本。

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673062699112-2bc9266b-9ef7-4d20-b3c3-a8ee62af5cdc.png#averageHue=%233e4144&clientId=ud458621a-3226-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=627&id=ua394b469&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1254&originWidth=1586&originalType=binary&ratio=1&rotation=0&showTitle=false&size=223182&status=done&style=none&taskId=ua3f29401-6caa-4ac5-b264-8dbb64d5d07&title=&width=793)

dependencies这个单词是不是在package.json中也存在,是的,在springboot中也是通过添加已经存在的第三方包来快速完成业务需求的开发的。

类似上面选择的Lombok,就是可以快速注解到类上,快速实现getter/setter、以及构造器的实现、日志输出等。

点击create,完成项目的创建。

## 分析初始化的项目结构

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673063723407-eddee850-8247-4607-b616-b08b616dbf48.png#averageHue=%234d564d&clientId=ud458621a-3226-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=731&id=ub1a22497&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1462&originWidth=2876&originalType=binary&ratio=1&rotation=0&showTitle=false&size=485402&status=done&style=none&taskId=u853a65b1-a6a8-4db2-bdf7-abd66d8c039&title=&width=1438)

- 从左侧src开始看

- 下面分为main主要存储项目代码,test用来写测试用例

- main中有分为java和resources。

- java就是存放项目的主要核心java源文件,等同在前端vue-cli中src下的view文件。

- java下的HelloApplication文件,类似前端的main.js入口文件

- resources文件用来存放静态文件,类似前端public目录,在项目中可以直接获取到绝对路径

- pom.xml文件就等同与前端的package.json文件,可以查看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 " target="_blank">https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<!-- parent是 创建项目时选择的springboot版本信息 -->

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.7.7</version>

<relativePath/>

</parent>

<!-- 下面2项是初始化项目填写的项目名,也可进行修改 -->

<groupId>com.learnspringboot</groupId>

<artifactId>hello</artifactId>

<!-- 下面3项对项目的描述,简单工程中,可有可无 -->

<version>0.0.1-SNAPSHOT</version>

<name>hello</name>

<description>hello</description>

<!-- 设置java的版本 -->

<properties>

<java.version>1.8</java.version>

</properties>

<!-- 添加的依赖 -->

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

</dependencies>

<!-- 添加的maven插件,用来构建项目,类似vue-cli中的devDependencies -->

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>

```

> 依赖:运行时开发时都需要用到的包,比如项目中需要一个包,就要添加一个依赖,这个依赖在项目运行时也需要,因此在项目打包时需要把这些依赖也打包进项目里;

> 插件:在项目开的发时需要,但是在项目运行时不需要,因此在项目开发完成后不需要把插件打包进项目中,比如有个可以自动生成getter和setter的插件,嗯对~这就是插件了,因为这玩意在编译时生成getter和setter,编译结束后就没用了,所以项目打包时并不需要把插件放进去~

- 右侧查看maven菜单,可以看到添加的依赖和插件。在pom.xml中添加新的依赖后,可以自己加载更新,也可以点击上边的三个图标进行更新。Lifecycle可以对项目进行包的安装install、清理clean、打包package、编译compile等操作,执行过命令后可以在左侧target目录下看到变化。例如执行了打包命令,会生成一个hello-0.0.1-SNAPSHOT.jar包。执行clean,会清理掉target中的所有文件。

总结:

| **springboot中** | **vue-cli中** |

| --- | --- |

| pom.xml | package.json |

| src/main/java | src/view |

| src/main/HelloApplication.java | src/main.js |

| src/main/resources | public 或者 src/assets |

| pom中的依赖 | package.json中的依赖 |

| pom中的插件 | package.json中的开发依赖 |

# 编写第一个Restful接口

认识完项目结构,接下来添加第一个restful接口。在后端开发中把工程会划分为controller、service、dao、config、vo、mapper等结构,这些只是为了约定规范,~~这些名字也可自己定,除非这个项目是自己开发~~。开发中还是最好要按照约定的来,方便自己方便大家。

| controller | 用于编写Web层相关的实现,供前端可以调用的接口定义 | 类似前端中的router |

| --- | --- | --- |

| service | 实现具体的业务逻辑,创建一些方法,供controller中调用 | 前端中的核心业务处理代码 |

| config | 添加一些插件的配置、或者其他拦截器配置 | config配置 |

| dao | 处理和数据库数据的映射 | 约定的数据结构 |

| vo | 用于定义一些供前端显示的数据结构,如返回数据resultJson结构 | 约定的数据结构 |

| mapper | 用来实现一些处理数据库查询的方法,供service调用 | 前端中的vuex数据源 |

![](https://cdn.nlark.com/yuque/0/2023/jpeg/737887/1673073270647-378a359e-5253-4ddd-bf17-b43d9ff3fb45.jpeg)

## 添加web依赖

修改pom.xml文件

```xml

<!-- 添加web开发的依赖 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

```

添加完成后,刷新maven下

## 创建controller

添加controller目录,添加UserController文件

```java

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("user")

public class UserService {

@GetMapping("hello")

public String hello(){

return "hello spring boot!";

}

}

```

然后进入HelloApplication启动项目,点击左侧图标或者右键执行Run "HelloApplication"

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673070837382-b1db7279-e1be-4a7a-9ad2-073fc18aff2c.png#averageHue=%23565d4e&clientId=u9d2d7bcc-2541-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=223&id=u0731f277&margin=%5Bobject%20Object%5D&name=image.png&originHeight=446&originWidth=1190&originalType=binary&ratio=1&rotation=0&showTitle=false&size=96104&status=done&style=none&taskId=u172ce208-2843-4214-a332-f1b74894918&title=&width=595)

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673070938903-7a335173-2a3a-4f49-b64f-69a96d9c5e4d.png#averageHue=%233e4042&clientId=u9d2d7bcc-2541-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=319&id=uec401d90&margin=%5Bobject%20Object%5D&name=image.png&originHeight=638&originWidth=834&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93776&status=done&style=none&taskId=ub93f4244-9a77-451d-9c0a-e5fb227827d&title=&width=417)

项目启动成功后,可以看到默认启动端口8080

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673071575810-3511fe96-38a9-4312-962a-ef73b76dd7cb.png#averageHue=%23343232&clientId=u9d2d7bcc-2541-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=298&id=u88b65c67&margin=%5Bobject%20Object%5D&name=image.png&originHeight=596&originWidth=2712&originalType=binary&ratio=1&rotation=0&showTitle=false&size=247104&status=done&style=none&taskId=uf8537d25-89f7-4240-b765-7fe627edda6&title=&width=1356)

接下来前端就可访问 [http://localhost:8080/user/hello](http://localhost:8080/user/hello),在页面中看到hello spring boot!,完成了第一个接口的开发。

## 设置返回json的数据格式

前后的分离开发,最常用的数据交互方式是json,接口返回的基本上都是json的格式。

### 在vo目录下创建ResultJson类

resultJson类定义返回给前端使用的json结果格式。

```java

import lombok.Data;

@Data // 此处的Data就是Lombok中的

public class ResultJson {

private boolean success;

private int code;

private String message;

private Object data;

}

```

### 在controller中添加json请求的处理

```java

@GetMapping("json")

public ResultJson retJson(){

ResultJson resultJson = new ResultJson();

resultJson.setCode(200);

resultJson.setMessage("接口调用成功");

resultJson.setData("hello spring boot!");

resultJson.setSuccess(true);

return resultJson;

}

```

接下来前端访问路径[http://localhost:8080/user/json](http://localhost:8080/user/json)就可以返回

```json

{

"success": true,

"code": 200,

"message": "接口调用成功",

"data": "hello spring boot!"

}

```

这样的数据结果对于前端是不是特别熟悉呢。

### 设置返回的data是list结构

#### 在pojo目录下定义一个User类

```java

@Data

public class User {

private Long id;

private String name;

private Integer age;

private String email;

public User(Long id, String name, Integer age, String email) {

this.id = id;

this.name = name;

this.email = email;

this.age = age;

}

}

```

#### 在controller中添加list接口的访问

```java

@GetMapping("list")

public ResultJson UserList(){

ResultJson resultJson = new ResultJson();

List<User> userList = new ArrayList<>();

User user1 = new User(1L, "aaa", 12, "aaa@qq.com");

User user2 = new User(2L, "bbb", 13, "bbb@qq.com");

userList.add(user1);

userList.add(user2);

resultJson.setData(userList);

resultJson.setCode(200);

resultJson.setMessage("userList");

return resultJson;

}

```

前端访问路径[http://localhost:8080/user/list](http://localhost:8080/user/list),返回的数据结构如下

```json

{

"success": false,

"code": 200,

"message": "userList",

"data": [

{

"id": 1,

"name": "aaa",

"age": 12,

"email": "aaa@qq.com"

},

{

"id": 2,

"name": "bbb",

"age": 13,

"email": "bbb@qq.com"

}

]

}

```

# 添加mybatis-plus插件,实现动态接口

以上接口返回的数据都是静态的mock数据,后端开发少不了连接数据库,进行动态数据查询。接下来使用mybatis-plus实现动态数据查询

## 在pom添加依赖

```xml

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>8.0.31</version>

</dependency>

<dependency>

<groupId>com.baomidou</groupId>

<artifactId>mybatis-plus-boot-starter</artifactId>

<version>3.4.3</version>

</dependency>

```

**在application.properties中添加配置**

```xml

# 连接数据库的基础配置

spring.datasource.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimeZone=UTC

spring.datasource.username=root

spring.datasource.password=12345678

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

```

## 创建数据库表

### 创建user表

```plsql

create table if not exists springdb.user

(

id bigint auto_increment comment '主键ID'

primary key,

name varchar(30) null comment '姓名',

age int null comment '年龄',

email varchar(50) null comment '邮箱'

)

collate = utf8_unicode_ci;

```

### 插入数据

```plsql

INSERT INTO springdb.user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@myspring.com');

INSERT INTO springdb.user (id, name, age, email) VALUES (2, 'Jack', 20, 'test2@myspring.com');

INSERT INTO springdb.user (id, name, age, email) VALUES (3, 'Tom', 28, 'test3@myspring.com');

INSERT INTO springdb.user (id, name, age, email) VALUES (4, 'Sandy', 21, 'test4@myspring.com');

INSERT INTO springdb.user (id, name, age, email) VALUES (5, 'Billie', 24, 'test5@myspring.com');

```

## 添加config目录,设置MybatisPlusConfig.java类

```java

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;

import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class MybatisPlusConfig {

//分页插件

@Bean

public MybatisPlusInterceptor mybatisPlusInterceptor(){

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

interceptor.addInnerInterceptor(new PaginationInnerInterceptor());

return interceptor;

}

}

```

### 使用mybatis的api查询数据

![](https://cdn.nlark.com/yuque/0/2023/jpeg/737887/1673074372691-405bf753-b8df-4f3c-8e8a-448047611a21.jpeg)

### 在mapper目录下定义UserMapper

```java

@Mapper

@Repository

public interface UserMapper extends BaseMapper<User> {

}

```

### 设置service的处理方法

```java

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.myspringboot.first.mapper.UserMapper;

import com.myspringboot.first.pojo.User;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

@Slf4j

public class UserService {

// userMapper实现自BaseMapper,所有拥有Mybatis的API方法

@Autowired

private UserMapper userMapper;

// 查询所有的user

public List<User> findAll(){

// LambdaQueryWrapper为mybatisplus中的类

return userMapper.selectList(new LambdaQueryWrapper<>());

}

public List<User> findPage(int page, int size){

Page<User> upage = new Page<User>(page, size);

Page<User> userPage = userMapper.selectPage(upage, new LambdaQueryWrapper<>());

log.info("total", userPage.getTotal());

log.info("pages", userPage.getPages());

return userPage.getRecords();

}

}

```

[Mybatis-plus的API](https://baomidou.com/pages/10c804/#abstractwrapper),以上查询完成全部依赖mybatis的Api

### 修改UserController,添加findAll和findPage接口

```java

@GetMapping("findAll")

public List<User> findAll(){

return userService.findAll();

}

@GetMapping("findPage")

public List<User> findPage(@RequestParam("page") Integer page,

@RequestParam("size") Integer size){

return userService.findPage(page, size);

}

```

设置完成后,重启项目。

前端就可以访问[http://localhost:8080/user/findAll](http://localhost:8080/user/findAll),和http://localhost:8080/user/findPage?page=1&size=2

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673075382578-9a64452d-b03e-4c8d-bffb-91f2320d829c.png#averageHue=%23fcfcfc&clientId=u9d2d7bcc-2541-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=734&id=ue4e08eb0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1468&originWidth=1258&originalType=binary&ratio=1&rotation=0&showTitle=false&size=192241&status=done&style=none&taskId=u7dd1f4bc-02a9-4518-9a9c-4230e78f1a9&title=&width=629)

![image.png](https://cdn.nlark.com/yuque/0/2023/png/737887/1673075366859-5553e72c-4408-4698-a52a-b94904bbd4b5.png#averageHue=%23fbfbfb&clientId=u9d2d7bcc-2541-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u3ecd2aca&margin=%5Bobject%20Object%5D&name=image.png&originHeight=790&originWidth=1260&originalType=binary&ratio=1&rotation=0&showTitle=false&size=112562&status=done&style=none&taskId=ua93c3dcf-cea8-441e-9702-a2498e806a9&title=&width=630)

返回的是数据库中对应的数据。

## 设置自定义的mapper查询数据

> mybatis只能完成单表查询,如果有关联表查询,就需要自定义mapper中的方法通过编写sql进行实现。

业务场景:查询出age大于18的user,新加advanceSearch接口。示例仍然是单表查询,只是为了测试

### 首先在MybatisPlusConfig类设置mapper扫描路径

### 添加@MapperScan注解

```java

@Configuration

@MapperScan("com.learnspringboot.hello.mapper")

public class MybatisPlusConfig {

//分页插件

@Bean

public MybatisPlusInterceptor mybatisPlusInterceptor(){

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

interceptor.addInnerInterceptor(new PaginationInnerInterceptor());

return interceptor;

}

}

```

### 在pom和application中设置mapper的访问路径

```xml

<build>

<resources>

<resource>

<!-- xml放在java目录下-->

<directory>src/main/java</directory>

<includes>

<include>**/*.xml</include>

</includes>

</resource>

<!--指定资源的位置(xml放在resources下,可以不用指定)-->

<resource>

<directory>src/main/resources</directory>

</resource>

</resources>

</build>

```

### 设置application.properties

```java

#mybatis-plus 配置

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

mybatis-plus.mapper-locations=classpath*:mapper/*.xml

```

### 在UserMapper中添加advanceSearch接口

```java

@Mapper

@Repository

public interface UserMapper extends BaseMapper<User> {

List<User> advanceSearch();

}

```

### 然后在resources中添加mapper目录

> IDEA添加一下![image.png](https://cdn.nlark.com/yuque/0/2022/png/737887/1672458182890-ac89254b-1acf-4215-b716-a85c73b6cd30.png#averageHue=%2335383b&clientId=uf65591cf-7880-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=91&id=ua57e1e0d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=182&originWidth=732&originalType=binary&ratio=1&rotation=0&showTitle=false&size=21599&status=done&style=none&taskId=u2322fdb8-bba9-4a1e-bf16-62c7b3ef0d5&title=&width=366)插件,这样会把mapper接口中定义的方法和xml中方法的实现进行一个关联。

> ![image.png](https://cdn.nlark.com/yuque/0/2022/png/737887/1672458236733-380502f2-d293-4a50-b5ae-c4ea6f0012d5.png#averageHue=%23998044&clientId=uf65591cf-7880-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=146&id=ua0fef5ca&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=482&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32463&status=done&style=none&taskId=u2f6df3ad-9dce-40c2-bc07-09a9552e5b2&title=&width=241)![image.png](https://cdn.nlark.com/yuque/0/2022/png/737887/1672458255390-4c6cebed-4e9d-49fa-bcd3-e9f6064bd503.png#averageHue=%233d3631&clientId=uf65591cf-7880-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=145&id=u8a2ba2cc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=324&originWidth=666&originalType=binary&ratio=1&rotation=0&showTitle=false&size=50078&status=done&style=none&taskId=ub3918889-c35c-485b-a516-6500eed94c2&title=&width=299)

#### 添加UserMapper.xml文件,处理advanceSearch接口的实现

```xml

<?xml version="1.0" encoding="UTF-8" ?>

<!--MyBatis配置文件-->

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "" target="_blank">http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.learnspringboot.hello.mapper.UserMapper">

<!-- advanceSearch -->

<select id="advanceSearch" resultType="com.learnspringboot.hello.pojo.User">

select id, name, age, email from user where age > 18;

</select>

</mapper>

```

### 在service中进行调用

```java

public List<User> advanceSearch(){

return userMapper.advanceSearch();

}

```

### 在controller中进行设置访问路径

```java

@GetMapping("advanceSearch")

public List<User> advanceSearch(){

return userService.advanceSearch();

}

```

然后前端就可以访问[http://localhost:8080/user/advanceSearch](http://localhost:8080/user/advanceSearch)

```json

[

{

"id": 2,

"name": "Jack",

"age": 20,

"email": "test2@myspring.com"

},

{

"id": 3,

"name": "Tom",

"age": 28,

"email": "test3@myspring.com"

},

{

"id": 4,

"name": "Sandy",

"age": 21,

"email": "test4@myspring.com"

},

{

"id": 5,

"name": "Billie",

"age": 24,

"email": "test5@myspring.com"

}

]

```

# 总结:

- pom和package结构类似

- controller和router结构类似

- service定义核心业务逻辑处理

- dao、vo、pojo等定义数据,类似前端的vuex数据结构处理

项目代码:[https://gitee.com/shenshuai89/springboothello.git](https://gitee.com/shenshuai89/springboothello.git)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值