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

news2024/9/22 14:31:41

目录

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

1.主键获取

1)mapper接口

2)mapper.xml

3)测试代码

4)测试结果

2.批量删除

1)mapper接口

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

2-使用mybatis中的foreach标签

2)mapper.xml

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

2-使用mybatis中的foreach标签

3)测试代码

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

2-使用mybatis中的foreach标签

4)测试结果

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

2-使用mybatis中的foreach标签

3.动态设置表名

1)mapper接口

2)mapper.xml

3)测试代码

4)测试结果

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

1-mapper接口

2-mapper.xml

3-test代码

4-测试结果

附录:

1 SpecialMapper文件

2 SpecialMapper.xml文件

 3.SpecialMaperTest文件

4.user表


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");
        //传入查询id
        if (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 mapper
        PUBLIC "-//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 {
    @Autowired
    private SpecialMapper specialMapper;


    /**
     * 获取添加数据时的主键
     */
    @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());
    }

    /**
     * 批量删除的特殊处理
     */
    @Test
    public void testDeleteBatch()
    {

        int result = specialMapper.deleteBatch("4,5,6");
        System.out.println(result);
    }

    /**
     * 动态获取设置表名
     */
    @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);

    }

    /**
     * 通过传入数组批量删除
     */
    @Test
    public void testAddUserByArray()
    {
        int[] array = {2,7};
        int result = specialMapper.deleteUserByArray(array);
        System.out.println(result);
    }

    /**
     * 水平分表查询
     */
    @Test
    public void testQueryUserByTableName()
    {


        /**
         * 模拟查询
         */


        //传入查询id
        int 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);


    }

    @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");
            //传入查询id
            if (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.coloradmin.cn/o/2138922.html

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

相关文章

【数据结构与算法 | 每日一题 | 力扣篇】力扣1184

1. 力扣1184&#xff1a;公交站间的距离 1.1 题目&#xff1a; 环形公交路线上有 n 个站&#xff0c;按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离&#xff0c;distance[i] 表示编号为 i 的车站和编号为 (i 1) % n 的车站之间的距离。 环线上的公交车…

微信支付开发-程序开发

一、操作流程图 二、后端代码实现 1、题库实现 a、列表、所有、详情、保存、启禁用、导入答题 b、获取奖品信息、保存奖品信息、 class Question extends Base {// 列表public function getList(){$param $this->request->param();$where [];if(!empty($param[title])…

spdlog二次封装

这里写自定义目录标题 封装的原因封装的思想初始化接口的封装对日志输出接口进行宏的封装 封装的原因 1.避免单例的锁冲突&#xff0c;因此直接创建全局的线程安全的日志器进行使用 2.因为日志输出没有文件名行号&#xff0c;因此使用宏进行二次封装输出日志的文件名和行号 3.…

【JavaScript】LeetCode:707设计链表

文章目录 题目内容题目分析(1) 获取第n个节点的值(2) 头部插入节点(3) 尾部插入节点(4) 第n个节点前插入节点(5) 删除第n个节点 完整代码 题目内容 题目分析 添加哨兵节点dummy。在第n个节点前插入节点时&#xff0c;应该找到第n - 1个节点&#xff08;即前一个节点&#xff0…

国内人工智能产业发展现状及对策研究

一、引言 人工智能作为新时代科技革命和产业变革的核心力量&#xff0c;正深刻改变着全球经济格局。我国政府高度重视人工智能产业发展&#xff0c;将其列为国家战略性新兴产业。在此背景下&#xff0c;本文旨在分析我国人工智能产业发展现状&#xff0c;探讨面临的挑战&#x…

java基础面试题总结

java基础面试题总结 目录 前言 1. JVM vs JDK vs JRE的了解 2. 谈谈你对编程、编译、运行的理解 3. 什么是字节码?采用字节码的好处是什么? 5. java中的注解有几种&#xff0c;分别是什么&#xff1f; 6. 字符型常量和字符串常量 7.标识符和关键字的认识 8. 泛型&#xff…

初识Verilog HDL其二

文章目录 运算符往期回顾 运算符 往期回顾 初识Verilog HDL其一

储能运维管理云平台解决方案EMS能量管理系统

在储能行业蓬勃发展的今天&#xff0c;储能运维管理的重要性日益凸显。而储能运维管理云平台的出现&#xff0c;正为储能系统的稳定运行和高效管理注入了新的活力。 一、储能运维管理面临的挑战 传统的储能运维管理方式往往依赖人工巡检和现场操作&#xff0c;存在诸多问题。比…

虚幻引擎 | 实时语音转口型 Multilingual lipsync

实时语音转口型&#xff1a;EPIC的metahuman sdk&#xff0c;NVIDIA的audio2face&#xff0c;都好。本文使用metahuman sdk 需要工具&#xff1a;Metahuman SDK网页账号&#xff0c;获取两日免费tokens https://space.metahumansdk.io/#/unauthorized ———————————…

6,csdn 语法

1 &#xff0c;标题 &#xff1a; 1.1 &#xff0c;语法 &#xff1a; 1 &#xff0c;语法 &#xff1a;几级标题&#xff0c;就几个井号   例如&#xff1a;### 1.1&#xff0c;语法 2 &#xff0c;小技巧 &#xff1a; 2.1&#xff0c;一条横线 &#xff1a; 1 &#x…

Table列表复现框实现【勾选-搜索-再勾选】

Table列表复现框实现【勾选-搜索-再勾选】 概要整体架构流程代码实现技术细节注意参考文献 概要 最近在开发时遇到一个问题&#xff0c;在进行表单渲染时&#xff0c;正常选中没有问题&#xff0c;单如果需要搜索选中时&#xff0c;一个是已选中的不会回填&#xff0c;二是在搜…

【运营攻略】怎样进行游戏产品的定位

关于游戏商业化设计的一些思考 - 游戏干饭之家 游戏运营进阶&#xff1a;数据分析驱动游戏版本调优 - 游戏干饭之家 在深入挖掘某款游戏数据时&#xff0c;发现了一个有趣的现象&#xff1a;70%的玩家好友数量在1-5个之间&#xff0c;11%的玩家好友数在6-10个&#xff0c;而平…

Fiddler下载安装及汉化

直接上干货 1.下载地址&#xff1a; 通过百度网盘分享的文件&#xff1a;fiddler汉化&#xff0c;FiddlerSetup抓包.exe等2个文件 链接&#xff1a;https://pan.baidu.com/s/12JBZO8z0mDHlHM1DCL365g 提取码&#xff1a;1111 2.fiddler安装&#xff1a; 注意安装位置 3.汉化&…

基于协同过滤+python+django+vue+的音乐推荐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…

计算机毕业设计 在线新闻聚合平台的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

象过河手机进销存,外出办公更方便,随时了解经营情况

你还在为外出时无法即时查看库存、处理订单而烦恼吗&#xff1f;电脑端进销存虽强&#xff0c;但一离开办公桌就仿佛与店铺“失联”&#xff0c;那些紧急的调货请求、客户咨询&#xff0c;都让人手忙脚乱&#xff01; 这里强烈推荐你试试【象过河手机进销存】&#xff0c;它就像…

计算机网络入门基础

1. 基础概念 我们在聊网络的时候&#xff0c;就像是我们在日常生活中寄信一样。我们可以把网络想象成一个巨大的邮局系统&#xff0c;负责把信息从一个地方传送到另一个地方。 a. 什么是协议栈&#xff1f; 协议栈就像是寄信过程中的多个步骤。我们可以把它想象成寄信的时候…

Python3 SMTP发送邮件

SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;由它来控制信件的中转方式。 python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。 Python创建 SM…

Kotlin:1.9.0 的新特性

一、概述 Kotlin 1.9.0版本英语官方文档 Kotlin 1.9.0 中文官方文档 The Kotlin 1.9.0 release is out and the K2 compiler for the JVM is now in Beta. Additionally, here are some of the main highlights: Kotlin 1.9.0版本已经发布&#xff0c;用于JVM的K2编译器现在…

运用Java实现倒计时功能

这个功能其实是比较好实现的&#xff0c;一般来说java中实现倒计时有两种方法&#xff1a; 1、使用 scheduledexecutorservice创建一个可重复执行的任务&#xff0c;直到时间到&#xff1a; ScheduledExecutorService 是 Java 中一种用于安排延迟或定期任务的工具。我们可以使…