SpringBoot+MyBatis-plus实现CRUD (踩坑总结!!!)

news2024/11/27 23:50:02

一、创建项目,引入相应的依赖 (项目源码在文末)

(不要选Module !!!!)

 

 <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.4.2</version>
 </dependency>

 二、创建表和对应的实体类

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL COMMENT '用户名',
  `user_password` varchar(255) DEFAULT NULL COMMENT '密码',
  `email` varchar(255) DEFAULT NULL COMMENT '邮箱',
  `phone` varchar(255) DEFAULT NULL COMMENT '手机号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    //用户名
    private String userName;
    //密码
    private String userPassword;
    //邮箱
    private String email;
    //手机号
    private String phone;
    //创建时间
    private Date createTime;
//    private String createTime;
}

 三、创建对应的实现层和控制层

import com.example.registerdemo.entity.User;
import com.example.registerdemo.param.UserRegisterParam;
import com.example.registerdemo.pojo.UserDTO;
import com.example.registerdemo.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;
@RestController
@RequestMapping("/user")

public class UserController {
    @Resource
    private UserService userService;

    //用户注册,用于处理用户注册请求
    @PostMapping("/register")
    public String userRegister(@Validated @RequestBody UserRegisterParam param) {
        User user = new User();
        BeanUtils.copyProperties(param,user);
        if(userService.userRegister(user)) {
            return "注册成功";
        }
        return "注册失败";
    }

    //获取用户的所有信息,用于处理查询所有用户的信息的请求
    @PostMapping("/getAllUser")
    public List<User> getAllUserInfo() {
        return userService.getAllUserInfo();
    }

    @PostMapping("/getUserByName")
    @Validated
    public List<User> getUser(@RequestParam("username") @NotNull(message = "用户名不能为空") String name){
        return userService.getUsersByName(name);
    }

    /**
     * 更新用户信息
     */
    @PostMapping("/getUpdateUser/{id}")
    public List<User> getUpdateUser(@RequestBody UserDTO userDTO){
        return userService.updateUser(userDTO);
    }

    /**
     * 删除用户
     */
    @PostMapping("/deleteUser/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.registerdemo.entity.User;
import com.example.registerdemo.mapper.UserMapper;
import com.example.registerdemo.pojo.UserDTO;
import com.example.registerdemo.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class RegisterUserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    /**
     * 用户注册功能(插入)
     *
     * 通过当前日期时间获取格式为 "yyyy-MM-dd HH:mm:ss" 的字符串 createTime。
     * 设置用户对象的 createTime 属性为 createTime。
     * 插入用户对象到数据库表中,如果受影响的行数大于0,则返回 true,否则返回 false。
     */
    public boolean userRegister(User user) {

        user.setCreateTime(new Date());
        if(userMapper.insert(user)>0) {
            return true;
        }
        return false;
    }

    /**
     * 查询全部
     * @return
     */
    @Override
    public List<User> getAllUserInfo() {
        return userMapper.selectList(null);
    }

    /**
     * 按照姓名进行查询
     * @param name
     * @return
     */
    @Override
    public List<User> getUsersByName(String name) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        return userMapper.selectList(queryWrapper);
    }

    /**
     * 按照id进行更新
     *
     * @param userDTO
     * StringUtils.isBlank和StringUtils.isEmpty主要区别就是
     * StringUtils.isBlank会认为全是空格的字符串为空,而StringUtils.isEmpty则将空格字符串认为不是空
     */
    @Override
    public List<User> updateUser( UserDTO userDTO) {
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setId(userDTO.getId());
        if (!StringUtils.isEmpty(userDTO.getUserPassword())) {
            user.setUserPassword(userDTO.getUserPassword());
        }
        userMapper.updateById(user);
        return null;
    }

    /**
     * 按照id进行删除
     * @param id
     */
    @Override
    public void deleteUser(Long id) {
        userMapper.deleteById(id);
    }
}

四、踩坑总结

        当然我没有单纯的从这个CRUD的内容上讨论踩坑,但是在这个过程中,遇到了一点相关的问题相信后面可能也会遇到,就在此进行一个总结吧。

踩坑①、

        我在写 “用户注册功能(其实就是简单的插入)”的时候,使用了BeanUtils工具类中的copyProperties的方法(当然,这是一种浅拷贝的方法,这只能拷贝同类型的数据,

先来说一下什么是浅拷贝,深拷贝。这两者最主要的区别就在于是否是复制了对象的真实实体还是说只是使用了一个指针,两者指向的是内存中的同一个对象。

浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址;

深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存;同时如果一个类中包含有引用类型变量,则该类拷贝以后引用类型也会被拷贝。)

这里面还有一个易错点就是,谁拷贝谁,不要弄反了!

