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

news2024/9/25 19:17:39

需求描述:

        由于某些情况下当查询过滤参数过大时,执行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.coloradmin.cn/o/1644497.html

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

相关文章

Vue3+vite优化基础架构(3)--- 优化vue-i18n国际化配置

Vue3vite优化基础架构&#xff08;3&#xff09;--- 优化vue-i18n国际化配置 说明全部页面进行中英文使用测试中英文切换对ElementPlus里面的所有组件进行中英文切换 说明 这里记录下自己在Vue3vite的项目增加全局中英文切换按钮对页面进行中英文切换及同时对ElementPlus里面的…

stm32单片机开发五、I2C通信

I2C这部分的时序单元可以看我另外一篇博客I2C基本知识 I2C发送数据时是高位先行&#xff0c;也就是先发送高位的&#xff0c;比如一个字节有8位B0-B7&#xff0c;先发送B7高位 I2C用的是同步时序&#xff0c;它有一个好处&#xff0c;比如传输过程中&#xff0c;出现了中断&…

深度学习之基于Pytorch姿态估计的仰卧起坐计数系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 仰卧起坐作为一种常见的健身动作&#xff0c;被广泛用于腹部肌肉的锻炼。然而&#xff0c;对于仰卧起…

(四)机器学习在银行中的典型应用场景(模型) #CDA学习打卡

本文总结了机器学习在银行中的典型业务应用场景&#xff0c;包括客户管理、零售智能营销、公司智能营销、自然语言处理、运营管理以及图像识别。

智慧园区sip对讲广播解决方案

智慧园区sip对讲广播解决方案18123651365 目前而言智慧园区管理者主要需要解决的问题是&#xff1a; 1.面对庞大的园区小区规模&#xff0c;能源管理全部依赖人工已经无法实现&#xff1b; 2.节能管理工作难度大&#xff0c;面对问题&#xff0c;没有好的解决方案&#xff1b; …

pyqt6的安装,使用-1

pyqt6安装的话&#xff0c;在自己所用的环境里安就可以&#xff0c;之前写有yolov5,yolov8的环境配置&#xff0c;python3.8的我安装就没有问题&#xff0c;打开anaconda&#xff0c;激活自己的环境 把这复制进去 pip install pyqt6 pip install pyqt6-tools 这个安装完了之后…

【JavaWeb】网上蛋糕项目商城-关键字搜索,购物车以及商品详情功能

概念 上文中已经实现热销和新品的商品列表功能&#xff0c;本文篇幅中实现关键字搜索商品&#xff0c;将商品加入购物车&#xff0c;以及查看商品的详情信息等功能 关键字搜索实现步骤 在head.jsp头部页面中&#xff0c;鼠标移动至搜索图标会显示隐藏的搜索框进行输入关键信…

数据结构(C):玩转链表

&#x1f37a;0.前言 言C之言&#xff0c;聊C之识&#xff0c;以C会友&#xff0c;共向远方。各位博友的各位你们好啊&#xff0c;这里是持续分享数据结构知识的小赵同学&#xff0c;今天要分享的数据结构知识是链表&#xff0c;在这一章&#xff0c;小赵将会向大家展开聊聊链表…

c语言排序算法之八(桶排序)

前言 以下内容是被验证可以有效理解桶排序&#xff0c;代码也较容易理解。如果你发现还有很多需要增加的&#xff0c;欢迎留言。 为什么要单独写排序算法这一系列&#xff0c;看过一些贴子普遍篇幅较长。看完依旧难以直观理解原理及整个过程。代码永远是基于理解的基础上才能…

Carla基础 | Carla预编译版安装与ROS联合仿真图文教程

目录 1 什么是Carla&#xff1f;2 Carla预编译版安装2.1 独立显卡配置2.2 安装ROS2.3 启动虚拟环境2.4 安装Carla预编译版2.5 安装carla-ros-bridge 3 测试案例常见问题 1 什么是Carla&#xff1f; Carla是由西班牙巴塞罗那自治大学计算机视觉中心指导开发的开源仿真模拟器&…

