MybatisPlus在Mybatis的基础上,只做增强,内置了关于单表的许多基础操作,让我们可以不在将时间放在那些基础的CRUD上,直接调用MybatisPlus提供的方法,大大减少了我们在开发过程中的低级代码量,使我们只需要将时间和精力放在一些复杂的多表联合查询上。下一篇我会写一个多表查询的增删改查!
直接从一个小demo开始
步骤:
1.建一个空的springboot项目(这里就不细说建项目了)
2.导依赖,写配置文件
依赖
<!-- web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
</dependency>
<!-- knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
application.yml配置文件:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver #驱动 username: root #用户名 password: 1234 #密码 url: jdbc:mysql://localhost:3306/management?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8 # mybatis-plus: global-config: db-config: logic-delete-field: deleted # 全局指定逻辑删除字段 logic-delete-value: 1 # 逻辑删除后的值 logic-not-delete-value: 0 # 没有删除的值 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 日志打印 mapper-locations: classpath*:mapper/*.xml # mapper.xml位置
3.建表
4.开始写代码,先从实体类开始
(为了方便,我的习惯是分别新建新增的类userSaveForm,批量删除的类UserDeleteForm,分页查找的类UserQuery,返回给前端数据的类UserVo)如下所示:
package com.example.management.domain.entity; import com.baomidou.mybatisplus.annotation.*; import com.example.management.groups.Add; import com.example.management.groups.Update; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import java.io.Serializable; import java.time.LocalDateTime; @Data @Builder @NoArgsConstructor @AllArgsConstructor @TableName("user") public class User { /** * 主键id */ @TableId(type = IdType.AUTO) private Long id; /** * 用户名 */ @TableField(value = "name") private String name; /** * 用户昵称 */ @TableField(value = "nickname") private String nickname; /** * 用户邮箱 */ @TableField(value = "email") private String email; /** * 用户电话 */ @TableField(value = "phone") private String phone; /** * 用户性别 */ @TableField(value = "gender") private String gender; /** * 用户密码 */ @TableField(value = "password") private String password; /** * 用户头像 */ @TableField(value = "head_portrait") private String headPortrait; /** * 用户状态 */ @TableField(value = "user_state") private String userState; /** * 创建时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(value = "create_time", fill = FieldFill.INSERT_UPDATE) private LocalDateTime createTime; /** * 修改时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; /** * 是否删除 0 未删除 1 已删除 */ @TableField(value = "deleted",fill = FieldFill.INSERT) private String deleted; }
package com.example.management.domain.form; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.example.management.groups.Add; import com.example.management.groups.Update; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.io.Serializable; import java.time.LocalDateTime; import java.util.List; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class UserSaveForm implements Serializable { private static final long serialVersionUID = 1L; /** * 主键id */ @NotNull(message = "id不能为空",groups = Update.class) private Long id; /** * 用户名 */ @NotBlank(message = "name不能为空", groups = {Update.class, Add.class}) private String name; /** * 用户昵称 */ @NotBlank(message = "nickname不能为空", groups = {Update.class, Add.class}) private String nickname; /** * 用户邮箱 */ @NotBlank(message = "email不能为空", groups = {Update.class, Add.class}) private String email; /** * 用户电话 */ @NotBlank(message = "phone不能为空", groups = {Update.class, Add.class}) private String phone; /** * 用户性别 */ @NotBlank(message = "gender不能为空", groups = {Update.class, Add.class}) private String gender; /** * 用户密码 */ @NotBlank(message = "password不能为空", groups = {Update.class, Add.class}) private String password; /** * 用户头像 */ @NotBlank(message = "headPortrait不能为空", groups = {Update.class, Add.class}) private String headPortrait; /** * 用户状态 */ @NotBlank(message = "userState不能为空", groups = {Update.class, Add.class}) private String userState; }
package com.example.management.domain.form; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import java.util.List; @Data public class UserDeleteForm { @NotEmpty(message = "id不能为空") private List<Long> ids; }
package com.example.management.domain.query; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.example.management.groups.Add; import com.example.management.groups.Update; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.io.Serializable; import java.time.LocalDateTime; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class UserQuery implements Serializable{ private static final long serialVersionUID = 1L; /** * 分页参数 */ private Integer page = 1; private Integer pageSize = 10; /** * 用户名 */ @NotBlank(message = "name不能为空", groups = {Update.class, Add.class}) private String name; /** * 用户昵称 */ @NotBlank(message = "nickname不能为空", groups = {Update.class, Add.class}) private String nickname; /** * 用户邮箱 */ @NotBlank(message = "email不能为空", groups = {Update.class, Add.class}) private String email; /** * 用户电话 */ @NotBlank(message = "phone不能为空", groups = {Update.class, Add.class}) private String phone; /** * 用户性别 */ @NotBlank(message = "gender不能为空", groups = {Update.class, Add.class}) private String gender; /** * 用户密码 */ @NotBlank(message = "password不能为空", groups = {Update.class, Add.class}) private String password; /** * 用户头像 */ @NotBlank(message = "headPortrait不能为空", groups = {Update.class, Add.class}) private String headPortrait; /** * 用户状态 */ @NotBlank(message = "userState不能为空", groups = {Update.class, Add.class}) private String userState; /** * 开始时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime startTime; /** * 结束时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime endTime; }
package com.example.management.domain.vo; import com.baomidou.mybatisplus.annotation.*; import com.example.management.groups.Add; import com.example.management.groups.Update; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.io.Serializable; import java.time.LocalDateTime; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class UserVo implements Serializable { private static final long serialVersionUID = 1L; /** * 主键id */ private Long id; /** * 用户名 */ private String name; /** * 用户昵称 */ private String nickname; /** * 用户邮箱 */ private String email; /** * 用户电话 */ private String phone; /** * 用户性别 */ private String gender; /** * 用户密码 */ private String password; /** * 用户头像 */ private String headPortrait; /** * 用户状态 */ private String userState; }
5关于自定义返回值的工具类和分页查询的配置如下:
package com.example.management.util;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
private int code;
private String message;
private T data;
private Long total;
private List records;
public Result(T data) {
this.code = 200;
this.message = "success";
this.data = data;
}
public Result(T data, boolean success, String message) {
if (success) {
this.code = 200;
this.message = "success";
} else {
this.code = 500;
this.message = message;
}
this.data = data;
}
public Result(int code, String message) {
this.code = code;
this.message = message;
this.data = null;
}
public static <T> Result<T> success(T data) {
return new Result<>(data);
}
public static <T> Result<T> fail(String message) {
return new Result<>(500, message);
}
public static <T> Result<T> fail(int code, String message) {
return new Result<>(code, message);
}
}
分页:
package com.example.management.util;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PageResult<T> implements Serializable {
private Long total;
private List<T> records;
public PageResult() {
}
public PageResult(Long total, List<?> records) {
this.total = total;
this.records = (List<T>) records;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List<?> getRecords() {
return records;
}
public void setRecords(List<?> records) {
this.records = (List<T>) records;
}
}
6.完成这些后就可以一步一步写代码
controller层
package com.example.management.controller;
import com.example.management.domain.entity.User;
import com.example.management.domain.form.UserDeleteForm;
import com.example.management.domain.form.UserSaveForm;
import com.example.management.domain.query.UserQuery;
import com.example.management.domain.vo.UserVo;
import com.example.management.groups.Add;
import com.example.management.service.UserService;
import com.example.management.util.PageResult;
import com.example.management.util.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
@Slf4j
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
/**
* 新增用户
*/
@PostMapping("/save")
public Result save(@RequestBody @Validated(Add.class) UserSaveForm form) {
log.info("删除用户:{}", form);
userService.saveUser(form);
return Result.success("添加成功");
}
/**
* 删除用户
*/
@DeleteMapping("/delete")
public Result delete(@RequestBody UserDeleteForm form) {
log.info("删除用户:{}", form);
userService.removeByIds(form.getIds());
return Result.success("删除成功");
}
/**
* 修改用户
*/
@PutMapping("/update")
public Result update(@RequestBody UserSaveForm form) {
log.info("修改用户:{}", form);
userService.updateUser(form);
return Result.success("修改成功");
}
/**
* 根据id查询用户
*/
@GetMapping("/{id}")
public Result getUser(@PathVariable("id") Long id) {
log.info("查询用户:{}", id);
User user = userService.getById(id);
if (Objects.nonNull(user)){
UserVo userVo = new UserVo();
BeanUtils.copyProperties(user,userVo);
return Result.success(userVo);
}else {
throw new RuntimeException("用户不存在");
}
}
/**
* 分页查询
*/
@GetMapping("/page")
public PageResult getList(UserQuery query){
return userService.pageByGender(query);
}
}
Service层:
package com.example.management.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.management.domain.entity.User;
import com.example.management.domain.form.UserSaveForm;
import com.example.management.domain.query.UserQuery;
import com.example.management.util.PageResult;
import com.example.management.util.Result;
public interface UserService extends IService<User> {
/**
* 新增用户
* @param form
*/
void saveUser(UserSaveForm form);
/**
* 修改用户
* @param form
*/
void updateUser(UserSaveForm form);
/**
* 分页查询用户
* @param query
* @return
*/
PageResult pageByGender(UserQuery query);
}
Service实现类:
package com.example.management.service.Impl;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.management.domain.entity.User;
import com.example.management.domain.form.UserSaveForm;
import com.example.management.domain.query.UserQuery;
import com.example.management.mapper.UserMapper;
import com.example.management.service.UserService;
import com.example.management.util.PageResult;
import com.example.management.util.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
private final UserMapper userMapper;
/**
* 修改用户
* @param form
*/
@Override
public void updateUser(UserSaveForm form) {
User entity = userMapper.selectById(form.getId());
if (Objects.nonNull(entity)){
BeanUtils.copyProperties(form,entity);
userMapper.updateById(entity);
}else {
throw new RuntimeException("对应的用户不存在");
}
}
/**
* 新增用户
* @param form
*/
@Override
public void saveUser(UserSaveForm form) {
User user = new User();
BeanUtils.copyProperties(form,user);
userMapper.insert(user);
}
/**
* 用户分页查询
* @param query
* @return
*/
@Override
public PageResult pageByGender(UserQuery query) {
Page<User> page = new Page<>(query.getPage(), query.getPageSize());
new LambdaQueryChainWrapper<>(userMapper)
.like(StringUtils.hasText(query.getName()), User::getName, query.getName())
.like(StringUtils.hasText(query.getNickname()), User::getNickname, query.getNickname())
.eq(StringUtils.hasText(query.getGender()), User::getGender, query.getGender())
.eq(StringUtils.hasText(query.getPassword()), User::getPassword, query.getPassword())
.page(page);
long total = page.getTotal();
List<User> rows = page.getRecords();
return new PageResult<>(total,rows);
}
}
可以看出单表直接调用MybatisPlus提供的方法,不需要再自己写sql;
注意:这里需要注意几个点
1.批量删除还有一种传参方法是路径传参可以直接跟在请求路径后面:
缺点是要删的用户比较多的话,路径会很长
@DeleteMapping("/{ids}")
public Result delete(@PathVariable List<Long> ids) {
log.info("批量删除商品:{}", ids);
userService.removeByIds(ids);
return Result.success("删除成功");
2.只要是前端根据id传的都需要去数据库中根据id查询是否存在。