点进方法的源码进行查看,可以发现:

 

方法中第一个元素的位置是,原始数据,即传进来的数据,第二位置放的数据是目标对象的数据,即复制后的数据,后面要使用的也就是第二个方法的数据,这两个位置的顺序一定不能反。

踩坑②、

        在进行用户注册的时候,还加入了“参数校验”的功能,然而我第一次引用的依赖是这个,导致我参数校验的时候,发现 @Validated注解根本没有起作用。

  <dependency>
     <groupId>javax.validation</groupId>
     <artifactId>validation-api</artifactId>
     <version>1.1.0.Final</version>
 </dependency>

后来修改成下面引用的依赖后,注解正常有效果了 。

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-validation</artifactId>
 </dependency>

 踩坑③、

        在创建时间属性时,发现生成的时间,总是和真实的时间没有对应上(其实就是时间的时区没有对应上!!),后面在时间的属性上,加入了注解@DateTimeFormat,@JsonFormat 好像也没有生效。

 这个尝试了很多方法也没有效果,后面换了一个思路,尝试在yml文件里面配置看看,然后发现了这篇文章:

 搜索的关键词有的时候也挺重要的

 

spring:
  application:
    name: registerdemo
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost/register?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2b8&allowMultiQueries=true

这样配置好在运行就好了,那个时间格式化的注解也不用加了。 

最后还要注意的一个小点就是 @Mapper 不要忘记加了。

 

