MyBatis 数据处理:主键获取、批量删除与动态表名

MyBatis 数据处理:主键获取、批量删除与动态表名

1.主键获取

        XML配置中使用了useGeneratedKeys="true"和keyProperty="id"来自动获取并设置插入后的自增主键。这是一个标准的做法。

1)mapper接口

/*** 添加数据时获取自增id*/
int addUserGetId(User user);

2)mapper.xml

<!--添加数据时获取自增主键-->
<insert id="addUserGetId" parameterType="org.xiji.enty.User" useGeneratedKeys="true" keyProperty="id">insert into user (username,password,userInfo) values(#{username},#{password},#{userInfo})
</insert>

3)测试代码

        在测试代码中,user.getId()应该能够返回插入后数据库自动生成的主键值。注意,这需要数据库支持自增主键,并且在JDBC连接中正确配置了自动生成主键的功能。

/*** 获取添加数据时的主键*/
@Test
public void testAddUserGetId()
{User user = new User();user.setUsername("test");user.setPassword("123456");user.setUserInfo("test");int id = specialMapper.addUserGetId(user);System.out.println("插入时,主键回显到传入的参数中"+user.getId());
}

4)测试结果

2.批量删除

        使用${ids}直接拼接SQL语句的方式存在SQL注入的风险,不建议使用。而使用<foreach>标签则是更安全的方式。

1)mapper接口

1-使用手动拼接字符串数组的方法
/*** 批量删除*/
int deleteBatch(String ids);

2-使用mybatis中的foreach标签
/*** 通过传入的数组*/
int deleteUserByArray(@Param("array") int[] array);

2)mapper.xml

1-使用手动拼接字符串数组的方法
<!--这种是手动拼接 批量删除获取参数-->
<delete id="deleteBatch" >delete from user where id in (${ids})
</delete>
2-使用mybatis中的foreach标签
<!--通过传入的数组-->
<!--批量删除获取参数-->
<delete id="deleteUserByArray" >delete from user where id  in <foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>

3)测试代码

        对于使用<foreach>标签的方法,测试代码看起来是正确的。注意,@Param("array") int[] array这样的参数传递方式是正确的,MyBatis会识别数组并正确地将其传递给SQL语句。

1-使用手动拼接字符串数组的方法
/*** 批量删除的特殊处理*/
@Test
public void testDeleteBatch()
{
//    手动把输入传入的集合转化为字符串,传入int result = specialMapper.deleteBatch("4,5,6");System.out.println(result);
}
2-使用mybatis中的foreach标签
/*** 通过传入数组批量删除*/
@Test
public void testAddUserByArray()
{int[] array = {2,7};int result = specialMapper.deleteUserByArray(array);System.out.println(result);
}

4)测试结果

1-使用手动拼接字符串数组的方法

2-使用mybatis中的foreach标签

这里删除第二条和第一条数据

3.动态设置表名

        动态设置表名时,使用${tableName}可以直接将变量值嵌入到SQL语句中,但这同样存在SQL注入的风险。如果tableName是从外部输入获得的话,请务必进行严格的验证和过滤。

1)mapper接口

/*** 动态设置表名*/
@MapKey("id")
List<Map<String,Object>> getUserByTableName(String tableName);

2)mapper.xml

/*** 动态设置表名*/
@MapKey("id")
List<Map<String,Object>> getUserByTableName(String tableName);

3)测试代码

        在测试代码中,动态设置表名的功能得到了验证,但是要注意在实际应用中确保表名的安全性。

/*** 动态获取设置表名*/
@Test
public void testGetUserByTableName(){System.out.println("查询第一张表");List<Map<String, Object>> user = specialMapper.getUserByTableName("user");for (int i = 0; i < user.size(); i++) {System.out.println(user.get(i).toString());}System.out.println(user);System.out.println("======================================================");System.out.println("查询第二张表");List<Map<String, Object>> user2 = specialMapper.getUserByTableName("user2");for (int i = 0; i < user2.size(); i++) {System.out.println(user2.get(i).toString());}System.out.println(user2);}

4)测试结果

user表的数据

user2表内容

5)扩展(水平分表的查询实现)

        对于水平分表的情况,需要根据ID来决定查询哪个表。在这个例子中,queryUserByTableName方法接收两个参数:id和tableName。然后根据id的值来决定查询哪个表。这种方式在处理分表的情况下是有效的,但同样要注意表名的安全性。

