Spring JdbcTemplate使用临时表+事务会话管理实现数据新增、查询及自动清除功能

需求描述:

        由于某些情况下当查询过滤参数过大时,执行sql由于参数过大而报错,此时 需要使用临时表的方式,即 当参数超过某个阀值(如 1000,可调整)新增一张临时表,将原表 与 该临时表进行inner join 达到条件筛选过滤的目的(当然,除了这种方式,还可以考虑 将参数进行切片后分批次查询组装)。

实操步骤:

        1,建表语句

CREATE TABLE T3 (
	STRING_VALUE VARCHAR(512),
	DATA_TYPE VARCHAR(128),
	STRING_VALUE1 VARCHAR(512),
	STRING_VALUE2 VARCHAR(1024)
);

CREATE GLOBAL TEMPORARY TABLE T3_DATA_TEMP (
	STRING_VALUE VARCHAR(512),
	DATA_TYPE VARCHAR(128),
	STRING_VALUE1 VARCHAR(512),
	STRING_VALUE2 VARCHAR(1024)
);

        2,引入需要的pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>testMybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 父项目信息 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.8</version>
        <relativePath/>
    </parent>
    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!-- 高斯DB驱动 -->
        <dependency>
            <groupId>com.huawei.gauss</groupId>
            <artifactId>com.huawei.gauss.jdbc.ZenithDriver</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

        3,编写application.properties文件

       