整个demo的源码详见:mybatis-plus_CRUD · 企业级代码管理平台 (aliyun.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/590601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux常见的二十多个指令

目录 一、指令的概念 二、28个常见的指令 ⭐2.1 ls指令 ⭐2.2 pwd指令 ⭐2.3 cd指令 ⭐2.4tree指令 ⭐2.5 mkdir指令 ⭐2.6 touch指令 ⭐2.7 rmdir指令 ⭐2.8 rm指令 ⭐2.9 clear指令 ⭐2.10 man指令 ⭐2.11 cp指令 ⭐2.12 mv指令 ⭐2.13 cat指令&#xff08;适…

正规文法、正规表达式、有限自动机及其之间的转换(笔记)

The Equivalent Transforming among RG, RE and FA 正规文法 A Grammar G is a quadruple (四元组):G (VN, VT, S, P ) Where, VN is a finite set of nonterminals.VT is a finite set of terminals.S is the start symbol, S ∈ \in ∈ VN.P is a finite set of product…

.Net 使用OpenAI开源语音识别模型Whisper

.Net 使用OpenAI开源语音识别模型 Whisper 前言 Open AI在2022年9月21日开源了号称其英文语音辨识能力已达到人类水准的 Whisper 神经网络&#xff0c;且它亦支持其它98种语言的自动语音辨识。 Whisper系统所提供的自动语音辨识&#xff08;Automatic Speech Recognition&…

python基础知识(四):input语句、if语句和pass语句

目录 1. input语句2. 强制转换3. if语句4. pass语句 1. input语句 input语句是程序获取从键盘输入的内容&#xff0c;会把输入的内容自动转换成字符串。 使用方法: 变量名 input(“提示语”) 例如 language input("你最爱什么语言?") print(language)这两行代码…

RK3588平台开发系列讲解(项目篇)常见模型结构

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、DNN二、CNN三、RNN沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 AI 模型常采用人工神经网络来模拟人脑神经的记忆和处理信号的能力。常见的人工神经网络类型有深度神经网络(Deep Neural Network,DNN)…

Vue中组件的几个重要点

1 单词命名组件名称 vue推荐的命名组件名称有以下几种&#xff1a; 首先看下组件有几个单词构成 单个单词 如果只有一个单词&#xff0c;那么建议全部小写&#xff0c;用的时候也是全部小写的&#xff0c;或者首字母大写 有人喜欢哪怕只有一个单词也首字母大写&#xff0c;…

读论文-GPRAR

论文&#xff1a;GPRAR: Graph Convolutional Network based Pose Reconstruction and Action Recognition for Human Trajectory Prediction&#xff08;2016&#xff09; 摘要 高精度的预测对于自动驾驶等各种应用至关重要。现有的预测模型在现实世界中很容易出错&#xff0…

linux【网络编程】之HTTP协议

一文了解应用层协议&#xff1a;HTTP协议 一、HTTP协议二、URL2.1 urlencode和urldecode 三、HTTP协议格式3.1 HTTP请求方法3.2 HTTP状态码3.3 HTTP响应报头 四、结合代码理解HTTP通信流程五、长连接六、http会话保持七、postman和fiddler 一、HTTP协议 在上篇文章中我们模拟了…

YOLOV5 + PYQT5双目测距

YOLOV5 PYQT5双目测距 1. 测距源码2. 测距原理3. PYQT环境配置4. 实验结果 1. 测距源码 详见文章 YOLOV5 双目测距&#xff08;python&#xff09; 2. 测距原理 如果想了解双目测距原理&#xff0c;请移步该文章 双目三维测距&#xff08;python&#xff09; 3. PYQT环境…

大数据需要学习哪些内容

Python 已成利器 在大数据领域中大放异彩 Python&#xff0c;成为职场人追求效率的利器&#xff0c;因为不管什么工作&#xff0c;数据都会是工作的一部分&#xff0c;有数据的地方&#xff0c;就有Python&#xff01; 我们知道&#xff0c;随着互联网的发展&#xff0c;线上…

数睿通2.0数据血缘、标准、质量功能更新发布

文章目录 引言数据血缘数据标准数据质量结语 引言 这段时间工作繁忙&#xff0c;琐事较多&#xff0c;加上二阳的冲击&#xff0c;导致数睿通 2.0 的更新进度缓慢&#xff0c;深表歉意&#xff0c;还望大家可以理解。本次更新主要包含数据治理模块的血缘&#xff0c;标准&…

阿里云的云安全审计可以用于哪些安全事件与合规审核?

阿里云的云安全审计可以用于哪些安全事件与合规审核&#xff1f; [本文由阿里云代理商[聚搜云www.4526.cn]撰写] 随着互联网的高速发展&#xff0c;各种互联网应用和服务也在不断涌现。但在运营过程中&#xff0c;安全事件和合规审核问题也不断出现。如何及时、准确地识别并解决…

[Nacos] Nacos Server之间的操作 (十一)

文章目录 1.ServiceManager#init()1.1 定时发送任务1.2 定时更新状态任务1.3 定时清除空service任务 1.ServiceManager#init() PostConstructpublic void init() {// 启动了一个定时任务&#xff1a;每60s当前Server会向其它Nacos Server发送一次本机注册表// 本机注册表是以各…

水声声波频率如何划分?水声功率放大器可将频率放大到20MHz吗?

水声声波频率如何划分&#xff1f;水声功率放大器可将频率放大到20MHz吗&#xff1f; 现如今我们可以在地球任意地区实现通信&#xff0c;是因为电磁波的作用。但是我们都知道海洋占了全球十分之七面积&#xff0c;电磁波在水下衰减速度太快&#xff0c;无法做到远距离传输&am…

linux内核内存管理slab

一、概述 linux内存管理核心是伙伴系统&#xff0c;slab&#xff0c;slub&#xff0c;slob是基于伙伴系统之上提供api&#xff0c;用于内核内存分配释放管理&#xff0c;适用于小内存&#xff08;小于&#xff11;页&#xff09;分配与释放&#xff0c;当然大于&#xff11;页…

Ext JS嵌套分组表格的实现

这里的嵌套分组表格指的是这样一种表格 表格的每一行可以展开下一层的Grid展开的嵌套表格是一个分组的表格显示的效果如下图: 这种显示的方式可以显示 3个层级的数据,比如这里的国家 、 将军等级、将军信息。 如果最外层再使用分组的表格, 则可以显示 4个层级的信息, 这种…

Ethercat学习-从站FOE固件更新(QT上位机)

文章目录 简介1、源码简介1、ec_FOEread2、ec_FOEwrite3、ec_FOEdefinehook 2、程序思路3、修改实现1、ecx_FOEwrite_gxf2、ecx_FOEread_gxf 4、其他5、结果6、源码连接 简介 FOE协议与下位机程序实现过程之前文章有提到&#xff0c;这里不做介绍了。这里主要介绍1、QT上位机通…

Java开发 - 让你少走弯路的Redis的主从复制

前言 大家举举手&#xff0c;让我看看还有多少人不会配置Redis的主从&#xff0c;主主这些的。故事发生在前段时间&#xff0c;小伙伴看到了博主的MySQL主从&#xff0c;就问博主有没有Redis的主从配置教程&#xff0c;本以为网上到处都是教程的博主打开网页一搜&#xff0c;好…

SpringCloud:分布式缓存之Redis主从

1.搭建主从架构 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 2.主从数据同步原理 2.1.全量同步 主从第一次建立连接时&#xff0c;会执行全量同步&#xff0c;将master节点的所有数据…

VSCode+Git+TortoiseGit+Gitee

目录 一、VSCode 1、VSCode(visual studio code)下载安装 2、VSCode使用技巧和经验 2.1、设置字体: 2.2、快捷方式 2.3、安装插件 二、Git下载安装 三、TortoiseGit 1、TortoiseGit 简介 2、下载安装Git及Tortoisegit 3、Tortoisegit拉取gitee仓库到本地 4、Git拉取…