Mybatis Plus—数据安全保护、批量操作

一、数据安全保护 

该功能为了保护数据库配置及数据安全,在一定的程度上控制开发人员流动导致敏感信息泄露。

  • 3.3.2 开始支持
  • 配置安全

YML 配置:

// 加密配置 mpw: 开头紧接加密内容( 非数据库配置专用 YML 中其它配置也是可以使用的 )
spring:datasource:url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoMpassword: mpw:Hzy5iliJbwDHhjLs1L0j6w==username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==

密钥加密:

// 生成 16 位随机 AES 密钥
String randomKey = AES.generateRandomKey();// 随机密钥加密
String result = AES.encrypt(data, randomKey);

如何使用:

// Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
--mpw.key=d1104d7c3b616f0b
  • 数据安全:

👉 字段加密解密(opens new window)

👉 字段脱敏(opens new window)

  • SQL 注入安全保护说明
Wrappers.query()
// 开启自动检查 SQL 注入
.checkSqlInjection().orderByDesc("任意前端传入字段")
​
// 手动校验方式
SqlInjectionUtils.check("任意前端传入字段")

注意!

  • 加密配置必须以 mpw: 字符串开头
  • 随机密钥请负责人妥善保管,当然越少人知道越好。

二、批量操作

  • 3.5.4 + 版本支持
  • 事务需要手动自行控制(默认false)
  • 注意
  • autoCommit参数在Spring项目下是无效的,具体见SpringManagedTransactionFactory,在原生mybatis下可用
  • 执行返回值为批量处理结果,业务可根据返回值判断是否成功
  • 数据能否写入或更新取决于代码能否正确执行到flushStatements
  • 支持Spring与非Spring项目使用
  • 执行抛出异常为PersistenceException
  • saveOrUpdate是个比较有争议的方法,个人建议批量操作保持为简单的新增或更新操作

1、类说明

   1.1 MybatisBatch<?>

  • 泛型为具体 实际数据类型
  • sqlSessionFactory可通过容器获取,非Spring容器下可在自行初始化Mybatis时将上下文记录起来
  • dataList为实际的批量数据处理 (非空)

 1.2 MybatisBatch.Method<?>

实际为BatchMethod, 封装了框架内部操作方法简化调用.

  • 泛型为 实际Mapper方法参数需要的类型
  • mapperClass为具体的实际Mapper类

#BatchMethod<?>

  • 泛型为 实际Mapper方法参数需要的类型
  • statementId : 执行的MappedStatement
  • parameterConvert: 参数类型转换处理器,当数据类型与实际mapper方法参数不一致时,可以通过类型转换器进行转换

2、使用说明

  1. 构建MybatisBatch (将数据与sqlSessionFactory绑定起来)
  2. 构建MybatisBatch.Method (确定执行执行Mapper类方法)
  3. 执行操作 (执行处理操作,将批量参数转换为实际mapper需要的参数)

3、返回值说明

List<BatchResult>

执行返回每次按照执行MappedStatement + sql分组返回的操作结果

注意

例如批量根据id更新:

假设10条数据, 5条更新一个字段 5条更新两个字段 , 那返回值就是容量为2的List, 里面各存储了五条记录更新情况

update table set c1 = ? where id = ? //只更新一个字段

update table set c1 = ? , c2 = ? where id = ? // 只更新两个字段

mappedStatement: 执行的MappedStatement

sql: 执行sql

parameterObjects: 参数列表

updateCounts[]: 影响行数(与上面的parameterObjects数据一一对应)

4、使用示例

框架提供了一个MybatisBatchUtils进行静态方法调用.

   4.1 execute

适用于insert,update,delete操作

  示例一: 数据类型为实体

List<H2User> userList = Arrays.asList(new H2User(2000L, "测试"), new H2User(2001L, "测试"));
MybatisBatch<H2User> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, userList);
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class);
mybatisBatch.execute(method.insert());

示例二: 数据类型为非实体

List<Long> ids = Arrays.asList(120000L, 120001L);
MybatisBatch<Long> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, ids);
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class);
mybatisBatch.execute(method.insert(id -> {// 将id转换为实体H2User h2User = new H2User();h2User.setTestId(id);return h2User;
}));

示例三: 自定义方法插入(无注解)

// mapper方法(方法参数无注解)
@Insert("insert into h2user(name,version) values( #{name}, #{version})"
)
int myInsertWithoutParam(H2User user1);// 准备数据集合
List<H2User> h2UserList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {h2UserList.add(new H2User("myInsertWithoutParam" + i));
}MybatisBatch<H2User> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, h2UserList);
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class);
mybatisBatch.execute(method.get("myInsertWithoutParam"));

示例四: 自定义方法插入(注解)