spring.datasource.url=jdbc:zenith:@xxx:xxxx
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.huawei.gauss.jdbc.inner.GaussDriver
mybatis.mapper-locations=classpath:mapper/*.xml

org.apache.springframework.jdbc.core.JdbcTemplate = debug



        4,编写 dao 层接口代码

package com.example.dao;

import com.example.entity.DataTemp;

import java.util.List;

public interface DataTempDao {

    void batchInsert(String dataType, List<?> values);

    void batchInsert(List<DataTemp> records);

    List<String> queryForList();

    void batchInsertmy_session_data(List<DataTemp> records);

    void createTempTable();

    List<String> queryValueList();

    List<String> queryValueListT3();

    void batchInsertT3(List<DataTemp> records);
}

        5,dao 层实现

package com.example.dao.impl;

import com.example.dao.DataTempDao;
import com.example.entity.DataTemp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Repository
public class DataTempDaoImpl implements DataTempDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void batchInsert(String dataType, List<?> values) {
        if (CollectionUtils.isEmpty(values)) {
            return;
        }
        batchInsert(values.stream().map(value -> new DataTemp(dataType, value.toString())).collect(Collectors.toList()));
    }

    @Override
    public void batchInsert(List<DataTemp> records) {
        String sql = "insert into t_comm_data_temp(data_type, string_value, string_value1, string_value2) values(?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql, records, records.size(), (ps, record) -> {
            ps.setString(1, record.getDataType());
            ps.setString(2, record.getStringValue());
            ps.setString(3, record.getStringValue1());
            ps.setString(4, record.getStringValue2());
        });
    }

    @Override
    public void batchInsertT3(List<DataTemp> records) {
//        String sql = "insert into t3(data_type, string_value, string_value1, string_value2) values(?, ?, ?, ?)";
        String sql = "insert into t3_data_temp(data_type, string_value, string_value1, string_value2) values(?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql, records, records.size(), (ps, record) -> {
            ps.setString(1, record.getDataType());
            ps.setString(2, record.getStringValue());
            ps.setString(3, record.getStringValue1());
            ps.setString(4, record.getStringValue2());
        });
    }

    @Override
    public List<String> queryForList() {
        String sql = "select string_value from t_comm_data_temp";
        return jdbcTemplate.queryForList(sql, String.class);
    }

    @Override
    public List<String> queryValueListT3() {
//        String sql = "select string_value from t3";
        String sql = "select string_value from t3_data_temp";
        return jdbcTemplate.queryForList(sql, String.class);
    }

    @Override
    public void batchInsertmy_session_data(List<DataTemp> records) {
        String sql = "insert into `#my_session_data`(data_type, string_value, string_value1, string_value2) values(?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql, records, records.size(), (ps, record) -> {
            ps.setString(1, record.getDataType());
            ps.setString(2, record.getStringValue());
            ps.setString(3, record.getStringValue1());
            ps.setString(4, record.getStringValue2());
        });
    }

    @Override
    public void createTempTable() {
        String sql = "CREATE TEMPORARY TABLE `#my_session_data` (  \n" +
                "    STRING_VALUE VARCHAR(512),\n" +
                "    DATA_TYPE VARCHAR(128),\n" +
                "    STRING_VALUE1 VARCHAR(512),\n" +
                "    STRING_VALUE2 VARCHAR(1024)\n" +
                ")";
        jdbcTemplate.execute(sql);
    }

    @Override
    public List<String> queryValueList() {
        String sql1 = "select string_value from `#my_session_data`";
        return jdbcTemplate.queryForList(sql1, String.class);
    }
}

        6,启动类

        

package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")
public class DemoApplication {


    public static void main(String[] args) {

        SpringApplication.run(DemoApplication.class, args);
    }

}

        7,编写单元测试类(涵盖业务流程)


import com.example.DemoApplication;
import com.example.dao.DataTempDao;
import com.example.dao.T1Dao;
import com.example.entity.DataTemp;
import com.example.entity.T1;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
@Slf4j
public class SpringTest {

    @Autowired
    DataTempDao dataTempDao;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    T1Dao t1Dao;

    @Test
    public void test1(){
        List<DataTemp> list = new ArrayList<>(10);
        DataTemp dataTemp = new DataTemp();
        dataTemp.setDataType("test");
        dataTemp.setStringValue("111");
        dataTemp.setStringValue1("1");
        dataTemp.setStringValue2("2");
        list.add(dataTemp);
        dataTempDao.batchInsert(list);
        //查询
        List<String> dataTemps = dataTempDao.queryForList();
        log.info("查询有:{}条数据!",dataTemps.size());
    }

    /**
     * 测试查询
     */
    @Test
    public void test2(){
        //查询
        String sql = "select * from T1";
        List<Map<String, Object>> query = jdbcTemplate.query(sql, new ColumnMapRowMapper());
        query.stream().forEach(v->{
            v.entrySet().stream().forEach(w->{
                log.info("key:{},value:{}",w.getKey(),w.getValue());
            });
        });
    }

    /**
     * 测试单条新增
     */
    @Test
    public void test3(){
        T1 t1 = new T1();
//        t1.setId(1L);
        t1.setData(new Timestamp(System.currentTimeMillis()));
        t1.setA("A");
        t1.setB("B");
        t1Dao.save(t1);
    }

    /**
     * 测试批量新增
     */
    @Test
    public void test4(){
        List<T1> list = new ArrayList<>(4);
        for (int i = 0; i < 4; i++) {
            T1 t1 = new T1();
            t1.setId(Long.valueOf(i));
            t1.setData(new Timestamp(System.currentTimeMillis()));
            t1.setA("A"+i);
            t1.setB("B"+i);
            list.add(t1);
        }
        t1Dao.batchInsert(list);
    }

    /**
     * 临时表测试
     * 同一个 session下的表才能查询到,即 每次创建完表执行操作后,session结束时会自动把数据及表清除掉,下次再执行时重新开始
     */
    @Test
    public void test5(){
        dataTempDao.createTempTable();
        log.info("建表完成!");

        List<DataTemp> list = new ArrayList<>(10);
        DataTemp dataTemp = new DataTemp();
        dataTemp.setDataType("test");
        dataTemp.setStringValue("111");
        dataTemp.setStringValue1("1");
        dataTemp.setStringValue2("2");
        list.add(dataTemp);
        dataTempDao.batchInsertmy_session_data(list);
        //查询
        List<String> dataTemps = dataTempDao.queryValueList();
        log.info("总共有:{} 条数据!",dataTemps.size());
    }

    @Test
    @Transactional
    public void test6(){
        List<DataTemp> list = new ArrayList<>(10);
        DataTemp dataTemp = new DataTemp();
        dataTemp.setDataType("test");
        dataTemp.setStringValue("111");
        dataTemp.setStringValue1("1");
        dataTemp.setStringValue2("2");
        list.add(dataTemp);
        dataTempDao.batchInsertT3(list);
        //查询
        List<String> dataTemps = dataTempDao.queryValueListT3();
        log.info("查询有:{}条数据!",dataTemps.size());
    }

}

        注意:要想实现 插入数据 与 查询 在同一个会话中实现,这里采用最简单的实现方式:事务  来实现,即 方法上加上注解   @Transactional 即可