Redis-五大数据类型-Set(集合)

五大数据类型-Set&#xff08;集合&#xff09; 简介 与List类似是一个列表功能&#xff0c;但Set是自动排重的&#xff0c;当需要存储一个列表数据&#xff0c;又不希望出现重复数据时&#xff0c;Set是一个很好的选择。 Set是String类型的无序集合&#xff0c;它底层其实是…

学生宿舍智能电表系统改造升级意义

石家庄光大远通电气有限公司学生宿舍智能电表控制系统改造升级功能与意义** 一、实时监测 宿舍智能电表控制系统具备实时监测功能&#xff0c;能够实时收集、记录和分析每个宿舍的用电数据。这种监测不仅可以帮助管理者掌握用电情况&#xff0c;还可以为用户提供详细的用电报…

重生奇迹mu魔剑士怎么转职

重生奇迹MU中的魔剑士怎么才可以转职? 随便建个角色升级到220级&#xff0c;然后小退重建就有魔剑士了。另外魔剑不用二转。400的三转和其他职业一样。 战士不能转魔剑的。当帐号中已经拥有一位等级超过220级以上的角色时&#xff0c;才可以创造职业为魔剑士的新角色。 魔剑…

gcc编译器分析

gcc编译器分析 参考词法分析语法分析预读一个符号语法分析函数调用关系重点函数分析c_parse_filec_parser_translation_unit 参考 《gcc源码分析》 词法分析 词法分析的过程就是将源代码识别成一个一个的词法符号&#xff0c;并在词法分析的过程中创建一些树节点&#xff0c…

YashanDB与帆软信创商业智能软件完成兼容互认证

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB与帆软信创商业智能软件&#xff08;V6.0&#xff09;顺利完成兼容性互认证&#xff0c;经严格测试&#xff0c;双方产品能够相互兼容&#xff0c;稳定运行。 崖山数据库系统YashanDB是深圳计算科学研究院自主研发设计…

一分钱不花从HTTP升级到HTTPS

HTTP升级到HTTPS是一个涉及安全性和技术实施的过程&#xff0c;主要目的是为了提升网站数据传输的安全性&#xff0c;防止数据被窃取或篡改。以下是一些关于从HTTP升级到HTTPS的技术性要点和步骤概述&#xff0c;结合上述信息资源&#xff1a; 一、理解HTTPS的重要性 HTTPS (…

[图解]SysML和EA建模住宅安全系统-01

1 00:00:00,980 --> 00:00:03,100 接下来&#xff0c;我们来看一下案例 2 00:00:04,930 --> 00:00:06,750 我们这次课程的案例 3 00:00:07,090 --> 00:00:13,800 选用了SysML实用指南的书上 4 00:00:13,810 --> 00:00:16,180 第十七章这个案例 5 00:00:16,350 …

《QT实用小工具·五十六》自适应界面变化的控件

1、概述 源码放在文章末尾 该项目实现了网格显示多张带文字的图片在界面中自适应布局 特点 跟随窗口大小变换位置&#xff0c;并带移动动画 响应鼠标事件&#xff0c;图片缩放动画 点击水波纹动画 项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #i…

​可视化大屏C位图:3D模型,可视化大屏的画龙点睛之处

Hello&#xff0c;我是大千UI工场&#xff0c;本期可视化大屏的焦点图&#xff08;C位&#xff09;分享将图表作为焦点图的情形&#xff0c;欢迎友友们关注、评论&#xff0c;如果有订单可私信。 3D模型在可视化大屏中有很大的价值&#xff0c;以下是一些相关的优点&#xff1a…

优优嗨聚集团:法律明灯,个债处理中的法律咨询力量

在现代社会&#xff0c;个人债务问题日益突出&#xff0c;无论是因生活消费、投资失利还是其他原因&#xff0c;债务问题都可能成为个人财务的一大负担。面对复杂的债务困境&#xff0c;许多人感到迷茫和无助。此时&#xff0c;法律咨询如同一盏明灯&#xff0c;能够为个人债务…