// 方法参数带注解
@Insert("insert into h2user(name,version) values( #{user1.name}, #{user1.version})"
)
int myInsertWithParam(@Param("user1") H2User user1);// 准备数据集合
List<H2User> h2UserList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {h2UserList.add(new H2User("myInsertWithParam" + i));
}MybatisBatch<H2User> mybatisBatch = new MybatisBatch<>(sqlSessionFactory, h2UserList);
MybatisBatch.Method<H2User> method = new MybatisBatch.Method<>(H2UserMapper.class);
mybatisBatch.execute(method.get("myInsertWithParam", (user) -> {// 转换成mapper方法参数Map<String, Object> map = new HashMap<>();map.put("user1", user);return map;
}));

 4.2 saveOrUpdate

执行保存或更新

注意

重点注意跨sqlSession下缓存和数据感知问题

saveOrUpdate(BatchMethod<T> insertMethod, BiPredicate<BatchSqlSession, T> insertPredicate, BatchMethod<T> updateMethod)

  • insertMethod: 指定insert操作处理
  • insertPredicate: 指定insert操作处理条件

注意

注意这里的BatchSqlSession,使用这个进行查询操作会每次都执行一次flushStatements.

如果在一次处理中,如果有两条记录相同的数据,在跨sqlSession中会执行两次插入导致主键冲突,而共享sqlsesion下会执行一次插入和一次更新

  • updateMethod: 指定update操作处理

 跨sqlSession

