MyBatisPlus ---- 插件

news2024/12/25 12:54:12

MyBatisPlus ---- 插件

  • 1. 分页插件
    • a>添加配置类
    • b>测试
  • 2. xml自定义分页
    • a>UserMapper中定义接口方法
    • b>UserMapper.xml中编写SQL
    • c>配置文件
    • d>测试
  • 3. 乐观锁
    • a>场景
    • b>乐观锁与悲观锁
    • c>模拟修改冲突
    • d>乐观锁实现流程
    • e>MyBatis-Plus实现乐观锁

1. 分页插件

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

a>添加配置类

package com.fickler.mybatisplus.config;

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

/**
 * @author dell
 * @version 1.0
 */
@Configuration
@MapperScan("com.fickler.mybatisplus.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){

        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusInterceptor;

    }

}

b>测试

    @Test
    public void testPage(){

        //设置分页参数
        Page<User> page = new Page<>(1, 5);
        userMapper.selectPage(page, null);
        //获取分页数据
        List<User> records = page.getRecords();
        records.forEach(record -> System.out.println(record));
        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());

    }

在这里插入图片描述

2. xml自定义分页

a>UserMapper中定义接口方法

package com.fickler.mybatisplus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fickler.mybatisplus.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

/**
 * @author dell
 * @version 1.0
 */
@Repository
public interface UserMapper extends BaseMapper<User> {

    /**
     * 根据年龄查询用户列表,分页显示
     * @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
     * @param age 年龄
     * @return
     */
    Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);

}

b>UserMapper.xml中编写SQL

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fickler.mybatisplus.mapper.UserMapper">

    <!--Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);-->
    <select id="selectPageVo" resultType="user">
        select uid, user_name, age, email from t_user where age > #{age}
    </select>

</mapper>

c>配置文件

  # 配置类型别名所对应的包
  type-aliases-package: com.fickler.mybatisplus.pojo

d>测试

    @Test
    public void testSelectPageVo(){

        //设置分页参数
        Page<User> page = new Page<>(1, 5);
        userMapper.selectPageVo(page, 20);
        //获取分页数据
        List<User> records = page.getRecords();
        records.forEach(record -> System.out.println(record));
        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());

    }

在这里插入图片描述

3. 乐观锁

a>场景

一件商品,成本价是 80 元,售价是 100 元。老板先是通知小李,说你去把商品价格增加 50 元。小李正在玩游戏,耽搁了一个小时。正好一个小时后,老板觉得商品价格增加到 150 元,价格太高,可能会影响销量。又通知小王,你把商品价格降低 30 元。
此时,小李和小王同时操作商品后台系统。小李操作的时候,系统先取出商品价格 100 元;小王也在操作,取出商品价格也是 100 元。小李将价格加了 50 元,并将 100 + 50 = 150 元存入了数据库;小王将商品减了 30 元,并将 100 - 30 = 70 元存入了数据库。是的,如果没有锁,小李的操作就完全被小王的覆盖了。
现在商品价格是 70 元,比成本价低 10 元。几分钟后,这个商品很快就出售了 1 千多件商品,老板亏 1 万多。

b>乐观锁与悲观锁

上面的故事,如果是乐观锁,小王保存价格前,会检查下价格是否被人修改过了。如果被修改过了,则重新取出的被修改后的价格,150 元,这样他会将 120 元存入数据库。
如果是悲观锁,小李取出数据后,小王只能等小李操作完之后,才能对价格进行操作,也会保证最终的价格是 120 元。

c>模拟修改冲突

数据库中增加商品表

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)
);

添加数据

INSERT INTO t_product (id, NAME, price) VALUES (1, '外星人笔记本', 100);

添加实体

package com.fickler.mybatisplus.pojo;

import lombok.Data;

/**
 * @author dell
 * @version 1.0
 */
@Data
public class Product {

    private Long id;
    private String name;
    private Integer price;
    private Integer version;

}

添加mapper

package com.fickler.mybatisplus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fickler.mybatisplus.pojo.Product;

/**
 * @author dell
 * @version 1.0
 */
public interface ProductMapper extends BaseMapper<Product> {
}

测试

    @Test
    public void testConcurrentUpdate(){

        //1.小李
        Product product1 = productMapper.selectById(1L);
        System.out.println("小李取出的价格:" + product1.getPrice());

        //2.小王
        Product product2 = productMapper.selectById(1L);
        System.out.println("小王取出的价格:" + product2.getPrice());

        //3.小李将价格加了50元,存入了数据库
        product1.setPrice(product1.getPrice() + 50);
        int result1 = productMapper.updateById(product1);
        System.out.println("小李修改的结果:" + result1);

        //4.小王将商品减了30元,存入了数据库
        product2.setPrice(product2.getPrice() - 30);
        int result2 = productMapper.updateById(product2);
        System.out.println("小王修改的结果:" + result2);

        //最后的结果
        Product product = productMapper.selectById(1L);
        System.out.println("最后的结果:" + product.getPrice());

    }

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

d>乐观锁实现流程

数据库中添加 version 字段
取出记录时,获取当前 version

