小技巧notebook

news/2024/10/31 5:27:36/

小技巧notebook

1、MybatisPlus 批量保存

从BaseMapper接口方法可知,mybatis plus mapper只有根据id批量删除和查询,没有批量保存(insert 、update),要实现也很简单,需要定义一个Service

@Service
@Slf4j
public class QueueUsedInfoService extends ServiceImpl<QueueUsedInfoMapper, QueueUsedInfo> implements BatchInsertService {
}
interface BatchInsertService extends IService<QueueUsedInfo> {
}

其中QueueUsedInfoMapper实现了BaseMapper接口:

@Mapper
public interface QueueUsedInfoMapper extends BaseMapper<QueueUsedInfo> {
}

这个时候可以发现QueueUsedInfoService中有诸如saveBatch,saveOrUpdateBatch方法使用

2、MybatisPlus 注解实现脚本标签使用

比如、、这些标签,在mapper映射文件中可以直接使用,但是如果通过注解的话是不可以直接用的,需要用到{“”}标签包裹,如

@Select({"""<script>SELECTe.id,d.* FROM(SELECTc.* FROM(SELECTa.cluster_id,a.cluster_user,substring_index( substring_index( a.used, ',', b.help_topic_id + 1 ), ',', - 1 ) AS queue FROMpartition_info aINNER JOIN mysql.help_topic b ON b.help_topic_id &lt; ( length( a.used ) - length( REPLACE ( a.used, ',', '' )) + 1 ) ) c WHERECONCAT( c.cluster_id, '-', c.queue ) IN <foreach item='item' index='index' collection='items' open='(' separator=',' close=')'>#{item}</foreach>) dLEFT JOIN queue_used_info e ON d.cluster_id = e.cluster_id AND d.cluster_user = e.cluster_user AND d.queue = e.queue</script>"""})
List<QueueUsedInfo> getQueueUsedInfos(@Param("items") List<String> lstCondition);

另外注意

3、Mybatis实现insert时,同时根据主键唯一性有条件update

