首页 > 其他分享 >mybatisplus拓展

mybatisplus拓展

时间:2023-07-30 13:00:59浏览次数:37  
标签:mybatisplus 数据库 private powernode 拓展 import com user

1. 逻辑删除   94

前面我们完成了基本的增删改查操作,但是对于删除操作来说,我们思考一个问题,在实际开发中我们真的会将数据完成从数据库中删除掉么?

当然是不会的,这里我们举个例子:

在电商网站中,我们会上架很多商品,这些商品下架以后,我们如果将这些商品从数据库中删除,那么在年底统计商品数据信息的时候,这个商品要统计的,所以这个商品信息我们是不能删除的。

mybatisplus拓展_字段

如果商城中的商品下架了,这时候我们将商品从数据库删掉

mybatisplus拓展_字段_02

那到了年终总结的时候,我们要总结一下这一年的销售额,发现少了20000,这肯定不合理。所以我们是不能将数据真实删除的。

这里我们就采取逻辑删除的方案,逻辑删除的操作就是增加一个字段表示这个数据的状态,如果一条数据需要删除,我们通过改变这条数据的状态来实现,这样既可以表示这条数据是删除的状态,又保留了数据以便以后统计,我们来实现一下这个效果。

1.1 演示逻辑删除  95

【1】先在表中增加一列字段,表示是否删除的状态,这里我们使用的字段类型为int类型,通过1表示该条数据可用,0表示该条数据不可用

mybatisplus拓展_User_03

mybatisplus拓展_User_04

【2】实体类添加一个字段为Integer,用于对应表中的字段

mybatisplus拓展_字段_05

//数据库对应的实体类user   4
@Data  //生成set get方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
public class User extends Model<User>{
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @TableLogic(value = "1",delval = "0")//指定当前字段为逻辑删除字段  95
    private Integer status;
}

【3】测试逻辑删除效果

LoginTest

package com.powernode;

import com.powernode.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

//测试逻辑删除   95
@SpringBootTest
public class LoginTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    void loginDelete(){
        userMapper.deleteById(7L);
    }
}

mybatisplus拓展_字段_06

查看拼接的SQL语句,我们发现在执行删除操作的时候,语句变成了修改,是将这条数据的状态由1变为的0,表示这条数据为删除状态

mybatisplus拓展_数据库_07

查询一下看看这条数据还能不能查询出来

LoginTest

//查询一下看看这条数据还能不能查询出来   95
    @Test
    void logicSelect(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

mybatisplus拓展_字段_08

我们还可以通过全局配置来实现逻辑删除的效果

mybatisplus拓展_User_09

2. 通用枚举   96

首先我们先来回顾一下枚举,什么是枚举呢?

当我们想要表示一组信息,这组信息只能从一些固定的值中进行选择,不能随意写,在这种场景下,枚举就非常的合适。

例如我们想要表示性别,性别只有两个值,要么是男性,要么是女性,那我们就可以使用枚举来描述性别。

【1】我们先在表中添加一个字段,表示性别,这里我们一般使用int来描述,因为int类型可以通过0和1这两个值来表示两个不同的性别

mybatisplus拓展_字段_10

mybatisplus拓展_User_11

【2】编写枚举类

GenderEnum

package com.powernode.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;

//性别的枚举类  96
public enum GenderEnum {
    MAN(0,"男"),WOMAN(1,"女");

    private Integer gender;
    private String genderName;

    GenderEnum(Integer gender, String genderName) {
        this.gender = gender;
        this.genderName = genderName;
    }
}

【3】实体类添加相关字段

mybatisplus拓展_数据库_12

package com.powernode.domain;

import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.powernode.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/*//数据库对应的实体类user   4
@Data  //生成set get方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
//@TableName("powershop_user") //指定数据库中的powershop_user表和这个User实体类映射  30
public class User extends Model<User> {

    //@TableId(type = IdType.AUTO) //指定id的自增策略 (跟随我们数据库的主键自增策略来的) 77
    //@TableId(type = IdType.INPUT)//主键该策略表示,必须由我们手动的插入id,否则无法添加数据  78
    //@TableId(type = IdType.ASSIGN_ID)//测试雪花算法  81
    @TableId(type = IdType.NONE)//NONE策略表示不指定主键生成策略,他跟随的是全局策略  82
    private Long id;

    *//*@TableId(type = IdType.ASSIGN_UUID) //UUID全局唯一标识符定义了在时间和空间都完全唯一的系统信息 83
    private String id;*//*


//    @TableField("username") //指定表中的字段名和属性对应  32
    private String name;

//    @TableField(select = false)//时age字段失效查询不到  34
    private Integer age;

    private String email;

//    @TableField("`desc`") //将desc字段变成普通字段  33
//    private String desc;

    //online属性在表中没有,但是我们有需要这个属性进行展示,所以使用TableField注解,  35
    // 去掉这个字段,不让他作为查询字段。
//    @TableField(exist = false)
//    private Integer online; //用户在线或不在线
}*/


//数据库对应的实体类user   4
@Data  //生成set get方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
public class User extends Model<User>{
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;

//    @TableLogic(value = "1",delval = "0")//指定当前字段为逻辑删除字段  95
    private Integer status;
    private GenderEnum gender;

}

【4】添加数据

package com.powernode;

import com.powernode.domain.User;
import com.powernode.enums.GenderEnum;
import com.powernode.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

//测试性别枚举   96
@SpringBootTest
public class EnumTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    void enumTest(){
        User user = new User();
        user.setName("liu");
        user.setAge(29);
        user.setEmail("[email protected]");
        user.setStatus(1);
        user.setGender(GenderEnum.WOMAN);

        userMapper.insert(user);
    }
}