SELECT id,`name`,price,`version` FROM product WHERE id=1

更新时,version + 1,如果 where 语句中的 version 版本不对,则更新失败

UPDATE product SET price=price+50, `version`=`version` + 1 WHERE id=1 AND `version`=1

e>MyBatis-Plus实现乐观锁

修改实体类

package com.fickler.mybatisplus.pojo;

import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;

/**
 * @author dell
 * @version 1.0
 */
@Data
public class Product {

    private Long id;
    private String name;
    private Integer price;
    @Version
    private Integer version;

}

添加乐观锁插件配置

package com.fickler.mybatisplus.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author dell
 * @version 1.0
 */
@Configuration
@MapperScan("com.fickler.mybatisplus.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){

        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //添加分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加乐观锁插件
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;

    }

}

测试修改冲突

小李查询商品信息:
SELECT id,name,price,version FROM t_product WHERE id=?
小王查询商品信息:
SELECT id,name,price,version FROM t_product WHERE id=?
小李修改商品价格,自动将version+1
UPDATE t_product SET name=?, price=?, version=? WHERE id=? AND version=?
Parameters: 外星人笔记本(String), 150(Integer), 1(Integer), 1(Long), 0(Integer)
小王修改商品价格,此时version已更新,条件不成立,修改失败
UPDATE t_product SET name=?, price=?, version=? WHERE id=? AND version=?
Parameters: 外星人笔记本(String), 70(Integer), 1(Integer), 1(Long), 0(Integer)
最终,小王修改失败,查询价格:150
SELECT id,name,price,version FROM t_product WHERE id=?

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝牙耳机什么牌子性价比高?性价比最好的蓝牙耳机排行

近年来&#xff0c;蓝牙耳机越来越成为人们日常生活中常见的数码产品之一&#xff0c;逐渐地&#xff0c;看到更多的音频厂商、手机厂商加入蓝牙耳机市场中来。最近&#xff0c;看到很多人问&#xff0c;蓝牙耳机什么牌子性价比高&#xff1f;下面&#xff0c;我来给大家分享一…

浅谈map和unordered_map的应用场景

map和unordered_map的适用场景 底层结构介绍 map底层是红黑树结构unordered_map底层是哈希结构; Hash适用场景(unordered_map) 内存存角度来说hash因为底层维护了哈希表的存在&#xff0c;内存消耗远大于红黑树&#xff0c;但是因为哈希表增删查改时的直接映射&#xff0c…

OpenFeign服务接口调用

✨ OpenFeign服务接口调用OpenFeign & FeignFeign基本介绍OpenFeign基本介绍二者对比OpenFeign的使用新建Module&#xff1a;cloud-consumer-feign-order80pom依赖application.yml全局配置文件主启动类Service1. 业务逻辑接口FeignClient配置调用provider服务2. 新建Paymen…

第三十九讲:神州无线AC基础管理配置

瘦AP零配置上线&#xff0c;对AP的管理和配置都在AC上进行。AC的基础管理包括AC的无线地址指定及无线功能开启、AP的注册、AP用户数管理、自动信道调整等。 一、配置AC无线IP地址 设置静态的无线IP地址查看AC选取的无线IP地址3.开启无线功能 二、AP注册 1&#xff0e;二层模式…

【网络结构设计】11、E-LAN | 通过梯度传输路径来设计网络结构

文章目录一、背景二、方法2.1 网络设计策略2.2 Partial Residual Networks2.3 Cross Stage Partial Networks2.4 Efficient Layer Aggregation Network三、效果论文&#xff1a;Designing Network Design Strategies Through Gradient Path Analysis 代码&#xff1a;暂无 出…

微服务应用视角解读如何选择 K8s 的弹性策略

头&#xff1a;潘俊峰 前言 微服务架构的出现&#xff0c;拆分了庞大的单体应用&#xff0c;让业务之间的开发与协作变得更加灵活。当面临业务流量增加的场景时&#xff0c;往往需要对一些应用组件进行扩容。K8s 在应用层面提供了 HPA&#xff0c;围绕 HPA 开源社区延伸出了 …

SAP-FI模块 处理自动生成会计凭证增强

FICO-模块一. 相关问题概览1. 固定资产业务过渡科目摘要增强功能-F-022. 固定资产业务过渡科目摘要增强功能-MIGO3. 主营业务收入等科目自动反记账功能二. 问题图片描述1. 固定资产业务过渡科目摘要增强功能-F-022. 固定资产业务过渡科目摘要增强功能-MIGO3. 主营业务收入等科目…

JavaScript 作用域-作用域概述,变量作用域,作用域链

JavaScript 作用域-作用域概述&#xff0c;变量作用域&#xff0c;作用域链 目录JavaScript 作用域-作用域概述&#xff0c;变量作用域&#xff0c;作用域链1. 作用域1.1 作用域概述1.2 全局作用域1.3 局部作用域 (函数作用域)1.4 JS 没有块级作用域2. 变量的作用域2.1 变量作用…

校验和之概念、计算原理、检验原理、实例计算、代码编程,力荐力荐力荐