<!--批量操作,无则insert 有则update,update时根据最后更新时间做三元表达式判断:更新时间小于数据库时间,则不更新-->
<insert id="batchInsertOrUpdate" parameterType="list">insert into sc_job(id,cluster_id,job_user,job_status,last_update_time) values<foreach collection ="lstJob" item="item" separator =",">(#{item.id},#{item.clusterId},#{item.jobUser},#{item.jobStatus},#{item.lastUpdateTime})</foreach >on DUPLICATE KEY UPDATElast_update_time = IF(last_update_time > values(last_update_time),last_update_time,values(last_update_time)),cluster_id = IF(last_update_time > values(last_update_time),cluster_id,values (cluster_id)),job_user = IF(last_update_time > values(last_update_time),job_user,values (job_user)),job_status = IF(last_update_time > values(last_update_time),job_status,values (job_status))
</insert>

解释:如果没出现主键冲突,则insert;出现主键冲突的情况下满足条件的字段进行update

4、MySQL 利用help_topic系统表实现字符串无限制分割

前提:账号拥有root权限

SELECTa.cluster_id,substring_index( substring_index( a.used, ',', b.help_topic_id + 1 ), ',', - 1 ) AS queue FROMpartition_info aINNER JOIN mysql.help_topic b ON b.help_topic_id < ( length( a.used ) - length( REPLACE ( a.used, ',', '' )) + 1 ) 

对表used字段进行无限制分割,原理:

利用help_topic.help_topic_id自增属性,得到切割后数据个数,然后使用substring_index循环切割,每次得到最后一个

5、跨服务器数据库数据交叉处理脚本

#!/bin/bash 
echo "Start Check Data."#mysqldump source schema and data
mysqldump -h192.168.137.129 -P3307 -uroot -proot parauser --tables 源库表 > ./parauser.sql;
mysqldump -h192.168.137.129 -P3307 -uroot -proot ngbilling --tables 源库表 > ./ngbilling.sql;#source schema and validate data to console
mysql -h192.168.137.129 -P3306 -uroot -proot -e"
use 目标库;
set names utf8;
source ./parauser.sql;
source ./ngbilling.sql;---------------------------业务处理------------------------------------DROP TABLES 源库表;
commit;"#remove dump file
rm ./ngbilling.sql ./parauser.sql -f;echo "Check Data Successful." 
exit; 

6、年份分表数据批量导出备份

#!/bin/bash 
echo "Start Export Matomo Data..."
#$1为要导出数据年份,$2为需要创建备份数据库名称(不需要手动创建,matomo_backup.sql放export.sh同级目录)
echo "导出$1年的数据到备份数据库$2...";
#mysqldump导出源数据库结构及数据,具体数据库连接信息请自行修改
mysqldump -h192.168.137.128 -P3306 -uroot -proot matomo --column-statistics=0 > ./matomo.sql;#切换到目标数据库服务器,具体数据库连接信息请自行修改
mysql -h192.168.137.128 -P3307 -uroot -proot -e"
#创建备份库
CREATE DATABASE IF NOT EXISTS $2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;
use $2;
source ./matomo_backup.sql;#创建数据源临时库
CREATE DATABASE IF NOT EXISTS matomo DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;
use matomo;
set names utf8;
source ./matomo.sql;#导出需要备份年份的数据(普通表)
---------------------------
INSERT IGNORE INTO $2.matomo_archive_invalidations SELECT * FROM matomo_archive_invalidations where DATE_FORMAT(ts_invalidated,'%Y') = $1;
---------------------------#切换到备份库,通过存储过程、游标创建备份库中不存在的数据表及数据插入
use $2;#处理matomo_archive_blob_*;matomo_archive_numeric_*数据表集合(年份表)
DROP PROCEDURE IF EXISTS export_list;
delimiter $
CREATE PROCEDURE export_list()
BEGIN#遍历结束标志DECLARE var_flag INT DEFAULT 0;#遍历表名变量DECLARE var_table_name VARCHAR(100);#表集合DECLARE table_name_list CURSOR FORSELECT table_name FROM information_schema.tablesWHERE table_schema = 'matomo' AND table_type = 'base table'AND(table_name like 'matomo_archive_blob_%' AND SUBSTR(table_name,21,4) = $1ORtable_name like 'matomo_archive_numeric_%' AND SUBSTR(table_name,24,4) = $1) ;#将结束标志绑定到游标DECLARE CONTINUE HANDLER FOR NOT FOUND SET var_flag = 1;#打开游标OPEN table_name_list;FETCH table_name_list INTO var_table_name;WHILE var_flag !=1 DO#判断表类型IF FIND_IN_SET('matomo_archive_blob_',var_table_name)THEN#需要先判断该表在备份库是否存在,不存在需要先创建,然后再插入数据SET @createTableStr = CONCAT('CREATE TABLE IF NOT EXISTS ',var_table_name,'(idarchive int(10) UNSIGNED NOT NULL,name varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,idsite int(10) UNSIGNED NULL DEFAULT NULL,date1 date NULL DEFAULT NULL,date2 date NULL DEFAULT NULL,period tinyint(3) UNSIGNED NULL DEFAULT NULL,ts_archived datetime NULL DEFAULT NULL,value mediumblob NULL,PRIMARY KEY (idarchive, name) USING BTREE,INDEX index_period_archived(period, ts_archived) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPACT');ELSE#先判断该表在备份库是否存在,不存在需要先创建,然后再插入数据SET @createTableStr = CONCAT('CREATE TABLE IF NOT EXISTS ',var_table_name,'(idarchive int(10) UNSIGNED NOT NULL,name varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,idsite int(10) UNSIGNED NULL DEFAULT NULL,date1 date NULL DEFAULT NULL,date2 date NULL DEFAULT NULL,period tinyint(3) UNSIGNED NULL DEFAULT NULL,ts_archived datetime NULL DEFAULT NULL,value mediumblob NULL,PRIMARY KEY (idarchive, name) USING BTREE,INDEX index_period_archived(period, ts_archived) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPACT');END IF;PREPARE stmt FROM @createTableStr;EXECUTE stmt;#对matomo_archive_blob_*;matomo_archive_numeric_*数据表数据进行备份SET @insertStr = CONCAT('INSERT IGNORE INTO ',var_table_name,' SELECT * FROM matomo.',var_table_name);PREPARE stmt FROM @insertStr;EXECUTE stmt;FETCH table_name_list INTO var_table_name;END WHILE;CLOSE table_name_list;
END;#执行存储过程
CALL export_list();#删除存储过程
DROP PROCEDURE export_list;#切换回matomo临时库
use matomo;#删除临时源库
DROP DATABASE matomo;
commit;"#remove dump file
rm ./matomo.sql;echo "Export Data Successful."
exit; 

导出备份完成后对源库表清理脚本

#!/bin/bash 
echo "Start Clean Matomo Data..."
echo "开始清除已备份的$1年数据,请确保已执行export.sh进行备份...";
mysql -h192.168.137.128 -P3306 -uroot -proot -e"
use matomo;#删除已备份年份的历史数据(普通表)
DELETE FROM matomo_archive_invalidations where DATE_FORMAT(ts_invalidated,'%Y') = $1;#删除matomo_archive_blob_*;matomo_archive_numeric_*已备份年份的数据表(年份表)
DROP PROCEDURE IF EXISTS drop_table_list;
delimiter $
CREATE PROCEDURE drop_table_list()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 12 DOIF i < 10THENSET @dropTableStr = CONCAT('DROP table IF EXISTS matomo_archive_blob_$1_0' , i , ',' , 'matomo_archive_numeric_$1_0' , i);ELSESET @dropTableStr = CONCAT('DROP table IF EXISTS matomo_archive_blob_$1_' , i , ',' , 'matomo_archive_numeric_$1_' , i);END IF;PREPARE stmt FROM @dropTableStr;EXECUTE stmt;SET i = i+1;END WHILE;
END;#执行存储过程
CALL drop_table_list();
#删除存储过程
DROP PROCEDURE drop_table_list;
commit;"echo "Clean Data Successful."
exit; 

7、MySQL数据同步到Redis步骤

#将利用redis管道模式将MySQL数据刷入Redis
#1、MySQL查询结果拼接成Redis执行脚本,见:db/mysql_to_redis.sql
#2、将上一步脚本执行查询结果写入文件(具体的地址,数据库s,账号,密码根据需要设置,mysql_to_redis.sql,mtr.txt路径为MySQL容器路径)
docker exec mysql /bin/bash -c 'mysql -h192.168.137.128 -P3306 -uroot -proot -Dngbilling --skip-column-names --raw < /mydir/mysql_to_redis.sql > /mydir/mtr.txt'
#3、cat数据文件,通过管道符将结果让redis-cli批量刷入redis(具体的地址,数据库,密码根据需要设置,mtr.txt为redis容器根路径)
cat mtr.txt |redis-cli -h 192.168.137.128 -n 0 --pipe -a root

8、MySQL根据select结果集批量更新

UPDATE console.cluster a
INNER JOIN ( SELECT name, is_proxy, resource_type FROM console.b_cluster ) b ON b.name = a.id
SET a.owned = b.is_proxy ,a.res_type = b.resource_type;UPDATE console.account_group a,ngbilling.b_group b
SET a.fee_name = b.group_name
WHEREa.id = b.group_id;

http://www.ppmy.cn/news/78428.html

相关文章

回望大学,做个总结

一个普通大学生的回望 我准大一-痛苦大一-拼搏大二-忙碌大三-泄气大四-领悟写在最后 我 01年&#xff0c;甘肃人&#xff0c;本科贵州大学&#xff0c;数据科学与大数据技术。 2023应届毕业生&#xff0c;拿到金蝶的Offer&#xff0c;但最后去了交通银行软件开发中心&#xf…

【ZYNQ】ZYNQ7000 UART 控制器及驱动应用示例

UART 简介 我们在使用 PS 的时候&#xff0c;通常会添加 UART 控制器&#xff0c;用于打印信息和调试代码。除此之外&#xff0c;PS 在和外 部设备通信时&#xff0c;也会经常使用串口进行通信。 UART 控制器 UART 控制器是一个全双工异步收发控制器&#xff0c;ZYNQ 内部包…

怎么学习机械学习相关的技术?

学习机器学习相关技术的过程可以分为以下几个步骤&#xff1a; 掌握基本数学和统计知识&#xff1a; 机器学习建立在数学和统计学的基础上&#xff0c;了解线性代数、概率论、统计学等基本概念和方法对于理解机器学习算法至关重要。 学习编程和数据处理&#xff1a; 掌握一门…

【LeetCode - 每日一题】1090. 受标签影响的最大值 (2023.05.23)

1090. 受标签影响的最大值 题意 涉及两个数组的排序分别对两个数组的选择有不同的要求 解法1 排序 哈希 这道题本质上其实很简单&#xff0c;首先根据 labels 排序&#xff0c;当 labels 相同时&#xff0c;根据 values 从大到小排序&#xff0c;然后将每个 labels 的前 u…

学习open62541 --- [77] 修改String类型变量的注意点

对于String类型的节点&#xff0c;其值的类型是UA_String&#xff0c;在这篇文章中我们解释了UA_String的生成方法。 当我们修改String类型节点的值时&#xff0c;会事先准备一个UA_String变量&#xff0c;这时就会遇到一个选择&#xff1a;是否需要动态分配内存&#xff0c;即…

决策树及决策树的划分依据(ID3、C4.5、CART)

一、决策树是什么&#xff1f; 决策树是一种基于树状结构的机器学习算法&#xff0c;用于解决分类和回归问题。它是一种自上而下的递归分割方法&#xff0c;通过对特征空间的递归划分来构建一个树形模型&#xff0c;用于进行预测和决策。在决策树中&#xff0c;每个内部节点表…

数学算法组合与排序

一句话总结&#xff1a;组合得次序是否重要&#xff0c;是否可重复&#xff0c;决定了组合数量 一、什么是组合&排序 组合可以是现实的一切事物、例如 [衣服&#xff0c;鞋子&#xff0c;眼镜...] 等等&#xff0c; 也可以表示一组数字 [1, 2, 3, 4, 5] &#xff0c;从个人…

python3.8,torch1.10.2+cu113、torch-geometric 安装

【1】conda create -n name python=3.8 【2】安装 torch 注意先看可适应的最高cuda版本 https://data.pyg.org/whl/ 版本对应 【3】按照顺序安装torch-geometric: torch-sparse、torch-scatter、torch-cluster、 torch-spline-conv \torch-geometric pip install torc…