MyBatisPlus教程详解

MyBatisPlus概述

可以节省大量工作时间,CRUD代码可以自动完成。

JPA、tk-mapper、mybatisplus

简介:

是什么?mybatis本就是简化JDBC操作的!

官网:https://baomidou.com/

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H0Gnn1iN-1649299128846)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20220330102606942.png)]

特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

快速入门

地址:https://baomidou.com/pages/226c21/

使用第三方组件:

1、导入对应依赖

2、研究依赖如何配置

3、代码如何编写

4、提高扩展能力基础

步骤:

1、创建数据库mybatis_plus

2、创建user表

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);


DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
-- 真实开发中,version(乐观锁)、deleted(逻辑删除)、

3、编写项目,初始化项目,使用springboot初始化!

4、导入依赖

<!--    数据库驱动    -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

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

说明:使用mybatis_plus可以节省大量的代码,尽量不要同时导入mybatis与mybatis_plus!有冲突!

5、连接数据库,和mybatis相同

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://*.*.*.*:*/mybatis_plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

6、使用mybatis_plus之后

1、pojo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

2、mapper接口

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xjc.demo.pojo.User;
import org.springframework.stereotype.Repository;

// TODO: 2022/3/30 在对应的mapper上继承基本的接口 BaseMapper
@Repository     //代表持久层
public interface UserMapper extends BaseMapper<User> {

    // TODO: 2022/3/30 所有的CRUD都已完成;不需要以前的一堆配置文件了
}

注意:需要在主启动类上扫描mapper下的所有接口

//扫描mapper文件夹
@MapperScan("com.xjc.demo.mapper")

3、使用

@Autowired
    private UserMapper userMapper;

    @Test
    void contextLoads() {
        //参数是一个Wrapper,条件构造器,这里先不用
        //查询全部用户
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
配置日志

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

#配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
CRUD扩展
insert插入:
//测试插入
    @Test
    public void insert(){
        User user = new User();
        user.setName("xjc");
        user.setAge(23);
        user.setEmail("123@.com");
        int insert = userMapper.insert(user);//id回自动生成
        System.out.println(insert);
        System.out.println(user);//id回自动回填
    }

数据库插入id的默认值为:全局的唯一id

默认方案:

@TableId(type = IdType.ID_WORKER)//默认全局唯一id

@TableId(type = IdType.AUTO)//主键自增  数据库字段也要设置自增

@TableId(type = IdType.NONE)//未设置主键

@TableId(type = IdType.INPUT)//手动输入

@TableId(type = IdType.UUID)//uuid

@TableId(type = IdType.ID_WORKER_STR)//ID_WORKER的字符串表示
主键生成策略:

分布式系统唯一id生成汇总方案:https://www.cnblogs.com/haoxinyue/p/5208136.html

使用了雪花算法:Twitter的snowflake算法

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心(北京、上海、),5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一!

更新操作
//测试更新
    @Test
    public void update(){
        User user = new User();
        user.setId(1509008691360169986L);
        user.setName("12312312313213132");
        int i = userMapper.updateById(user);
    }

sql是动态配置的,sql会动态拼接

自动填充

创建时间,修改时间,这些操作自动化完成,不希望手动更新!

方式一:数据库级别

1、在表中新增创建时间,修改时间(工作中不建议)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KTRemdYu-1649299128854)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20220330141834952.png)]

方式二:代码级别

添加注解:

//字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

编写处理器,处理注解即可!

@Slf4j
@Component    //把处理器组件加到IOC容器中
public class MyDateObjectHandler implements MetaObjectHandler {

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

    //更新时填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start  update  fill.......");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}
乐观锁

乐观锁:它总是认为不会出现问题,就无论干什么都不去上锁!如果出现问题,再次更新值测试

悲观锁:它总是认为会出现问题,就无论干什么都会上锁,再去操作!

乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

测试一下乐观锁插件:

1、数据库加version字段

2、实体类加字段

	@Version   //乐观锁注解
    private Integer version;

3、注册组件

//扫描mapper文件夹
@MapperScan("com.xjc.demo.mapper")
@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {


    /**
     * 旧版
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    /**
     * 新版
     */
    /*@Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }*/
}

测试:

//测试乐观锁成功
    @Test
    public void testLGS(){
        //查询用户信息
        User user = userMapper.selectById(1L);

        //修改用户信息
        user.setName("xiajingc");
        user.setAge(1000);
        //执行更新操作
        int i = userMapper.updateById(user);
    }

    //测试乐观锁失败
    @Test
    public void testLGS2(){
        //线程1    查询用户信息
        User user = userMapper.selectById(1L);
        //修改用户信息
        user.setName("xiajingc");
        user.setAge(1000);

        //模拟另外一个线程执行并发操作
        User user1 = userMapper.selectById(1L);
        //修改用户信息
        user1.setName("xiajingc132");
        user1.setAge(1000);
        int i1 = userMapper.updateById(user1);

        //执行更新操作
        int i = userMapper.updateById(user);//如果没有乐观锁会覆盖插队线程的值
    }
查询操作

查询看源码即可

分页查询

1、使用limit

2、第三方插件

3、MP内置分页

使用:配置拦截器组件即可

//分页
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }

直接使用Page对象即可

//测试查询
    @Test
    public void testPage(){
        // 参数1:当前页   参数2:页面大小
        Page<User> page = new Page<>(1,5);
        IPage<User> userIPage = userMapper.selectPage(page,null);
        System.out.println(userIPage);
    }
删除操作

看源码

逻辑删除

就是软删除

1、加字段,加注解

@TableLogic  //逻辑删除注解
    private Integer deleted;

2、配置

	//逻辑删除组件
    @Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }
#逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

测试:

查询的时候,会屏蔽逻辑删除过的记录

性能分析插件

平时开发中会遇到慢sql。

MP也提供性能分析插件,如果超过这个时间就停止运行。

1、导入插件

//SQL执行效率插件
    @Bean
    @Profile({"dev","test"})//设置 dev 和 test环境开启
    public PerformanceInterceptor performanceInterceptor(){
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(1000); //ms   设置sql执行的最大时间为1ms,如果超过则不执行
        performanceInterceptor.setFormat(true);  //开启格式化支持
        return performanceInterceptor;
    }

配置环境

#设置开发环境
spring.profiles.active=dev

2、测试使用

在这里插入图片描述

条件构造器

十分重要:Wrapper

写一些复杂的sql就可以用它代替。使用链式编程

具体的每一个的使用可以自行看源码或者官网,或者直接百度查询

//查询name不为空、并且邮箱不为空,年龄大于等于12的
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("name")
                .isNotNull("email")
                .ge("age",12);
        List<User> users = userMapper.selectList(wrapper);
        System.out.println(users);

1、isNotNull 查询不为空的

2、ge 大于等于

3、gt 大于

4、le 小于等于

5、lt 小于

6、eq 等于(匹配)

7、ne 不等于

8、between between值1 AND 值2

9、notBetween notBetween值1 AND 值2

10、like like’%值%’

11、notLike

12、likeLeft

13、likeRight

14、isNull

15、in

16、notIn

17、inSql

在这里插入图片描述

18、notInSql

在这里插入图片描述

19、groupBy

在这里插入图片描述

20、orderByAsc

21、orderByDesc

22、orderBy

23、having

在这里插入图片描述

24、func
在这里插入图片描述

25、or

26、and

27、nested

在这里插入图片描述

28、apply

在这里插入图片描述

29、last

在这里插入图片描述

30、exists
在这里插入图片描述

31、notExists
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值