阅读前请看一下&#xff1a;我是一个热衷于记录的人&#xff0c;每次写博客会反复研读&#xff0c;尽量不断提升博客质量。文章设置为仅粉丝可见&#xff0c;是因为写博客确实花了不少精力。不用担心你关注我而我却不关注你&#xff0c;因为我是个诚信互关的人&#xff01;&…

如何用LightningChart创建Android图表数据可视化应用程序?(下)

LightningChart JS 是一款高性能的 JavaScript 图表工具&#xff0c;专注于性能密集型、实时可视化图表解决方案。 LightningChart .JS | 下载试用&#xff08;qun&#xff1a;740060302&#xff09;https://www.evget.com/product/4189/download 在上一篇&#xff0c;我们介…

CDN是什么?用了CDN就一定比不用更快吗?

对于开发同学来说&#xff0c;CDN这个词&#xff0c;既熟悉又陌生。 平时搞开发的时候很少需要碰这个&#xff0c;但却总能听到别人提起。 我们都听说过它能加速&#xff0c;也大概知道个原因&#xff0c;但是往深了问。 用了CDN就一定比不用更快吗&#xff1f; 就感觉有些…

Node.js操作Dom ,轻松hold住简单爬虫

前言 前段时间&#xff0c;我发现一个开源题库&#xff0c;题目非常有意思。我想把它整成一个JSON文件做为数据储备&#xff0c;方便整活。 一共有一百五十多道题目&#xff0c;手动CV我肯定是不想干的。于是写了个脚本&#xff0c;在写脚本的过程中&#xff0c;我发现一个能…

Opencv(C++)笔记--利用分水岭算法实现图像分割

1--分水岭算法的原理详细原理讲解可参考&#xff1a;博客1和视频1&#xff1b;原理简述&#xff1a;分水岭算法的基本思想是把图像视为拓扑地貌&#xff0c;图像中每一点像素的灰度值表示该点的海拔高度&#xff0c;每一个局部极小值及其影响区域称为集水盆&#xff0c;而两个集…

csrf漏洞原理及防御

攻击原理 从上图可以看出&#xff0c;要完成一次CSRF攻击&#xff0c;受害者必须依次完成两个步骤 1.登录受信任网站A&#xff0c;并在本地生成Cookie 2.在不登出A的情况下&#xff0c;访问危险网站B 防御原理 csrf能防御的本质是&#xff0c;黑客虽然携带了合法的cookie&a…

振弦采集模块的辅助功能寄存器

振弦采集模块辅助功能寄存器 1.频率值模拟量输出 VMXXX&#xff08;仅 VM501、 VM511&#xff09; 模块支持将当前实时频率值以模拟量形式从管脚输出&#xff0c;模拟量有电流和电压两种输出形式。为了使用此功能&#xff0c;需要将辅助功能寄存器 AUX.[0]设置为 1&#xff0…

<Linux开发> ubuntu开发工具-EasyConnect使用记录

&#xff1c;Linux开发&#xff1e; ubuntu开发工具-EasyConnect使用记录 1、安装EasyConnect 打开EasyConnect官网EasyConnect 根据当前电脑系统选择对应版本下载 作者这里是ubuntu 22.04版本 右击&#xff0c;选择 “软件安装” 即可安装完成&#xff1b;windows版本类似…

数据可视化:揭开“智慧校园”新篇章,助力新时代教育信息化

随着移动互联网、物联网等新一代信息技术的快速发展&#xff0c;建设智慧校园已经具备了成熟的技术条件。自从教育部启动教育信息化2.0计划后&#xff0c;建设智慧校园已成为我国教育信息化发展目标&#xff0c;无论是国家教育事业发展的十三五规划&#xff0c;还是十四五规划&…

Hadoop高手之路7-Hadoop的新特性

文章目录Hadoop高手之路7-Hadoop的新特性一、Hadoop2.0以上新特性二、Yarn资源管理框架1. yarn体系结构2. yarn的工作流程三、HDFS的高可用HA1. HDFS的高可用&#xff08;HA&#xff09;架构2. 搭建Hadoop高可用HA集群1) 规划集群节点2) 环境准备3) 配置HA集群(1) 修改core-sit…

【ROS】—— ROS通信机制——实践与练习(六)

文章目录前言1. 话题发布1.1 C方式实现1.2 python实现2. 话题订阅2.1 C实现2.2 python实现3. 服务调用3.1 C3.2 python4. 参数设置4.1 C4.2 python4.3 运行4.4 其他方式4.4.1 修改小乌龟节点的背景色(命令行实现)4.4.2 启动节点时&#xff0c;直接设置参数4.4.3 通过launch文件…

Java测试框架——JUnit详解(45)

文章目录前言何为JUnit&#xff1f;官方资料JUnit4常用注解和断言代码测试搭建一个JUnit测试环境生命周期忽略测试断言测试异常测试测试时间套件测试JUnit5JUnit5对比JUnit4的好处导包的改变注解的改变扩展JUnit新功能&#xff1a;参考文章JUnit是Java编程语言的单元测试框架&a…