8,整个项目代码结构

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024精武杯部分复现

首先是计算机部分&#xff0c;这里是题目 做完才发现其实很多东西在火眼里面已经有更快的捷径了&#xff0c;但是自己当时没发现&#xff0c;还去傻傻的开虚拟机去找&#xff0c;说到底&#xff0c;还是对取证软件的理解不够&#xff0c;也不怎么会用。不废话了&#xff0c;直接…

怎么给word文件名批量替换部分文字?word设置批量替换文字教程

批量替换Word文件名中的几个字&#xff0c;对于经常处理大量文件的人来说&#xff0c;是一项非常实用的技能。以下是一个详细的步骤指南&#xff0c;帮助你快速完成这项任务。 首先&#xff0c;你需要准备一个可以批量重命名文件的工具。市面上有很多这样的工具可供选择&#x…

人工智能的发展将如何重塑网络安全

微信搜索关注公众号网络研究观&#xff0c;获取更多信息。 人们很容易认为人工智能 (AI) 真正出现是在 2019 年&#xff0c;当时 OpenAI 推出了 ChatGPT 的前身 GPT-2。 但现实却有些不同。人工智能的基础可以追溯到 1950 年&#xff0c;当时数学家艾伦图灵发表了题为“计算机…

密码学《图解密码技术》 记录学习 第十四章

目录 十四章 14.1 本章学习的内容 14.2 什么是 SSL/TLS 14.2.1 Alice 在 Bob 书店买书 14.2.2 客户端与服务器 14.2.3 АSSL/TLS 承载HTTP 14.2.4 SSL/TLS的工作 14.2.5 SSL/TLS也可以保护其他的协议 14.2.6 密码套件 14.2.7 SSL 与 TLS 的区别 14.3 使用 SSL/TLS 进…

产业观察:电机驱动成为人形机器人的动力核心

前不久&#xff0c;波士顿动力发布一则“再见&#xff0c;液压Atlas”视频&#xff0c;宣告其著名的液压驱动双足人形机器人Atlas正式退役。这则视频引起全球所有Atlas粉丝的高度关注。然而紧接着&#xff0c;波士顿动力便又推出了全部由电机驱动的新一代Atlas机器人&#xff0…

【Git】【MacOS】Github从创建与生成SSH公钥

创建账号 这一步不过多赘述&#xff0c;根据自己的邮箱新创建一个账号 配置SSH公钥 本人是macOS系统&#xff0c;首先从终端输入 cd ~/.ssh进入.ssh目录,然后通过 ls查看有没有一个叫做id_rsa.pub的文件 本人之前生成过SSH公钥,如果没有的话&#xff0c;通过 ssh-keygen -t…

luci框架相关笔记

luci架构 LuCI 架构采用了MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;各个目录的作用如下&#xff1a; model&#xff08;模型&#xff09;: 位于 /usr/lib/lua/luci/model 下&#xff0c;存放了与系统配置相关的模型脚本。这些脚本负责与底层系统…

cmd输入mysql -u root -p无法启动

问题分析&#xff1a;cmd输入mysql -u root -p无法启动 解决方法&#xff1a;配置系统环境变量 1.找到mysql安装文件下的bin文件&#xff1a;&#xff08;复制改文件地址,如下图所示&#xff09; 2.电脑桌面下方直接搜索环境变量并进入&#xff0c;如下图 3.点击环境变量&a…

读取打包到JAR中的文件:常见问题与解决方案(文件在但是报错not find)

读取打包到JAR中的文件&#xff1a;常见问题与解决方案 喝淡酒的时候&#xff0c;宜读李清照&#xff1b;喝甜酒时&#xff0c;宜读柳永&#xff1b;喝烈酒则大歌东坡词。其他如辛弃疾&#xff0c;应饮高梁小口&#xff1b;读放翁&#xff0c;应大口喝大曲&#xff1b;读李后主…