@Autowired
private H2UserMapper userMapper;List<H2User> h2UserList = new ArrayList<>();
for (int i = 0; i < 100; i++) {h2UserList.add(new H2User(Long.valueOf(40000 + i), "test" + i));
}
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class);new MybatisBatch<>(sqlSessionFactory,h2UserList).saveOrUpdate(mapperMethod.insert(), // 指定insert方法((sqlSession, h2User) -> userMapper.selectById(h2User.getTestId()) == null),  //判断条件,引用另个mapper方法mapperMethod.updateById()); // 指定update方法

 共用sqlSession

List<H2User> h2UserList = new ArrayList<>();
for (int i = 0; i < 100; i++) {h2UserList.add(new H2User(Long.valueOf(50000 + i), "test" + i));
}
MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class);new MybatisBatch<>(sqlSessionFactory,h2UserList).saveOrUpdate(mapperMethod.insert(), // 指定insert方法((sqlSession, h2User) -> sqlSession.selectList(mapperMethod.get("selectById").getStatementId(), h2User.getTestId()).isEmpty()), //判断条件,共用sqlSessionmapperMethod.updateById()); // 指定update方法

 4.3 事务处理

   Spring事务处理示例一

@Autowired
private TransactionTemplate transactionTemplate;transactionTemplate.execute((TransactionCallback<List<BatchResult>>) status -> {MybatisBatch.Method<H2User> mapperMethod = new MybatisBatch.Method<>(H2UserMapper.class);// 执行批量插入MybatisBatchUtils.execute(sqlSessionFactory, h2UserList, mapperMethod.insert());throw new RuntimeException("出错了");
});

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

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

相关文章

设计模式系列:三、责任链设计模式

一、概述 责任链模式是一种行为设计模式&#xff0c;它允许多个对象处理一个请求&#xff0c;从而避免了请求的发送者和接收者之间的耦合关系。 优点是把任务划分为一个一个的节点&#xff0c;然后按照节点之间的业务要求、顺序&#xff0c;把一个个节点串联起来&#xff0c;…

如何使用浏览器自动化框架Playwright开发“万媒易发”实现多平台自动发布文章?

作为一名程序员和开发者&#xff0c;我深知在多个媒体平台手动发布和管理文章的痛苦。因此&#xff0c;我决定使用Playwright浏览器自动化框架&#xff0c;开发一款名为“万媒易发”的工具&#xff0c;实现多平台自动发布文章。下面我将分享这款工具的开发过程和成果&#xff0…

浅析教学型数控车床使用案例

教学型数控车床是一种专为教学和培训设计的机床&#xff0c;它具有小型化、高精度和灵活性的特点&#xff0c;可以作为学校和技术学院的培训机器。下面是一个使用案例&#xff0c;以展示教学型数控车床在教学实训中的应用。 案例背景&#xff1a; 某职业技术学院的机械工程专业…

H5ke11--4java分发多servlet--用来把选课系统加快-含源代码

前言: java有两个cookie, 举例子:充电桩计费在serversocket 客户端socket[ 我怎么知道有没有东西传进来,就是端口 首先我客户端发送我的ip,然后serversocket进行监听客户端唻的 那我serversocket维护着一个队列,serversocket有个阈值啊超出进行排队 代码详解: 1首先getParamet…

Socket通信之网络协议基本原理

一台机器将自己想要表达的内容&#xff0c;按照某种约定好的格式发送出去&#xff0c;当另外一台机器收到这些信息后&#xff0c;也能够按照约定好的格式解析出来&#xff0c;从而准确、可靠地获得发送方想要表达的内容。这种约定好的格式就是网络协议&#xff08;Networking P…

VR全景航拍要注意什么,航拍图片如何处理

引言: VR全景航拍技术是当前摄影和航拍领域的新潮流。它采用虚拟现实技术&#xff0c;通过360度全景镜头捕捉画面&#xff0c;可以为观众提供身临其境的视觉体验。在宣传展示中&#xff0c;利用VR全景航拍技术可以为品牌宣传带来更加生动、震撼的视觉效果。 一、航拍注意事项 …

【追求卓越01】数据结构--数组

引导 这一章节开始&#xff0c;正式进入数据结构与算法的学习过程中。由简到难&#xff0c;先开始学习最基础的数据结构--数组。 我相信对于数组&#xff0c;大家肯定是不陌生&#xff0c;因为数组在大多数的语言中都有&#xff0c;也是大家在编程中常常会接触到的。我不会说数…

WebP 相对于 PNG、JPG 有什么优势?

新的东西&#xff0c;还没有普及&#xff0c;但绝大多数浏览器已兼容了 WebP 是一种由 Google 开发的图像格式&#xff0c;相比于 PNG 和 JPG 格式有以下几个优势&#xff1a; 更小的文件大小&#xff1a;相同质量下&#xff0c;WebP 格式的文件大小比 PNG 和 JPG 格式都要小得…

蝶恋花

《蝶恋花》 作家&#xff0f;罗光记 华灯初上&#xff0c;夜色阑珊&#xff0c;轻风微起&#xff0c;落英缤纷。正是春意盎然之时&#xff0c;蝴蝶翩翩起舞&#xff0c;花间留恋。此情此景&#xff0c;不禁令人感叹&#xff1a;“蝶恋花&#xff0c;花恋蝶&#xff0c;人间至…

《数据仓库入门实践》

前言&#xff1a; 1、问什么要写这篇博客&#xff1f; 随着自己在数仓岗位工作的年限增加&#xff0c;对数仓的理解和认知也在发生着变化 所有用这篇博客来记录工作中用到的知识点与经验 2、这篇博客主要记录了那些内容&#xff1f; 在日常工作中&#xff0c;发现刚接触不久数仓…

jQuery实现横版手风琴效果

一、实现效果 当鼠标滑过方块的时候&#xff0c;方块的状态就会发生如下图所示的变化&#xff0c;同理当鼠标滑到其他的方块也会发生同样的效果&#xff0c;不仅大小会改变同时方块的颜色也会跟着发生变化&#xff1a; 二、代码实现 <!DOCTYPE html> <html><h…

opencv-python读取的图像分辨率太大不能完全显示

如果使用OpenCV-Python读取的图像分辨率太大&#xff0c;无法完全显示在屏幕上&#xff0c;可以考虑以下几种方法&#xff1a; 1.缩放图像&#xff1a;使用OpenCV的resize函数&#xff0c;将图像缩小到适合屏幕显示的大小。例如&#xff0c;可以将图像的宽度和高度都缩小到屏幕…

笔记58:Encoder-Decoder 架构

本地笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a a a

121. 买卖股票的最佳时机 --力扣 --JAVA

题目 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利…

SpringBoot 导入其他配置文件

默认情况下&#xff0c;springboot 初始的项目中都有一个 application.yml 或者 application.properties 文件&#xff0c;如果我们希望再定义一个独立的配置文件用来配置特定业务数据&#xff0c;而不希望把这些配置内容都堆积在 application 配置文件中&#xff0c;实现这个需…

python命令行交互 引导用户选择宠物

代码 以下代码将在命令行中&#xff0c;引导用户选择一个或者多个宠物&#xff0c;并反馈用户选择的宠物 # -*- coding:UTF-8 -*- """ author: dyy contact: douyaoyuan126.com time: 2023/11/22 15:19 file: 在命令行中引导用户选择宠物.py desc: xxxxxx &qu…

蓝桥等考C++组别七级007

第一部分:选择题 1、C++ L7 (15分) 执行以下程序后,输出结果是( )。 int a = 5; int b = a++; cout << a << " " << b; A. 5 5 B. 5 6 C. 6 5 D. 6 6 正确答案:C

好题分享(2023.11.12——2023.11.18)

目录 ​ 前情回顾&#xff1a; 前言&#xff1a; 题目一&#xff1a;《有效括号》 思路&#xff1a; 总结&#xff1a; 题目二&#xff1a;《用队列实现栈》 思路&#xff1a; 总结&#xff1a; 题目三&#xff1a;《用栈实现队列》 思路&#xff1a; 总结 &#x…

WPF实战项目十五(客户端):RestSharp的使用

1、在WPF项目中添加Nuget包&#xff0c;搜索RestSharp安装 2、新建Service文件夹&#xff0c;新建基础通用请求类BaseRequest.cs public class BaseRequest{public Method Method { get; set; }public string Route { get; set; }public string ContenType { get; set; } &quo…

Node.js之http模块

http模块是什么&#xff1f; http 模块是 Node,js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer() 方法&#xff0c;就能方便的把一台普通的电脑&#xff0c;变成一台Web 服务器&#xff0c;从而对外提供 Web 资源服务。 如果我们想在node…