写在最前面
用了10年+的 PHP 从原生到 ThinkPHP 又到 Laravel 真的很方便。
为了突破自己跳出舒适圈,决定从现在开始学习 Spring Boot 做后端。
至于为什么用 VSCode 而不是 IEDA ? 因为已经很熟悉 VSC 的界面和操作逻辑,等实在觉得 IEDA 很方便的时候再换坑吧,哈哈哈~~~
VSCode 搭建环境
Extension Pack for Java 和 Spring Boot Extension Pack 大礼包装就完事。
VSCode 新建项目
你可以在线 https://start.spring.io/ 配置项目。
当然我这里用的是 VSCode 自然编辑器里也可以直接配置。
初始依赖包
-
F1输入Spring Initializr:Crate a Maven Project肥册 -
依赖包选择,先安装
Spring Boot DevTools和Spring Web -
之后如果要追加依赖包,可以通过
https://mvnrepository.com/查询追加到pom.xml的<dependencies>内部,也可以通过VSCode里的MAVEN工具栏搜索选择后自动添加如下图。
Hello World
src\main\java\com\example\juejin新建目录controller新建文件IndexController.javapackage com.example.juejin.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @RequestMapping("/") public String index(){ return "Hello World"; } }- 右上角点击
Run Java运行,或者安装插件Spring Boot Dashboard来运行 - 浏览器输入
http://localhost:8080后Hello World粗线了! - 默认 8080 可以在
src\main\resources\application.properties修改server.port=8080
连接数据库
一. 安装依赖包
二. 配置数据库信息
在 src\main\resources\application.properties 追加
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/spring_boot_juejin?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql = true
如果
MySQL Connector Java安装的是 8.xMySQL的版本也必须是 8.x 的
三. 数据返回JSON格式
- 实体类 在
src\main\java\com\example\juejin新建目录domain新建文件Users.java和数据库表名一致,内部的属性名字和字段名保持一致。package com.example.juejin.domain; import javax.persistence.Entity; import javax.persistence.Id; import lombok.Data; @Entity @Data public class Users { @Id private Integer id; private String name; private Integer age; private String email; } - 操作数据库类 在
src\main\java\com\example\juejin新建目录dao新建文件UsersRepository.java这里文件名不强制和数据库表一致,只是强迫症。package com.example.juejin.dao; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import com.example.juejin.domain.Users; public interface UsersRepository extends JpaRepository<Users, Integer> { @Query(value = "SELECT * FROM users", nativeQuery = true) List<Users> getAll(); } src\main\java\com\example\juejin\controller\IndexController.java完整版package com.example.juejin.controller; import java.util.List; import javax.annotation.Resource; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.juejin.dao.UsersRepository; import com.example.juejin.domain.Users; @RestController public class IndexController { @RequestMapping("/") public String index(){ return "Hello World"; } @Resource private UsersRepository usersRepository; @RequestMapping("/users") public List<Users> getUsers(){ return usersRepository.getAll(); } }- 浏览器输入
http://localhost:8080/users后JSON数据粗线了!
连接数据库(简约版)
使用了 MyBatis 更加方便!
一. 安装依赖包
二. 配置数据库信息
在 src\main\resources\application.properties 追加
spring.datasource.url = jdbc:mysql://localhost:3306/spring_boot_juejin?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = root
如果
MySQL Connector Java安装的是 8.xMySQL的版本也必须是 8.x 的
三. 数据返回JSON格式
- 【实体类对应数据库表】定义
entity包,在src\main\java\com\example\juejin新建目录entity新建文件Users.java和数据库表名一致,内部的属性名字和字段名保持一致。package com.example.juejin.entity; import lombok.Data; @Data public class Users { private Integer id; private String name; private Integer age; private String email; } - 【接口操作数据库】定义
mapper包,在src\main\java\com\example\juejin新建目录mapper新建文件UsersMapper.java这里文件名不强制和数据库表一致,只是强迫症。package com.example.juejin.mapper; import java.util.List; import org.apache.ibatis.annotations.Select; import com.example.juejin.entity.Users; public interface UsersMapper { @Select("SELECT * FROM users") List<Users> findAll(); } - 【配置启动MyBatis】在
demoApplication添加@MapperScan("com.example.juejin.mapper")package com.example.juejin; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.example.juejin.mapper") public class JuejinApplication { public static void main(String[] args) { SpringApplication.run(JuejinApplication.class, args); } } - 【控制器】
src\main\java\com\example\juejin\controller\UsersController.javapackage com.example.juejin.controller; import java.util.List; import javax.annotation.Resource; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.juejin.entity.Users; import com.example.juejin.mapper.UsersMapper; @RestController @RequestMapping("/users") public class UsersController { @Resource UsersMapper usersMapper; @GetMapping public List<Users> getUsers(){ return usersMapper.findAll(); } } - 浏览器输入
http://localhost:8080/users后JSON数据粗线了!
增删改查(入门版)
只是简单实现 CRUD 功能,比如删除和修改功能没有做成功与否判断。
- 【接口操作数据库】
src\main\java\com\example\juejin\mapper\UsersMapper.javapackage com.example.juejin.mapper; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import org.springframework.transaction.annotation.Transactional; import com.example.juejin.entity.Users; public interface UsersMapper { // 获取 users 表全部数据 @Select("SELECT * FROM `users`") List<Users> findAll(); // 查询 指定 id 数据 @Select("SELECT * FROM `users` WHERE `id` = #{id}") Users findById(Long id); // 添加 @Update("INSERT INTO `users` (`name`, `age`, `email`) VALUES (#{name}, #{age}, #{email});") @Transactional void save(Users user); // 删除 @Delete("DELETE FROM `users` WHERE `id` = #{id}") void deleteById(Long id); // 修改 @Update("UPDATE `users` SET `name` = #{name}, `age` = #{age}, `email` = #{email} WHERE `id` = #{id};") @Transactional void updateById(Users user); } - 【控制器】
src\main\java\com\example\juejin\controller\UsersController.javapackage com.example.juejin.controller; import java.util.List; import javax.annotation.Resource; import org.springframework.web.bind.annotation.DeleteMapping; 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.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.juejin.entity.Users; import com.example.juejin.mapper.UsersMapper; @RestController @RequestMapping("/users") public class UsersController { @Resource UsersMapper usersMapper; // 获取 users 表全部数据 @GetMapping public List<Users> getUsers(){ return usersMapper.findAll(); } // 查询 指定 id 数据 @GetMapping("/{id}") public Users findById(@PathVariable("id") Long id){ return usersMapper.findById(id); } // 添加 @PostMapping public String addUser(@RequestBody Users user) { usersMapper.save(user); return "添加成功"; } // 删除 @DeleteMapping("/{id}") public String deleteUser(@PathVariable("id") Long id) { usersMapper.deleteById(id); return "删除成功"; } // 修改 @PutMapping public String updateUser(@RequestBody Users user) { usersMapper.updateById(user); return "修改成功"; } }
连接数据库(MyBatis-Plus)
官方文档:baomidou.com
一. 安装 MyBatis-Plus (安装 MyBatis-Plus 就不需要安装 MyBatis 了,二者只安装一个。)
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
二. 配置文件 com\example\juejin\common\config\MybatisPlusConfig.java
package com.example.juejin.common.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
@Configuration
@MapperScan("com.example.juejin.mapper")
public class MybatisPlusConfig {
/**
* 分页插件 不配置数据不会分页
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
}
三. 数据库读取
- 【实体类对应数据库表】
com\example\juejin\entity\User.javapackage com.example.juejin.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @TableName("user") // MyBatis-Plus @Data public class User { @TableId(type = IdType.AUTO) // MyBatis-Plus private Integer id; private String username; private String password; private String nickName; private Integer age; private String sex; private String address; } - 【接口操作数据库】
com\example\juejin\mapper\UserMapper.javapackage com.example.juejin.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.juejin.entity.User; public interface UserMapper extends BaseMapper<User> { // MyBatis-Plus } - 添加自定义 【Result】 工具类
package com.example.juejin.common; public class Result<T> { private String code; private String msg; private T data; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } public Result() { } public Result(T data) { this.data = data; } public static Result<?> success() { Result<?> result = new Result<>(); result.setCode("0"); result.setMsg("成功"); return result; } public static <T> Result<T> success(T data) { Result<T> result = new Result<>(data); result.setCode("0"); result.setMsg("成功"); return result; } public static Result<?> error(String code, String msg) { Result<?> result = new Result<>(); result.setCode(code); result.setMsg(msg); return result; } }
增删改查
【控制器】com\example\juejin\controller\UsersController.java 通过 Result 返回状态
package com.example.juejin.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.juejin.common.Result;
import com.example.juejin.entity.User;
import com.example.juejin.mapper.UserMapper;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
UserMapper userMapper;
// 添加
@PostMapping
public Result<?> save(@RequestBody User user){
Integer res = userMapper.insert(user);
if(res != 1 ){
return Result.error("-1", "数据添加失败");
}
return Result.success(res);
}
// 删除
@DeleteMapping("/{id}")
public Result<?> delete(@PathVariable Long id){
Integer res = userMapper.deleteById(id); // 成功 data 返回 1
if(res == 0 ){
return Result.error("-1", "数据不存在");
}
return Result.success(res);
}
// 修改
@PutMapping
public Result<?> update(@RequestBody User user){
Integer res = userMapper.updateById(user); // 成功 data 返回 1
if(res == 0 ){
return Result.error("-1", "数据不存在");
}
return Result.success(user);
}
// 查询 user 表全部数据
@GetMapping
public Result<?> findAll(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "5") Integer pageSize){
Page<User> userPage = userMapper.selectPage(new Page<>(pageNum, pageSize),null); // 分页查询
// List<User> users = userMapper.selectList(null); // 查询全部记录
return Result.success(userPage);
}
// 查询 指定 id 数据
@GetMapping("/{id}")
public Result<?> findById(@PathVariable Long id){
User res = userMapper.selectById(id); // 成功 data 返回数据
if(res == null){
return Result.error("-1", "数据不存在");
}
return Result.success(res);
}
}
注册和登录
注册判断是否已存在
package com.example.juejin.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.juejin.common.Result;
import com.example.juejin.entity.User;
import com.example.juejin.mapper.UserMapper;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
UserMapper userMapper;
// 登录
@PostMapping("/login")
public Result<?> login(@RequestBody User user){
// 验证 username 和 password 是否匹配
User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()).eq(User::getPassword, user.getPassword()));
if(res == null){
return Result.error("-1", "用户名或密码错误");
}
return Result.success(res);
}
// 注册
@PostMapping("/register")
public Result<?> register(@RequestBody User user){
User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));// 判断 username 是否已存在
Integer res2 = userMapper.insert(user);
if(res != null){
return Result.error("-1", "用户名已存在");
}
if(res2 != 1 ){
return Result.error("-1", "数据添加失败");
}
return Result.success(res);
}
}
图片上传和读取
com\example\juejin\controller\FileController.java
package com.example.juejin.controller;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.example.juejin.common.Result;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
@RestController
@RequestMapping("/files")
public class FileController {
// 上传图片
@PostMapping("/upload")
public Result<?> upload(MultipartFile file) throws IOException{
String originalFilename = file.getOriginalFilename();
String uuid = IdUtil.fastSimpleUUID(); // hutool 需要重启
String rootFilePath = System.getProperty("user.dir") + "/src/main/resources/files/" + uuid + "_" + originalFilename;
FileUtil.writeBytes(file.getBytes(), rootFilePath); // hutool
return Result.success(uuid + "_" + originalFilename);
}
// 读取图片
@GetMapping("/{flag}")
public void getFiles(@PathVariable String flag, HttpServletResponse response) {
OutputStream os; // 新建一个输出流对象
String basePath = System.getProperty("user.dir") + "/src/main/resources/files/"; // 定于文件上传的根路径
List<String> fileNames = FileUtil.listFileNames(basePath); // 获取所有的文件名称
String fileName = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse(""); // 找到跟参数一致的文件
try {
if (StrUtil.isNotEmpty(fileName)) {
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
response.setContentType("application/octet-stream");
byte[] bytes = FileUtil.readBytes(basePath + fileName); // 通过文件的路径读取文件字节流
os = response.getOutputStream(); // 通过输出流返回文件
os.write(bytes);
os.flush();
os.close();
}
} catch (Exception e) {
System.out.println("文件下载失败");
}
}
}
本番部署
安装 Maven
- maven.apache.org/download.cg…
解压到
C:\apache-maven-3.8.6 - VSCode Maven for Java
配置
C:\apache-maven-3.8.6\bin\mvn
打包
MAVEN-clearMAVEN-compileMAVEN-package获得到juejin\target\***.jar
如果在打包中出现报错,点击
MAVEN右上角重新加载所有 MAVEN 项目按钮,再打包就不会报错了。
上传本番
持续更新