前言
增删改查是后端最基本的技能。下面我就带领小伙伴们通过一个简单的示例来讲解SpringBoot的增删改查。Spring Boot框架层次从上至下可分为5层:分别为View层,Controller层,Service层,Mapper层,Model层
1. View层:视图根据接受到的数据最终展示页面给用户浏览,需要与Controller层结合起来使用
2. Controller层:负责具体的业务模块流程的控制,响应用户的请求,调用Service层的接口来控制业务流程,决定使用何种视图并准备响应数据,并把接收到的参数传给Mapper,调用Mapper的方法接口
3. Service层:主要负责业务模块的逻辑应用设计,同时有一些是关于数据库处理的操作,但是不是直接和底层数据库相关联,而是首先设计接口,再设计实现其中的类,在接口实现方法中需要导入Mapper层,接着在Spring的配置文件中配置其实现的关联,从而在应用中调用Service接口来进行业务处理
4. Mapper层:主要是做数据持久层的工作,同时提供增删改查工作,Mapper层也是首先设计接口,再设计实现其中的类,具体实现在mapper.xml文件中,然后就可以在模块中调用此接口来进行数据业务的处理
5. Model层:创建对象,包括构造器和get、set方法和toString方法
Controller层:沟通前后端,注解为@RestController
Service层:沟通Mapper层和Controller层,注解为@Service
Mapper层:沟通数据库和Service层,注解为@Repository
我们以一个简单的用户管理来讲解SpringBoot增删改查的实例
1. 创建数据库
首先创建数据库mydb,然后创建数据表,数据表创建语句如下:
create table if not exists user(id int unsigned not null auto_increment comment "用户ID",nickname varchar(32) not null comment "昵称",avater varchar(250) not null comment "头像",phone varchar(11) not null comment "手机号",create_time datetime not null comment "创建时间",update_time datetime not null comment "更新时间",state tinyint(1) default 1 comment "用户状态 1:正常;0:禁用;默认:1"primary key(id)
)ENGINE=innodb DEFAULT CHARSET=utf8insert into user values(1,"老舅妈撸代码","https://profile-avatar.csdnimg.cn/b4a1fe618b454834b630acdebf8a29a9_qq_41765777.jpg","17861857725","2023-09-22 15:53:12",null,1);
insert into user values(2,"快乐的老田","https://profile-avatar.csdnimg.cn/fe6a31a2c2a340f492494ebe9c15f638_lvrouhuosha1o.jpg","15069987814","2023-09-22 16:02:12",null,1);
2. 创建项目,安装所需依赖(包括Swagger)
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 https://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.7.17-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>11</java.version></properties><dependencies><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.3.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></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><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>2.3.1</version><scope>test</scope></dependency><!-- Swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><!-- Swagger-UI --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories><pluginRepositories><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></pluginRepository><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></pluginRepository></pluginRepositories></project>
3. 配置数据库连接,配置SpringBoot
配置/main/resources/application.properties文件
#端口号配置
server.port=9099#数据源相关配置
spring.datasource.url=jdbc:mysql://localhost:3306/finshing?serverTimezone=UTC&&characterEncoding=UTF-8&allowMultiQueries=true
spring.datasource.password=123456
spring.datasource.username=root#mybatis映射对应的实体类位置
mybatis.type-aliases-package=com.example.demo.entity#mybatis的映射xml文件路径位置
mybatis.mapper-locations=classpath:/mapper/*Mapper.xml#开启数据库下划线映射Java驼峰
mybatis.configuration.map-underscore-to-camel-case: truespring.mvc.view.prefix=/pages/
spring.mvc.view.suffix=.htmlspring.mvc.pathmatch.matching-strategy = ant_path_matcher# 配置上传文件大小限制
# 单个文件大小配置
spring.servlet.multipart.maxFileSize=30MB
# 请求总大小配置
spring.http.multipart.maxRequestSize = 30MB
4. 配置Swagger接口文档
添加src/main/java/com/example/demo/configclass/SwaggerConfig.java文件,配置Swagger,配置成功后访问:localhost:9099/swagger-ui.html即可访问swagger接口说明文档
package com.example.demo.configclass;import com.google.common.reflect.Parameter;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2) // DocumentationType.SWAGGER_2 固定的,代表swagger2
// .groupName("分布式任务系统") // 如果配置多个文档的时候,那么需要配置groupName来分组标识.apiInfo(apiInfo()) // 用于生成API信息.select() // select()函数返回一个ApiSelectorBuilder实例,用来控制接口被swagger做成文档.apis(RequestHandlerSelectors.basePackage("com.example.demo.controller")) // 用于指定扫描哪个包下的接口.paths(PathSelectors.any())// 选择所有的API,如果你想只为部分API生成文档,可以配置这里.build().globalOperationParameters(Arrays.asList(new ParameterBuilder().name("Token").description("Token验证").modelRef(new ModelRef("string")).parameterType("header").required(false).build()// ,// new ParameterBuilder()// .name("X-Custom-Header")// .description("Custom header")// .modelRef(new ModelRef("string"))// .parameterType("header")// .required(false)// .build()));}/*** 用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本* @return*/private ApiInfo apiInfo() {return new ApiInfoBuilder().title("XX项目API") // 可以用来自定义API的主标题.description("XX项目SwaggerAPI管理") // 可以用来描述整体的API.termsOfServiceUrl("") // 用于定义服务的域名.version("1.0") // 可以用来定义版本。.build(); //}}
5. 封装返回结果工具类
src/main/java/com/example/demo/utils/ResultUtil.java,在utils目录下创建ResultUtil.java工具类,用于对返回结果的封装。
{
code: 200,
msg:"操作成功",
data:[ ], // 或者{ }、number、nul、string、boolean
}
package com.example.demo.utils;import lombok.Data;/*** @author yeqc* @date 2022/3/28 21:54*/
@Data
public class ResultUtil<T> {public static final Integer SUCCESS_CODE = 200;public static final Integer FAIL_CODE = 4000;public static final String SUCCESS_MESSAGE = "操作成功";public static final String FAIL_MESSAGE = "操作失败";/*** 返回状态码*/private Integer code;/*** 返回信息*/private String message;/*** 返回数据*/private T data;private int count;private ResultUtil() {}public static <T> ResultUtil<T> success() {ResultUtil<T> resultUtil = new ResultUtil<>();resultUtil.setCode(SUCCESS_CODE);resultUtil.setMessage(SUCCESS_MESSAGE);return resultUtil;}public static <T> ResultUtil<T> success(T data) {ResultUtil<T> resultUtil = success();resultUtil.setData(data);return resultUtil;}public static <T> ResultUtil<T> success(String message, T data) {ResultUtil<T> resultUtil = success();resultUtil.setMessage(message);resultUtil.setData(data);return resultUtil;}public static <T> ResultUtil<T> success(Integer code, String message, T data) {ResultUtil<T> resultUtil = new ResultUtil<>();resultUtil.setCode(code);resultUtil.setMessage(message);resultUtil.setData(data);return resultUtil;}public static <T> ResultUtil<T> success(Integer code, String message,Integer count, T data) {ResultUtil<T> resultUtil = new ResultUtil<>();resultUtil.setCode(code);resultUtil.setMessage(message);resultUtil.setCount(count);resultUtil.setData(data);return resultUtil;}public static <T> ResultUtil<T> fail() {ResultUtil<T> resultUtil = new ResultUtil<>();resultUtil.setCode(FAIL_CODE);resultUtil.setMessage(FAIL_MESSAGE);return resultUtil;}public static <T> ResultUtil<T> fail(T data) {ResultUtil<T> resultUtil = fail();resultUtil.setData(data);return resultUtil;}public static <T> ResultUtil<T> fail(String message, T data) {ResultUtil<T> resultUtil = fail();resultUtil.setMessage(message);resultUtil.setData(data);return resultUtil;}public static <T> ResultUtil<T> fail(Integer code, String message) {ResultUtil<T> resultUtil = fail();resultUtil.setCode(code);resultUtil.setMessage(message);return resultUtil;}public static <T> ResultUtil<T> fail(Integer code, String message, T data) {ResultUtil<T> resultUtil = new ResultUtil<>();resultUtil.setCode(code);resultUtil.setMessage(message);resultUtil.setData(data);return resultUtil;}public void setCode(int code){this.code = code;}public int getCode(){return this.code;}public void setMessage(String message){this.message = message;}public String getMessage(){return message;}public void setData(T data){this.data = data;}public T getData(){return data;}public void setCount(int count){this.count = count;}public int getCount(){return count;}
}
6. 创建Controller控制器
package com.example.demo.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;import com.example.demo.entity.User;
import com.example.demo.service.serviceImpl.UserServiceImpl;
import java.util.List;import com.example.demo.utils.ResultUtil;@Api(tags = "人员相关操作")
@RestController
@RequestMapping("/user")
public class UserController {@AutowiredUserServiceImpl userServiceImpl;// 获取用户列表@ApiOperation(value = "获取用户列表")@GetMapping("/list")public ResultUtil<List<User>> list(){return ResultUtil.success(userServiceImpl.list());}// 获取用户信息@ApiOperation(value = "获取用户信息")@GetMapping("/info")public ResultUtil<User> info(@RequestParam int id){return ResultUtil.success(userServiceImpl.info(id));}// 添加用户@ApiOperation(value = "添加用户")@PostMapping("/add") public ResultUtil<String> add(@RequestBody User user){if(userServiceImpl.add(user) == 1){return ResultUtil.success("操作成功");}else{return ResultUtil.fail("操作失败");}}// 编辑用户@ApiOperation(value = "编辑用户")@PostMapping("/update")public ResultUtil<String> update(@RequestBody User user){if(userServiceImpl.update(user) == 1){return ResultUtil.success("操作成功");}else{return ResultUtil.fail("操作失败");}}// 删除用户@ApiOperation(value = "删除用户")@PostMapping("/delete")public ResultUtil<String> delete(@RequestBody int[] ids){userServiceImpl.delete(ids);return ResultUtil.success("操作成功");}// 关注用户@ApiOperation(value = "关注用户")@PostMapping("/forward")public String forward(){return "/user/forward";}
}
7. 创建Service层
创建service接口类,src/main/java/com/example/demo/service/UserService.java
package com.example.demo.service;import com.example.demo.entity.User;
import java.util.List;public interface UserService {// 列表List<User> list();// 信息User info(int id);// 新增用户int add(User user);// 更新int update(User user);// 删除void delete(int[] ids);
}
创建service接口实现类,src/main/java/com/example/demo/service/serviceImpl/UserServiceImpl.java
package com.example.demo.service.serviceImpl;import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.mapper.UserMapper;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import java.util.List;@Service
@Component
public class UserServiceImpl implements UserService{@AutowiredUserMapper userMapper;@Override public List<User> list(){return userMapper.list();}@Overridepublic User info(int id){return userMapper.info(id);}@Overridepublic int add(User user){return userMapper.add(user);}@Overridepublic int update(User user){return userMapper.update(user);}@Overridepublic void delete(int[] ids){userMapper.delete(ids);}
}
8. 创建Mapper
创建Mapper接口类,src/main/java/com/example/demo/mapper/UserMapper.java
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
import java.util.List;@Mapper
@Component
public interface UserMapper {// 列表List<User> list();// 信息User info(int id);// 添加int add(User user); // 更新int update(User user);// 删除void delete(int[] ids);
}
创建MapperXML文件类,src/main/resources/mapper/UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><!-- 获取单个人信息 --><select id="info" parameterType="Integer" resultType="User">select * from user where id = #{id}</select><!-- 获取列表信息 --><select id="list" resultType="User">select * from user</select><!-- 删除 --><delete id="delete">delete from user where id in<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach></delete><!-- 添加 --><insert id="add" useGeneratedKeys="true" keyProperty="id">insert into user(id,nickname,phone,avater,create_time,update_time,state)values(#{id},#{nickname},#{phone},#{avater},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP},#{state})</insert><!-- 更新 --><update id="update" useGeneratedKeys="true" keyProperty="id">update user<set>nickname = #{nickname},phone = #{phone},avater = #{avater},create_time = #{createTime},update_time = #{updateTime},state = #{state},</set>where id = #{id}</update>
</mapper>