Day01--mybatis-plus介绍

mybatis-plus官方教程:https://mp.baomidou.com/guide/

1、当使用mybatis-plus依赖时导入的坐标:baomidou

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

2、@MapperScan

作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加

3、要想在控制台看到sql输出日志,需要在application.properties配置文件中添加以下代码

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

4、主键生成策略

  • auto-increment
  • uuid:每次随机生成唯一值,排序不方便
  • redis
  • mybatis-plus (使用了snowplake算法)

常见的主键生成策略介绍:https://www.cnblogs.com/haoxinyue/p/5208136.html

mybatis-plus默认只用自己自带的主键生成策略,但可以自己设置要使用的主键生成策略,使用如下注解@TableId
  • @TableId(type = IdType.ID_WORKER)
    mybatis-plus自带的策略,生成19位值,当属性类型类数字类型时使用该策略,比如long

  • @TableId(type = IdType.ID_WORKER_STR)
    mybatis-plus自带的策略,生成19位值,当属性类型类字符串类型时使用该策略,比如String
    在这里插入图片描述

  • @TableId(type = IdType.UUID)
    随机生成唯一值

  • @TableId(type = IdType.AUTO)
    数据库ID自增

  • @TableId(type = IdType.INPUT)
    用户输入ID, 该类型可以通过自己注册自动填充插件进行填充

  • @TableId(type = IdType.NONE)
    没有策略

    在需要设置主键的实体类属性上使用该注解,可以设置主键策略,主要有以下几种策略。
    在这里插入图片描述

5、mbatis-plus自动填充

第一步:在实体类里需要自动填充的属性上面添加注解

如在下面User实体类的createTime和updateTime属性上添加注解
在这里插入图片描述

第二步:创建类,实现MetaObjectHandler接口,实现接口里的方法

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

import java.util.Date;

/**
 * @Description :
 * @Author :lenovo
 * @Date :2021/2/20 21:34
 */
 @Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    //用mybatis-plus实现添加操作,在这个方法内执行
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    //用mybatis-plus实现修改操作,在这个方法内执行
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}



6、丢失更新

多个人同时需改一条记录,最后提交的会把之前提交的数据覆盖更新。
在这里插入图片描述

6.1、丢失更新解决方案:

6.1.1 、悲观锁(表级锁):串行操作。

举例1:如上图修改数据,Lucy修改money数据时,别人都不能进行操作,只有lucy操作完成后,其他人才能操作。
举例2:又比如当一个人上网浏览新闻时,别人不能浏览,只有当这个人浏览完成后,别人才能浏览,如果这个人浏览一百年,其他所有人就要等一百年,这就是悲观锁。

6.1.2、 乐观锁

使用版本号进行并发的控制。比如多个人修改数据时,只有一个人才能修改成功,其他人不能同时修改。
在这里插入图片描述乐观锁的实现原理:
在这里插入图片描述乐观锁的具体实现:
mybatis-plus实现乐观锁官方步骤:https://mp.baomidou.com/guide/interceptor-optimistic-locker.html#optimisticlockerinnerinterceptor

  • 1、表中添加字段,作为乐观锁版本号。
    在这里插入图片描述

  • 2、对应实体类添加版本号属性。
    在这里插入图片描述
    @version注解所在的包:
    在这里插入图片描述

  • 3、插件配置

spring工程:在spring.xml配置文件中

<bean class="baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>

spring-boot项目:新建一个存放配置类的包,在该包下新建个配置类:编写乐观锁插件

 package com.nonglin.mpdemo.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.nonglin.mpdemo")
public class Mpconfig {

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

  • 4、在测试类中测试乐观锁:
  //测试乐观锁
    @Test
    public void testOptimisticLocker(){
        User user = userMapper.selectById(1363307390618947585L);

        user.setAge(1);
        int row = userMapper.updateById(user);
        System.out.println("修改"+row+"条数据");
    }

7、mybatis-plus简单查询

7.1、根据id查询记录

//根据id查询
    @Test
    public void findById(){
        User user = userMapper.selectById(1L);
        System.out.println(user);
    }

控制台输出:
在这里插入图片描述

DBC Connection [HikariProxyConnection@671981276 wrapping com.mysql.cj.jdbc.ConnectionImpl@28fd3dc1] will not be managed by Spring
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id=? 
==> Parameters: 1(Long)
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 1, Jone, 18, test1@baomidou.com, null, null, null
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@35342d2f]
User(id=1, name=Jone, age=18, email=test1@baomidou.com, createTime=null, updateTime=null, version=null)

7.2、过多个id批量查询

 //多个id批量查询
    @Test
    public void findByBatchIds(){
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));
        for(User user:users){
            System.out.println(user);
        }
    }

控制台输出:
在这里插入图片描述

JDBC Connection [HikariProxyConnection@1171672359 wrapping com.mysql.cj.jdbc.ConnectionImpl@34fe326d] will not be managed by Spring
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id IN ( ? , ? , ? ) 
==> Parameters: 1(Long), 2(Long), 3(Long)
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 1, Jone, 18, test1@baomidou.com, null, null, null
<==        Row: 2, Jack, 120, test2@baomidou.com, null, null, null
<==        Row: 3, Tom, 28, test3@baomidou.com, null, null, null
<==      Total: 3
打印输出:
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@65eabaab]
User(id=1, name=Jone, age=18, email=test1@baomidou.com, createTime=null, updateTime=null, version=null)
User(id=2, name=Jack, age=120, email=test2@baomidou.com, createTime=null, updateTime=null, version=null)
User(id=3, name=Tom, age=28, email=test3@baomidou.com, createTime=null, updateTime=null, version=null)

