学习记录:mybatis和jdbc实现数据表作为参数的相关的sql操作

一、业务场景

1.1 由于数据量非常大,需要根据根据id进行分表存储,减少数据的查询压力

1.2 使用工具类对id进行计算,保证插入表的随机性

二、jdbc插入和mybatis插入

mapper中的方法

复制代码
 int insertUser(@Param("user") User user, @Param("tableName") String tableName);

2.1 mybatis的xml

复制代码
    public Result insertUser(User user) {
        if (user == null || user.getId() == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        String tableName = TableRouter.routeTable(user.getId(), "user");
        User userById = this.getUserById(user.getId());
        if (userById != null) {
            return Result.error("用户ID已存在");
        }
        int i = userMapper.insertUser(user, tableName);
        if (i > 0) {
            return Result.success("用户插入成功");
        }else{
            return Result.error("用户插入失败");
        }
    }

MyBatis六种传参

mybatis 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="com.example.daythree.mapper.UserMapper">

    <!-- 通过拦截器自动处理表名 -->
    <select id="getUserById" resultType="com.example.daythree.domain.User">
        SELECT * FROM ${tableName} WHERE id = #{id}
    </select>

    <!-- 修正:如果id是自增主键,不要在INSERT中包含id -->
    <insert id="insertUser" parameterType="com.example.daythree.domain.User">
        INSERT INTO ${tableName}
            (id, name, email)
        VALUES
            (#{user.id}, #{user.name}, #{user.email})
    </insert>

    <!-- 方式一:通过拦截器处理表名 -->
    <select id="getUserByEmail" resultType="com.example.daythree.domain.User">
        SELECT * FROM ${tableName} WHERE email = #{email}
    </select>

</mapper>

ps:

主要将user插入指定表中

1.xml主要有三个参数 <id ,方法><parameterType,参数类型><resultType,返回类型>

2.主要是id和resultType,对于插入返回类型不用写 int类型

3.传入的user 使用#{user.id}获取相应的信息 可参考

2.2 jdbc插入

复制代码
    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;


public Result insertUser(User user) {
        if (user == null || user.getId() == null) {
            return Result.error("用户ID不能为空");
        }
        String tableName = TableRouter.routeTable(user.getId(), "user");
        String sql = "INSERT INTO " + tableName + " (id, name, email) VALUES (?,?,?)";
        try (Connection connection = DriverManager.getConnection(url, username, password);
             PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            preparedStatement.setLong(1, user.getId());
            preparedStatement.setString(2, user.getName());
            preparedStatement.setString(3, user.getEmail());
            preparedStatement.executeUpdate();
        }
        catch (SQLException e) {
            e.printStackTrace();
            return Result.error("用户插入失败,请检查是否id重复");
        }
        return Result.success("用户插入成功");
    }

通过@Value注入配置信息,然后写sql执行

三、分表工具类

复制代码
package com.example.daythree.utils;

import java.util.ArrayList;
import java.util.List;

public class TableRouter {

//    表的数量
    private static final int TABLE_COUNT = 2;

//    根据用户ID路由到对应的表
    public static String routeTable(Long id, String baseName) {
        if (id == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        int tableIndex = (int) (id % TABLE_COUNT);
        return baseName + "_" + tableIndex;
    }

//    获取所有用户表
    public static List<String> getAllUserTables(String baseName) {
        List<String> tables = new ArrayList<>(TABLE_COUNT);
        for (int i = 0; i < TABLE_COUNT; i++) {
            tables.add(baseName + "_" + i);
        }
        return tables;
    }
}

四.个人总结

  1. 业务场景就是分表存储 然后查询id 确定表查;查询其他信息 融合所有表查询

  2. 有些看似简单的操作,第一做问题很多,比如这里的指定表插入;平时mp使用多了,都不太会写mybatis的xml以及想不到jdbc插入

  3. 说明一下xml

User getUserByParam(Map<String, Object> params) 这样单个参数的 直接解析使用

<select id="getUserByParam" resultType="com.example.demo.model.User">

select `user_id`,`real_name`,`nick_name`,`sex`,`phone`,`password` from bss_user

where `phone` = #{phone} and `password` = #{password}

</select>

int insertUser(@Param("user") User user, @Param("tableName") String tableName);这样多个参数的必须指定@Param 调用必须使用Param中参数获取 比如 user.name

复制代码
<insert id="insertUser" parameterType="com.example.daythree.domain.User">
    INSERT INTO ${tableName}
        (id, name, email)
    VALUES
        (#{user.id}, #{user.name}, #{user.email})
</insert>

User getUserByParam(@Param("params") Map<String, Object> params);

<select id="getUserByParam" resultType="com.example.demo.model.User">

select `user_id`,`real_name`,`nick_name`,`sex`,`phone`,`password` from bss_user

where `phone` = #{params.phone} and `password` = #{params.password}

</select>

这里的params.phone相当于获取params的键phone的值

相关推荐
协同生态21 分钟前
天锐绿盾新版注册机【仅用于个人学习,禁止其他用途】
学习
Cuby!29 分钟前
【AFDM与信号处理:论文阅读】仿射频分复用:扩展OFDM以实现场景灵活性和弹性
论文阅读·笔记·学习·信息与通信·信号处理
AAA阿giao1 小时前
从零开始学 React:用搭积木的方式构建你的第一个网页!
前端·javascript·学习·react.js·前端框架·vite·jsx
Hello.Reader1 小时前
Flink SQL EXPLAIN “看懂计划”到“用 PLAN_ADVICE 调优”
大数据·sql·flink
Arciab1 小时前
C++ 学习_流程控制
c++·学习
HyperAI超神经1 小时前
【vLLM 学习】vLLM TPU 分析
开发语言·人工智能·python·学习·大语言模型·vllm·gpu编程
xiaoxiaoxiaolll1 小时前
前沿速递 | Adv. Eng. Mater.:基于LPBF与压力渗透的FeSi2.9-Bakelite多功能复合材料设计与性能调控
学习
Freshman小白1 小时前
《人工智能与创新》网课答案2025
人工智能·学习·答案·网课答案
Y_fulture1 小时前
datawhale组队学习:第一章习题
学习·机器学习·概率论
阿蒙Amon1 小时前
JavaScript学习笔记:15.迭代器与生成器
javascript·笔记·学习