• springboot 整合mybatisplus


    1.导入依赖

    <!--mybatis-plus 是自己开发的,并非官方!-->
    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>

    说明:我们使用mybatis-plus可以节省我们大量的代码,尽量不要同时带入mybatis跟mybatis-plus,可能会产生冲突

    在这里插入图片描述

    连接数据库! 这一步和mybatis相同

    url字段中 设置时区:serverTime=GMT%2b8 (%2b 就是+的意思,这里是指加8个小时,以北京东八区为准)

    # mysql 8 驱动不同,需要增加时区设置
    spring.datasource.username=root
    spring.datasource.password=83821979Zs
    spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

    2.  pojo-dao(连接mybatis,配置mapper.xml文件)-service-controller
    dao层

    mapper接口

    /**
    * @DATE: 2021/3/3 0003 23:24
    * @Author: 小爽帅到拖网速
    */

    // 在对应的Mapper上面实现基本的接口BaseMapper
    @Repository // 代码持久层
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    // 所有的CRUD操作都已经编写完成了
    // 你不需要像以前那样配置一大堆文件了
    }

    3、配置日志

    我们所有的Sql现在是不可见的,我们希望知道它是怎么执行的,所以我们必须要看日志!

    # 配置日志
    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

    6.@TableId(type = IdType.AUTO)

    其余的源码解释

    public enum IdType {
    AUTO(0), // 数据库id自增
    NONE(1), // 未设置主键
    INPUT(2), // 手动输入
    ID_WORKER(3), // 默认的全局id
    UUID(4), // 全局唯一id
    ID_WORKER_STR(5); // ID_WORKER 字符串表示法
    }

    改为手动输入之后,就需要自己配置id

    public class User {

    // 对应数据库的主键(uuid、自增id、雪花算法、redis、zookeeper)
    @TableId(type = IdType.INPUT) // 默认方案
    private Long id;
    private String name;
    private Integer age;
    private String email;
    }

    7.自动填充

    实体类字段属性上需要增加注解

    // 字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date create_time;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date update_time;
    1
    2
    3
    4
    5
    编写处理器来处理这个注解即可!

    由于这个处理器在Springboot下面, mybatis会自动处理我们写的所有的处理器

    当我们执行插入操作的时候,自动帮我们通过反射去读取哪边有对应注解的字段,从而把处理器代码插入成功,会自动帮我把createTime,updateTime插入值

    package com.shuang.handler;

    import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.logging.Log;
    import org.apache.ibatis.reflection.MetaObject;
    import org.springframework.stereotype.Component;

    import java.util.Date;

    /**
    * @DATE: 2021/3/4 0004 21:43
    * @Author: 小爽帅到拖网速
    */

    @Slf4j
    @Component // 一定不要忘记把处理器加到IOC容器中!
    public class MyMetaObjectHandler implements MetaObjectHandler {

    // 插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
    log.info("start insert fill.....");
    // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
    this.setFieldValByName("createTime",new Date(),metaObject);
    this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    // 更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
    this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    }

    8.乐观锁

    测试Mybatis-Plus的乐观锁实现

    1、给数据库中增加version字段

    实体类加对应的字段

    //乐观锁version注解
    @Version
    private Integer version;
    1
    2
    3
    3、注册组件

    // 这个扫描本来是在我们MybatisPlusApplication 主启动类中,现在我们把它放在配置类中
    // 扫描mapper文件夹
    @MapperScan("com.shuang.mapper")
    @EnableTransactionManagement // 自动开启事务管理
    @Configuration // 配置类

    public class MybatisPlusConfig {

    // 注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
    return new OptimisticLockerInterceptor();
    }
    }

    // 测试乐观锁成功
    @Test
    public void testVersionSuccess(){
    // 1. 查询用户信息
    User user = userMapper.selectById(1L);
    // 2. 修改用户信息
    user.setName("fan");
    user.setAge(24);
    // 3. 执行更新操作
    userMapper.updateById(user);
    }

    // 测试乐观锁失败!多线程下
    @Test
    public void testVersionFall(){
    // 线程1
    User user1 = userMapper.selectById(1L);
    user1.setName("fan111");
    user1.setAge(14);

    // 线程2
    User user2 = userMapper.selectById(1L);
    user2.setName("fan222");
    user2.setAge(24);
    userMapper.updateById(user2);

    //自旋锁来多次尝试提交!
    userMapper.updateById(user1); //如果没有乐观锁就会覆盖插队线程的值
    }
    }

    9.分页查询
    分页在网站使用的十分之多!

    原始的limit 进行分页
    pageHepler 第三方插件
    Mybatis-Plus其实也内置了分页插件!
    如何使用分页插件

    1、拦截器组件即可

    public class MybatisPlusConfig {
    // 分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {

    return new PaginationInterceptor();
    }
    }

    2、直接使用Page对象即可!

    // 测试分页查询
    @Test
    public void testPage(){
    // 参数1 当前页 ;参数2 页面大小
    Page<User> page = new Page<>(1,5);
    userMapper.selectPage(page,null);

    page.getRecords().forEach(System.out::println);
    System.out.println("getCurrent()"+page.getCurrent());
    System.out.println("page.getSize()"+page.getSize());
    System.out.println("page.getTotal()"+page.getTotal());
    }

     获取总条数!

    10.逻辑删除
    物理删除:从数据库中直接移除

    逻辑删除:再数据库中没有被移除,而是通过一个变量来让它失效! deleted = 0 => deleted = 1

    说明:

    只对自动注入的sql起效:

    插入: 不作限制
    查找: 追加where条件过滤掉已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
    更新: 追加where条件防止更新到已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
    删除: 转变为 更新
    例如:

    删除: update user set deleted=1 where id = 1 and deleted=0
    查找: select id,name,deleted from user where deleted=0
    字段类型支持说明:

    支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
    如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()
    附录:

    逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
    如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。
    管理员可以查看被删除的记录! 防止数据的丢失,类似于回收站!

    测试一下:

    在数据表中增加一个deleted字段

    实体类中增加字段

    // 逻辑删除注解
    @TableLogic
    private Integer deleted;
    1
    2
    3
    配置

    public class MybatisPlusConfig {
    // 逻辑删除组件
    @Bean
    public ISqlInjector iSqlInjector(){
    return new LogicSqlInjector();
    }
    }

    # 配置逻辑删除
    mybatis-plus.global-config.db-config.logic-delete-value= 1
    mybatis-plus.global-config.db-config.logic-not-delete-value= 0
    1
    2
    3
    测试一下删除!

    10条件构造器

    十分重要:Wrapper

    非空 大于
    @Test
    void contextLoads(){
    // 查询 name 不为空的用户,并且邮箱不为空的用户,年龄大于等于20
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper
    .isNotNull("name")
    .isNotNull("email")
    .ge("age",20);

    查询一个名字
    @Test
    void getOneName(){
    // 查询名字 小爽帅到拖网速
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","小爽帅到拖网速"); // 查询一个数据
    userMapper.selectOne(wrapper);
    }

    userMapper.selectList(wrapper).forEach(System.out::println);
    }

    使用between
    @Test
    void betweenTest(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.between("age",25 ,100);
    Integer count = userMapper.selectCount(wrapper);// 查询结果数
    System.out.println(count);
    }

    连接查询(内查询)
    // 内查询
    @Test
    void innerJoinTest(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    // id 在子查询中查找出来的
    wrapper.inSql("id","select id from user where id<3");
    List<Object> users = userMapper.selectObjs(wrapper);
    users.forEach(System.out::println);
    }

    升序排序

    过id进行排序
    @Test
    void orderById(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //
    wrapper.orderByDesc("id");
    List<Object> objects = userMapper.selectObjs(wrapper);
    objects.forEach(System.out::println);
    }


    # mybatis-plus相关配置
    mybatis-plus:
    # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
    mapper-locations: classpath:**/*Mapper.xml
    # 以下配置均有默认值,可以不设置
    global-config:
    #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 0
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #刷新mapper 调试神器
    refresh-mapper: false
    #数据库大写下划线转换
    #capital-mode: true
    #序列接口实现类配置
    #key-generator: com.baomidou.springboot.xxx
    #逻辑删除配置
    #logic-delete-value: 0 # 逻辑已删除值(默认为 1)
    #logic-not-delete-value: 1 # 逻辑未删除值(默认为 0)
    #自定义填充策略接口实现
    # meta-object-handler: com.zhengqing.config.MyMetaObjectHandler
    #自定义SQL注入器
    #sql-injector: com.baomidou.springboot.xxx
    configuration:
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
    map-underscore-to-camel-case: true
    cache-enabled: false
    # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
    # call-setters-on-nulls: true
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    # 解决oracle更新数据为null时无法转换报错,mysql不会出现此情况
    jdbc-type-for-null: 'null'




  • 相关阅读:
    Filter 和 interceptor 的区别
    JAVA基础知识|Optional
    CentOS 7安装MariaDB 10详解以及相关配置
    Linux系统zookeeper环境搭建(单机、伪分布式、分布式)
    Java设计模式——模板方法模式
    Java设计模式——装饰模式
    Java设计模式——观察者模式
    Java设计模式——代理模式
    Java设计模式——适配器模式
    Java设计模式——策略模式
  • 原文地址:https://www.cnblogs.com/lyy0622/p/15027310.html
Copyright © 2020-2023  润新知