此时我们查看控制台,会发现添加失败了

mybatisplus拓展_数据库_13

原因是我们无法将一个枚举类型作为int数字插入到数据库中。不过我们对于枚举类型都给了对应的int的值,所以这里我们只需要进行一个配置,就可以将枚举类型作为数字插入到数据库中,为属性gender,添加上@EnumValue注解

package com.powernode.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;

//性别的枚举类  96
public enum GenderEnum {
    MAN(0,"男"),WOMAN(1,"女");

    @EnumValue
    private Integer gender;
    private String genderName;

    GenderEnum(Integer gender, String genderName) {
        this.gender = gender;
        this.genderName = genderName;
    }
}

此时我们再次执行添加操作,发现可以成功添加数据,而枚举类型的值也作为数据被插入到数据库中

mybatisplus拓展_数据库_14

mybatisplus拓展_数据库_15

mybatisplus拓展_User_16

3. 字段类型处理器   98

在某些场景下,我们在实体类中是使用Map集合作为属性接收前端传递过来的数据的,但是这些数据存储在数据库时,我们使用的是json格式的数据进行存储,json本质是一个字符串,就是varchar类型。那怎么做到实体类的Map类型和数据库的varchar类型的互相转换,这里就需要使用到字段类型处理器来完成。

【1】我们先在实体类中添加一个字段,Map类型

mybatisplus拓展_数据库_17

//数据库对应的实体类user   4
@Data  //生成set get方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
@TableName(autoResultMap = true)//将数据库查到的数据封装到map中  98
public class User extends Model<User>{
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;

//    @TableLogic(value = "1",delval = "0")//指定当前字段为逻辑删除字段  95
    private Integer status;
    private GenderEnum gender;

    //指定这个字段存储到数据库,将map处理器变成json格式  98
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private Map<String,String> contact;//联系方式  98

}

【2】在数据库中我们添加一个字段,为varchar类型

mybatisplus拓展_数据库_18

【3】为实体类添加上对应的注解,实现使用字段类型处理器进行不同类型数据转换

mybatisplus拓展_数据库_19

@TableName(autoResultMap = true)//将数据库查到的数据封装到map中  98

【4】字段类型处理器依赖Fastjson这个Json处理器,所以我们需要引入对应的依赖

mybatisplus拓展_User_20

<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.76</version>
		</dependency>

【5】测试添加操作  98

TypeHandlerTest

//向数据库添加一条数据  98
    @Test
    void typeHandler(){
        User user = new User();
        user.setName("li");
        user.setAge(28);
        user.setEmail("[email protected]");
        user.setGender(GenderEnum.MAN);
        user.setStatus(1);

        HashMap<String, String> map = new HashMap<>();
        map.put("tel","13388889999");
        map.put("phone","010-1234567");

        user.setContact(map);

        userMapper.insert(user);
    }