例:现在我们有一张表数据量太多了,想要垂直分表

下面是思路

user表有6条数据

我们想要从3号id开始垂直分,分到user2表中

1-mapper接口
/*** 水平分表*/
List<User> queryUserByTableName(@Param("id") int id,@Param("tableName") String tableName);
2-mapper.xml
<!--水平分表查询-->
<select id="queryUserByTableName"  resultType="org.xiji.enty.User" >select * from ${tableName} where id=#{id}</select>
3-test代码
@Test
public void testQueryUserByTableName2()
{//用于接受数据List<User> userList =null;int id = 2;/*** 随机查询*/for (int i = 0; i < 6; i++) {id = (int) (Math.random()*6);/*如果id等于零那就赋值唯1*/if (id == 0) {id = 1;}System.out.println("======================================================");System.out.println("请输入要查询的id"); //传入查询idif (id < 4 && id > 0) {userList = specialMapper.queryUserByTableName(id, "user");}if (id > 3 && id < 7) {userList=specialMapper.queryUserByTableName(id,"user2");}for (int j = 0; j < userList.size(); j++) {User user = userList.get(j);System.out.println(user.toString());}}}

4-测试结果

附录:

1 SpecialMapper文件

package org.xiji.mapper;import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.xiji.enty.User;import java.util.List;
import java.util.Map;@Mapper
public interface SpecialMapper {/*** 批量删除*/int deleteBatch(@Param("ids") String ids);/*** 动态设置表名*/@MapKey("id")List<Map<String,Object>> getUserByTableName(@Param("tableName") String tableName);/*** 添加数据时获取自增id*/int addUserGetId(User user);/*** 通过传入的数组*/int deleteUserByArray(@Param("array") int[] array);/*** 水平分表*/List<User> queryUserByTableName(@Param("id") int id,@Param("tableName") String tableName);
}

2 SpecialMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xiji.mapper.SpecialMapper"><!--添加数据时获取自增主键--><insert id="addUserGetId" parameterType="org.xiji.enty.User" useGeneratedKeys="true" keyProperty="id">insert into user (username,password,userInfo) values(#{username},#{password},#{userInfo})</insert><insert id="addUserByArray"></insert><!--通过传入的数组--><!--批量删除获取参数--><delete id="deleteUserByArray" >delete from user where id  in<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach></delete><!--动态设置表名--><select id="getUserByTableName" resultType="java.util.Map">select * from ${tableName}</select><!--水平分表查询--><select id="queryUserByTableName"  resultType="org.xiji.enty.User" >select * from ${tableName} where id=#{id}</select></mapper>

 3.SpecialMaperTest文件

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.xiji.enty.User;
import org.xiji.mapper.SpecialMapper;import java.util.List;
import java.util.Map;
import java.util.Scanner;@SpringJUnitConfig(locations = {"classpath:springConfig.xml"})
public class SpecialMapperTest {@Autowiredprivate SpecialMapper specialMapper;/*** 获取添加数据时的主键*/@Testpublic void testAddUserGetId(){User user = new User();user.setUsername("test");user.setPassword("123456");user.setUserInfo("test");int id = specialMapper.addUserGetId(user);System.out.println("插入时,主键回显到传入的参数中"+user.getId());}/*** 批量删除的特殊处理*/@Testpublic void testDeleteBatch(){int result = specialMapper.deleteBatch("4,5,6");System.out.println(result);}/*** 动态获取设置表名*/@Testpublic void testGetUserByTableName(){System.out.println("查询第一张表");List<Map<String, Object>> user = specialMapper.getUserByTableName("user");for (int i = 0; i < user.size(); i++) {System.out.println(user.get(i).toString());}System.out.println(user);System.out.println("======================================================");System.out.println("查询第二张表");List<Map<String, Object>> user2 = specialMapper.getUserByTableName("user2");for (int i = 0; i < user2.size(); i++) {System.out.println(user2.get(i).toString());}System.out.println(user2);}/*** 通过传入数组批量删除*/@Testpublic void testAddUserByArray(){int[] array = {2,7};int result = specialMapper.deleteUserByArray(array);System.out.println(result);}/*** 水平分表查询*/@Testpublic void testQueryUserByTableName(){/*** 模拟查询*///传入查询idint id = 2;List<User> user = specialMapper.queryUserByTableName(id, "user");User user1 = user.get(0);String username = user1.getUsername();System.out.println(username);System.out.println("======================================================");id = 5;List<User> user2 = specialMapper.queryUserByTableName(id, "user2");User user3 = user2.get(0);String username2 = user3.getUsername();System.out.println(username2);}@Testpublic void testQueryUserByTableName2(){//用于接受数据List<User> userList =null;int id = 2;/*** 随机查询*/for (int i = 0; i < 6; i++) {id = (int) (Math.random()*6);/*如果id等于零那就赋值唯1*/if (id == 0) {id = 1;}System.out.println("======================================================");System.out.println("请输入要查询的id");//传入查询idif (id < 4 && id > 0) {userList = specialMapper.queryUserByTableName(id, "user");}if (id > 3 && id < 7) {userList=specialMapper.queryUserByTableName(id,"user2");}for (int j = 0; j < userList.size(); j++) {User user = userList.get(j);System.out.println(user.toString());}}}}

4.user表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int NOT NULL AUTO_INCREMENT COMMENT '用户id',`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名字',`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户密码',`userInfo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户信息',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

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

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

相关文章

大数据处理技术:MapReduce综合实训

目录 1 实验名称 2 实验目的 3 实验内容 4 实验原理 5 实验过程或源代码 5.1 WordCount词频统计 5.2 HDFS文件读写 5.3 倒排索引 5.4 网页排序——PageRank算法 6 实验结果 6.1 WordCount词频统计 6.2 HDFS文件读写 6.3 倒排索引 6.4 网页排序——PageRank算法 1…

Spring Event 业务解耦神器(泛型喔!)

一.前言 又与我一直负责Cocos Creator的开发,我发现在TS领域,是可以自定义事件(有兴趣的大宝可以坐飞机直达:[CocosCreator]自定义事件(订阅/发布)管理器),这样做有什么好处呢?回答:解耦! 于是乎,我就觉得前端能干的事,后端也一样能干!当然,如果后端是TS或JS写的,比如nodeJS,…

『功能项目』切换职业面板【48】

我们打开上一篇47技能冷却蒙版的项目&#xff0c; 本章要做的事情是切换职业UI面板的功能 首先双击打开Canvas预制体在左上主角面板信息中新建一个button按钮 重命名&#xff08;父物体是按钮Button&#xff0c;子物体Image即可&#xff09; 创建一个Image 设计一下布局 复制三…

[进阶]面向对象之 包 final

文章目录 包什么是包包名的规则:什么时候需要导包 final常量 包 什么是包 包就是文件夹。用来管理各种不同功能的Java类&#xff0c;方便后期代码维护。 包名的规则: 公司域名反写包的作用&#xff0c;需要全部英文小写&#xff0c;见名知意。使用其他类时&#xff0c;需要…

上传头像,访问本地图片

文件大坑&#xff1a; web项目&#xff1a;首先不能直接访问本地资源&#xff0c;只能够访问服务器上的资源。 所以我想就储存数据到服务器&#xff0c;但是这样有个问题就是&#xff0c;当重新启动程序时&#xff0c;服务器上的所有文件会被重新编译&#xff0c;导致之前的文…

[数据集][图像分类]痤疮严重程度分级分类数据集999张3类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;999 分类类别数&#xff1a;3 类别名称:["Level_0","Level_…

[论文精读]Graph Neural Network-Based Anomaly Detection in Multivariate Time Series

论文网址&#xff1a;[2106.06947] Graph Neural Network-Based Anomaly Detection in Multivariate Time Series (arxiv.org) 论文代码&#xff1a;https://github.com/d-ailin/GDN 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的…

java的内存分配和回收机制

Java 与 C之间有一堵由内存动态分配和垃圾收集技术所围成的高墙&#xff0c;墙外面的人想进去&#xff0c;墙里面的人却想出来。 概述 垃圾收集&#xff08;GC&#xff09;需要完成的三件事情&#xff1a; 哪些内存需要回收&#xff1f;什么时候回收&#xff1f;如何回收&am…

4个方法教你图片转PDF怎么弄。

我们有时候会接触了一些重要的图片文件或者资料&#xff0c;想要装换成可编辑的PDF格式&#xff0c;更方便自己管理。这时候就会需要转换的工具&#xff0c;我这里就有&#xff14;款可以完成这种转换的高效工具可以分享给大家。 1、365PDF转换软件 直通车&#xff1a;www.pdf…

速通LLaMA1:《LLaMA: Open and Efficient Foundation Language Models》全文解读

文章目录 论文总览1. 创新点和突破点2. 技术实现与算法创新3. 架构升级4. 概念补充SwiGLU激活函数AdamW 5. 总结 AbstractIntroductionApproachPre-training DataArchitecture&#xff08;架构&#xff09;Optimizer&#xff08;优化器&#xff09;Efficient implementation&am…

[网络]https的概念及加密过程

文章目录 一. HTTPS二. https加密过程 一. HTTPS https本质上就是http的基础上增加了一个加密层, 抛开加密之后, 剩下的就是个http是一样的 s > SSL HTTPS HTTP SSL 这个过程, 涉及到密码学的几个核心概念 明文 要传输的真正意思是啥 2)密文 加密之后得到的数据 这个密文…

循环练习 案例

swich新特性 jdk12 穿透 逢七过 //含有七和被七整除舍去 public class test1 {public static void main(String[] args){for (int i 1; i <100 ; i) {if(i%70||i%107||i/107){continue;}System.out.println(i);}} } 求平方根 //输入大于2的整数&#xff0c;求平方根&…

linux---压缩打包

linux打包和压缩文件和目录&#xff1a; 归档(打包)命令&#xff1a;tar 归档就是将多个文件或者目录打包成为一个文件&#xff0c;存放再磁盘中&#xff0c;方便文件或者目录丢失时&#xff0c;可以恢复。 归档文件名使用相对路径 &#xff08;注意区分归档文件和被归档文…

LAMP+WordPress

一、简介 LAMP&#xff1a; L&#xff1a;linux——操作系统&#xff0c;提供服务器运行的基础环境。A&#xff1a;apache&#xff08;httpd&#xff09;——网页服务器软件&#xff0c;负责处理HTTP请求和提供网页内容。M&#xff1a;mysql&#xff0c;mariadb——数据库管理…

【网络安全的神秘世界】攻防环境搭建及漏洞原理学习

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 Kali安装docker 安装教程 PHP攻防环境搭建 中间件 介于应用系统和系统软件之间的软件。 能为多种应用程序合作互通、资源…

JavaScript高级——作用域和作用链

1、概念理解&#xff1a; —— 就是一块“地盘”&#xff0c;一个代码所在的区域 —— 静态的&#xff08;相对于上下文对象&#xff09;&#xff0c;在编写代码时就确定了 2、分类 ① 全局作用域 ② 函数作用域 ③ 没有块作用域&#xff08;ES6有了&#xff09; 3、作用 …

828华为云征文 | 云服务器Flexus X实例:多智能体对话框架 AutoGen 部署和实例运行

目录 一、什么是多智能体&#xff1f; 二、什么是 AutoGen&#xff1f; 三、部署 AutoGen 3.1 更新 apt 软件源 3.2 安装 python 3.10 3.3 安装 AutoGen 3.4 安装 AutoGen Studio 四、运行 AutoGen Studio 五、实例展示 5.1 构建实例 5.2 运行 六、总结 在体验了华为…

第 13 章 兵马未动,粮草先行——InnoDB 统计数据是如何收集的

表的统计数据&#xff1a;SHOW TABLE STATUS LIKE table_name; 索引的统计数据&#xff1a;SHOW INDEX FROM table_name; 13.1 两种不同的统计数据存储方式 InnoDB 提供了两种存储统计数据的方式&#xff1a; 永久性的统计数据。存储在磁盘上&#xff0c;服务器重启之后还在…

上图为是否色发

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

利士策分享,深耕一事:解锁专注秘诀

利士策分享&#xff0c;深耕一事&#xff1a;解锁专注秘诀 在信息洪流与诱惑交织的时代&#xff0c;专注成为稀缺能力。 我们常被社交媒体、工作邮件和琐事分散注意力&#xff0c;难以集中。 然而&#xff0c;专注是实现个人成长、职业发展和生活目标的基石。 要提升专注力&…