Python数据清洗与可视化实践:国际旅游收入数据分析

文章目录 概要整体流程名词解释NumPyPandasMatplotlibre 技术细节数据清洗可视化 小结 概要 在本篇博客中&#xff0c;我们将通过一个实际的案例&#xff0c;演示如何使用Python进行数据清洗和可视化&#xff0c;以分析国际旅游收入数据。我们将使用Python中的Pandas库来进行数…

04-25 周四 FastBuild重构实践-TLS、全局捕获异常、一键配置

04-25 周四 FastBuild重构实践 时间版本修改人描述04-25V0.1宋全恒新建文档2024年5月6日14:33:16V1.0宋全恒完成文档撰写 简介 由于 04-22 周日 阿里云-瑶光上部署FastBuild过程(配置TLS、自定义辅助命令)描述了重新部署一个FastBuild实例的过程&#xff0c;通过阅读这个&…

线性表的概念与结构,以及顺序表和链表的简单概念

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

JS hook cookie

JS hook cookie cookie 的值是V&#xff0c;v是动态变化的 可以看到D中生成了cookie的值n 尝试使用RPC定位到cookie。 替换内容&#xff0c;下断点。 将写好的RPC代码直接插入 加入代码&#xff0c;file.virjar.com/sekiro_web_client.js?_123 这个地址是在前端创建客户端…

开源模型应用落地-CodeQwen模型小试-小试牛刀(一)

一、前言 代码专家模型是基于人工智能的先进技术&#xff0c;它能够自动分析和理解大量的代码库&#xff0c;并从中学习常见的编码模式和最佳实践。这种模型可以提供准确而高效的代码建议&#xff0c;帮助开发人员在编写代码时避免常见的错误和陷阱。 通过学习代码专家模型&…

【网络知识】光猫、路由器 和 交换机 的作用和区别?

数字信号&#xff1a;是指自变量是离散的、因变量也是离散的信号&#xff0c;这种信号的自变量用整数表示&#xff0c;因变量用有限数字中的一个数字来表示。在计算机中&#xff0c;数字信号的大小常用有限位的二进制数表示。 模拟信号&#xff1a;模拟信号是指用连续变化的物…

学习c#第26天 面向对象基础之类与对象

1.类 1.什么是类? 俗话说&#xff0c;“物以类聚&#xff0c;人以群分”。意思是同类的东西经常聚在一起&#xff0c;志同道合 的人相聚成群。前者说物&#xff0c;后者说人。这里以物来进行举例说明[见图]&#xff1a; 水果超市&#xff0c;所有同类的水果摆放在一起&#xf…

【机器学习与实现】线性回归分析

目录 一、相关和回归的概念&#xff08;一&#xff09;变量间的关系&#xff08;二&#xff09;Pearson&#xff08;皮尔逊&#xff09;相关系数 二、线性回归的概念和方程&#xff08;一&#xff09;回归分析概述&#xff08;二&#xff09;线性回归方程 三、线性回归模型的损…

vivado刷题笔记46

题目&#xff1a; Design a 1-12 counter with the following inputs and outputs: Reset Synchronous active-high reset that forces the counter to 1 Enable Set high for the counter to run Clk Positive edge-triggered clock input Q[3:0] The output of the counter c…

场外个股期权和场内个股期权的优缺点是什么?

场外个股期权和场内个股期权的优缺点 场外个股期权是指在沪深交易所之外交易的个股期权&#xff0c;其本质是一种金融衍生品&#xff0c;允许投资者在股票交易场所外以特定价格买进或卖出证券。场内个股期权是以单只股票作为标的资产的期权合约&#xff0c;其内在价值是基于标…

金融业开源软件应用 管理指南

金融业开源软件应用 管理指南 1 范围 本文件提供了金融机构在应用开源软件时的全流程管理指南&#xff0c;对开源软件的使用和管理提供了配套 组织架构、配套管理规章制度、生命周期流程管理、风险管理、存量管理、工具化管理等方面的指导。 本文件适用于金融机构规范自身对开…
最新文章