执行的SQL语句如下

mybatisplus拓展_数据库_21

通过观察SQL语句,我们发现当插入一个Map类型的字段的时候,该字段会转换为String类型

查看数据库中的信息,发现添加成功

mybatisplus拓展_字段_22

【6】测试查询操作,通过结果发现,从数据库中查询出来的数据,已经被转到Map集合

//查询  98
    @Test
    void typeHandlerSelect(){
        List<User> users = userMapper.selectList(null);
        System.out.println(users);
    }

mybatisplus拓展_User_23

4. 自动填充功能   99

在项目中有一些属性,如果我们不希望每次都填充的话,我们可以设置为自动填充,比如常见的时间,创建时间和更新时间可以设置为自动填充。

【1】在数据库的表中添加两个字段   99

mybatisplus拓展_User_24

注意只有设置了下划线和小驼峰映射,这种mysql的写法才能和实体类完成映射

mybatisplus拓展_字段_25

【2】在实体类中,添加对应字段,并为需要自动填充的属性指定填充时机

mybatisplus拓展_User_26

//数据库对应的实体类user   4
@Data  //生成set get方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
@TableName(autoResultMap = true)//将数据库查到的数据封装到map中  98
public class User extends Model<User>{
    @TableId
    private Long id;
    private String name;
    private Integer age;
    private String email;

//    @TableLogic(value = "1",delval = "0")//指定当前字段为逻辑删除字段  95
    private Integer status;
    private GenderEnum gender;

    //指定这个字段存储到数据库,将map处理器变成json格式  98
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private Map<String,String> contact;//联系方式  98

    @TableField(fill = FieldFill.INSERT)  //设置插入时自动填充  99
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)//设置插入和更新时自动填充  99
    private Date updateTime;

}

【3】编写自动填充处理器,指定填充策略   99

MyMetaHandler

package com.powernode.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

//配置填充策略  99
@Component
public class MyMetaHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        setFieldValByName("createTime",new Date(),metaObject);
        setFieldValByName("updateTime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        setFieldValByName("updateTime",new Date(),metaObject);
    }
}

【4】这里在插入前先设置一下mysql时区

mybatisplus拓展_字段_27

set GLOBAL time_zone = '+8:00'

mybatisplus拓展_数据库_28

通过查看发现,目前时区时间正常

SELECT NOW()

mybatisplus拓展_数据库_29

【5】再将配置文件的时区修改为serverTimezone=Asia/Shanghai

mybatisplus拓展_数据库_30

【6】测试插入操作  99

FillTest

@Test
    void testFillInsert(){
        User user = new User();
        user.setName("wang");
        user.setAge(35);
        user.setEmail("[email protected]");
        user.setGender(GenderEnum.MAN);
        user.setStatus(1);
        HashMap<String, String> contact = new HashMap<>();
        contact.put("phone","010-1234567");
        contact.put("tel","13388889999");
        userMapper.insert(user);
    }

mybatisplus拓展_User_31

mybatisplus拓展_User_32

【7】测试更新操作  99

FillTest

//更新
    @Test
    void testFillUpdate(){
        //1682337035187712001
        User user = new User();
        user.setId(1682337035187712001L);
        user.setName("wangwu");
        user.setAge(39);
        user.setEmail("[email protected]");
        user.setGender(GenderEnum.MAN);
        user.setStatus(1);
        HashMap<String, String> contact = new HashMap<>();
        contact.put("phone","010-1234567");
        contact.put("tel","13388889999");
        userMapper.updateById(user);
    }

mybatisplus拓展_字段_33

mybatisplus拓展_数据库_34

5. 防全表更新与删除插件  100

在实际开发中,全表更新和删除是非常危险的操作,在MybatisPlus中,提供了插件和防止这种危险操作的发生

先演示一下全表更新的场景

mybatisplus拓展_数据库_35

这是很危险的

如何解决呢?

注入MybatisPlusInterceptor类,并配置BlockAttackInnerInterceptor拦截器