7.3、简单的条件查询

 //简单条件查询
    @Test
    public void estSelectByMap(){
        HashMap<String,Object> map = new HashMap<>();
        map.put("name","Lucy");
        map.put("age",18);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }

控制台输出:
在这里插入图片描述

JDBC Connection [HikariProxyConnection@774095232 wrapping com.mysql.cj.jdbc.ConnectionImpl@499683c4] will not be managed by Spring
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE name = ? AND age = ? 
==> Parameters: Lucy(String), 18(Integer)
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 1363104207493660674, Lucy, 18, Lucy@qq.com, null, null, null
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2b917fb0]
User(id=1363104207493660674, name=Lucy, age=18, email=Lucy@qq.com, createTime=null, updateTime=null, version=null)

8、mybatis-plus分页

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
(1)创建配置类
在配置类中添加插件

 //分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

(2)测试selectPage分页
测试:最终通过page对象获取相关数据

   //测试分页插件
    @Test
    public void testPage(){
        //创建page参数
        //传入两个参数 当前页和每页显示的记录数
        Page<User> page  = new Page<>(1,4);

        //调用mybatis-plus分页查询的方法
        //调用mybatis-plus分页查询过程中底层进行了封装,把分页所有数据封装到page中
        userMapper.selectPage(page,null);

        //通过page对象获取分页数据
        System.out.println("当前页"+page.getCurrent());//当前页
        System.out.println("每页数据list集合"+page.getRecords());//每页数据list集合
        System.out.println("每页显示记录数"+page.getSize());//每页显示记录数
        System.out.println("总记录数"+page.getTotal());//总记录数
        System.out.println("总页数"+page.getPages());//总页数
        System.out.println("是否有上一页"+page.hasPrevious());//是否有上一页
        System.out.println("是否有下一页"+page.hasNext());//是否有下一页
    }

控制台输出:
在这里插入图片描述

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@71f96dfb] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1545644729 wrapping com.mysql.cj.jdbc.ConnectionImpl@4b7c4456] will not be managed by Spring
 JsqlParserCountOptimize sql=SELECT  id,name,age,email,create_time,update_time,version  FROM user
==>  Preparing: SELECT COUNT(1) FROM user 
==> Parameters: 
<==    Columns: COUNT(1)
<==        Row: 11
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user LIMIT 0,4 
==> Parameters: 
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 1, Jone, 18, test1@baomidou.com, null, null, null
<==        Row: 2, Jack, 120, test2@baomidou.com, null, null, null
<==        Row: 3, Tom, 28, test3@baomidou.com, null, null, null
<==        Row: 4, Sandy, 21, test4@baomidou.com, null, null, null
<==      Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@71f96dfb]
当前页1
每页数据list集合[User(id=1, name=Jone, age=18, email=test1@baomidou.com, createTime=null, updateTime=null, version=null), User(id=2, name=Jack, age=120, email=test2@baomidou.com, createTime=null, updateTime=null, version=null), User(id=3, name=Tom, age=28, email=test3@baomidou.com, createTime=null, updateTime=null, version=null), User(id=4, name=Sandy, age=21, email=test4@baomidou.com, createTime=null, updateTime=null, version=null)]
每页显示记录数4
总记录数11
总页数3
是否有上一页false
是否有下一页true

9、mybatis-plus删除

9.1、物理删除

真的从数据库中将数据删除

 //根据id删除
    @Test
    public void deleteById(){
        int result = userMapper.deleteById(1363126056508198913L);
        System.out.println(result);
    }

    //批量删除
    @Test
    public void testDeleteBatchIds(){
        int result = userMapper.deleteBatchIds(Arrays.asList(1L,2L,3L));
        System.out.println(result);
    }

9.2、逻辑删除

并没有将数据从数据库中删除,数据还存在数据库中,只是查询时查不出来数据了。

第一步:表添加逻辑删除字段,对应实体类添加属性,属性添加注解。

在这里插入图片描述在这里插入图片描述

第二步:在项目的配置类中配置逻辑删除插件

(mp3.3版本之后不需要引入该插件页可以实现功能)

    //逻辑删除插件
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
第三步:application.properties 加入配置
#逻辑删除配置
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
第四步:测试逻辑删除
/**
 * 测试 逻辑删除
 */
@Test
public void testLogicDelete() {
    int result = userMapper.deleteById(1L);
    System.out.println(result);
}
  • 测试后发现,数据并没有被删除,deleted字段的值由0变成了1
    在这里插入图片描述

  • 测试后分析打印的sql语句,是一条update
    在这里插入图片描述

  • 注意:被删除数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作

10、mybatis-plus性能分析

性能分析拦截器,用于输出每条 SQL 语句及其执行时间
SQL 性能执行分析,开发环境使用,超过指定时间,停止运行。有助于发现问题。

10.1、配置插件

(1)参数说明

  • 参数:maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。
  • 参数:format: SQL是否格式化,默认false。

(2)在 MybatisPlusConfig 中配置插件
注意:该插件在3.2.0以上版本移除,推荐使用使用第三方拓展执行SQL分析(需在pom.xml导入p6spy 依赖)打印功能

/**
 * SQL 执行性能分析插件
 * 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
 */
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

(3)Spring Boot 中设置dev环境,在springboot配置文件中设置

#环境设置:dev、test、prod
spring.profiles.active=dev

10.2、测试

/**
 * 测试 性能分析插件
 */
@Test
public void testPerformance() {
    User user = new User();
    user.setName("我是Helen");
    user.setEmail("helen@sina.com");
    user.setAge(18);
    userMapper.insert(user);
}

11、mybatis-plus实现复杂条件查询

创建QueryWarpper对象

 @Test
 public void testFindByCondition(){
        QueryWrapper<User> wrapper  = new QueryWrapper<>();
        //用warpper对象调用方法
        wrapper.
        
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值