1 分页插件

MyBatis Plus 自带分页插件,只要简单的配置即可实现分页功能

  • 添加配置类 MyBatisPlusConfig

    @Configuration
    @MapperScan("com.atguigu.mybatisplus.mapper")
    public class MyBatisPlusConfig {
      //添加分页插件
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    }
  • 编写测试方法

    @Test
    public void testPage(){
    	// new Page()中的两个参数分别是当前页码,每页显示数量
    	// selectPage() 第一个参数是 Page,第二个参数是条件构造器,将满足条件的进行查询
    	Page<User> page = userMapper.selectPage(new Page<>(1, 5), null);
    	List<User> users = page.getRecords();
    	users.forEach(System.out::println);
    	List<User> list = page.getRecords();
    	list.forEach(System.out::println);
    	System.out.println("当前页:"+page.getCurrent());
    	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());
    }
测试结果:
User(id=1, name=Jone, age=18, email=test1@baomidou.com, isDeleted=0)
User(id=2,name=Jack, age=20, email=test2@baomidou.com, isDeleted=0)
User(id=3, name=Tom,age=28, email=test3@baomidou.com, isDeleted=0)
User(id=4, name=Sandy, age=21,email=test4@baomidou.com, isDeleted=0)
User(id=5, name=Billie, age=24, email=test5@baomidou.com, isDeleted=0)
当前页:1
每页显示的条数:5
总记录数:17
总页数:4
是否有上一页:false
是否有下一页:true

2 自定义分页

上面调用的是 MyBatis-Plus 提供的带有分页的方法,那么我们自己定义的方法如何实现分页呢?

Mapper 接口自定义方法中,第一个参数必须是 Page<\T> 对象,返回值也必须是这个类型的对象。

  • UserMapper 接口中定义一个方法

    // 根据年龄查询用户列表,分页显示
    Page<User> selectPageVo(@Param("page") Page<User> page,@Param("age") Integer age);
  • UserMapper.xml 中编写 SQL 实现该方法

    <select id="selectPageVo" resultType="User">
        select id,username as name,age,email from t_user where age > #{age}
    </select>
  • 编写测试方法

    @Test
    public void testPageVo(){
        Page<User> page = userMapper.selectPageVo(new Page<User>(1,2), 20);
        List<User> users = page.getRecords();
        users.forEach(System.out::println);
    }

3 乐观锁

作用:当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁的实现方式:

  • 取出记录时,获取当前 version

  • 更新时,带上这个 version

  • 执行更新时, set version = newVersion where version = oldVersion

  • 如果 version 不对,就更新失败

  • 数据库中增加商品表

    CREATE TABLE t_product (
        id BIGINT(20) NOT NULL COMMENT '主键 ID',
        NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
        price INT(11) DEFAULT 0 COMMENT '价格',
        VERSION INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
        PRIMARY KEY (id)
    );
  • 实体类 version 字段添加注解 @Version

    @Data
    public class Product {
        private Long id;
        private String name;
        private Integer price;
        @Version
        private Integer version;
    }
  • 添加乐观锁插件配置

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
  • 再次执行测试方法

    小李查询商品信息:

    小王查询商品信息:

    小李修改商品价格,自动将 version+1

    小王修改商品价格,此时 version 已更新,条件不成立,修改失败

    最终,小王修改失败,查询价格:150

  • 优化执行流程

    @Test
    public void testProduct01(){
        //1.小李获取商品价格
        Product productLi = productMapper.selectById(1);
        System.out.println("小李获取的商品价格为:" + productLi.getPrice());
     
        //2.小王获取商品价格
        Product productWang = productMapper.selectById(1);
        System.out.println("小李获取的商品价格为:" + productWang.getPrice());
     
        //3.小李修改商品价格+50
        productLi.setPrice(productLi.getPrice()+50);
        productMapper.updateById(productLi);
     
        //4.小王修改商品价格-30
        productWang.setPrice(productWang.getPrice()-30);
        int result = productMapper.updateById(productWang);
        if(result == 0){
            //操作失败,重试
            Product productNew = productMapper.selectById(1);
            productNew.setPrice(productNew.getPrice()-30);
            productMapper.updateById(productNew);
        }
     
        //5.老板查询商品价格
        Product productBoss = productMapper.selectById(1);
        System.out.println("老板获取的商品价格为:" + productBoss.getPrice());
    }