mybatisplus拓展_字段_36

MybatisPlusConfig

package com.powernode.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//配置类   85
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //这个是配置 防全表更新与删除拦截器  100
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        //这里我们配置分页插件   85
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

测试全表更新,会出现抛出异常,防止了全表更新

UpdateAllTest

package com.powernode;

import com.powernode.domain.User;
import com.powernode.enums.GenderEnum;
import com.powernode.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

//测试防全表更新与删除插件  100
@SpringBootTest
public class UpdateAllTest {
    @Autowired
    private UserService userService;

    @Test
    public void updateAll(){
        User user = new User();
        user.setGender(GenderEnum.MAN);

        //更新性别为男  原本null这个参数是要写条件的,null表示没有条件,即表中数据全部更新  100
        userService.saveOrUpdate(user,null);
    }
}

测试,ok 拦截住了全表更新

mybatisplus拓展_User_37

标签:mybatisplus,数据库,private,powernode,拓展,import,com,user
From: https://blog.51cto.com/u_15784725/6899871

相关文章

  • 人脸识别技术:拓展智能世界的大门
    导言:人脸识别技术是计算机视觉领域的一项重要技术,通过分析和识别人脸图像,将人脸信息与数据库中的信息进行匹配,实现身份认证、安防监控、智能支付等应用。随着人工智能技术的不断发展和应用,人脸识别技术正迅速走进我们的日常生活。本文将深入探讨人脸识别技术的原理、应用场景以及......
  • 椭球面拟合方法及一般多项式函数拟合拓展
    基于对一般二次曲面拟合效果的不满,特地整理这一篇文章。不加任何限制的一般二次曲面拟合在机器视觉实际应用时会出现很多意外的情况。比如文章《匹配位姿拟合求精方法-兜尼完-博客园(cnblogs.com)》和《9点拟合梯度边缘亚像素方法-兜尼完-博客园(cnblogs.com)》,这两种方......
  • MyBatisPlus入门案例
              ......
  • mybatisplus入门
    1. MybatisPlus的介绍MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。愿景我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。2.......
  • MyBatisPlus
    【狂神说Java】MyBatisPlus最新完整教程通俗易懂:https://www.bilibili.com/video/BV17E411N7KN/快速入门使用第三方组件:1、导入对应的依赖2、研究依赖如何配置3、代码如何编写4、提高扩展技术能力【代码演示】pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxm......
  • 手撕博客0到1拓展-bootstrap-table
    1.默认常量信息(表)1.1.无法转换为自定义方法属性默认值描述heightundefined表格的高度classestabletable-borderedtable-hover表格的类名称buttons{}按钮,bootstraptable加载的按钮集,可自定义theadClasses表头样式''undefinedText'-'当数据为undefined时显示的字符localeund......
  • MyBatisPlus公共字段自动填充
    公共字段自动填充公共字段新增员工,修改、编辑员工信息时,都需要设置创建时间,修改时间等操作,这些操作过于重复、繁琐,为了有更快捷高效的,MyBatisPlus提供了公共字段自动填充功能,当我们执行insert和update操作时才执行MyBatisPLus公共字段自动填充就是在插入或者修改操作时,为指定字......
  • mybatisPlus
    mybatisPlusmybatisplus基础:mybatisspringspringmvc为什么要学习mybatisplus?可以解决大量时间所有的CRUD代码它都可以自动化完成简介简化jdbc操作简化mybatis快速入门网站:快速开始|MyBatis-Plus(baomidou.com)使用第三方依赖导入对应的依赖研究......
  • mybatisPlus简介
    mybatisplus简化了dao层packagecom.example.mp_01.dao;importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.example.mp_01.domain.User;importorg.apache.ibatis.annotations.Mapper;@MapperpublicinterfaceUserdaoextendsBaseMapper<User>......
  • 数据类型及拓展
    数据类型字母,$,_//Ctrl+D快速复制一行//Ctrl+/注释intnum=10;//数字Stringb="hello";//字符串基本类型数值类型整数类型byte占1字节范围:-128-127short占2字节范围-32768-32767int占4字节范围-2147483648-2147483647long占8字节范围-92233720368547758......