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

32 篇文章 0 订阅
6 篇文章 0 订阅

需求描述:

        由于某些情况下当查询过滤参数过大时,执行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,整个项目代码结构

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用JdbcTemplate结合SpringSpring MVC可以更加方便地实现学生表student的增删改查。以下是一个简单的示例,演示如何使用JdbcTemplateSpringSpring MVC实现学生表的增删改查。 首先,你需要按照上述提到的步骤配置数据库连接和创建`Student`类。 接下来,你可以创建一个`StudentController`类来处理学生表的增删改查请求: ```java @Controller @RequestMapping("/student") public class StudentController { @Autowired private StudentService studentService; @GetMapping("/list") public String getAllStudents(Model model) { List<Student> students = studentService.getAllStudents(); model.addAttribute("students", students); return "studentList"; } @GetMapping("/{id}") public String getStudentById(@PathVariable int id, Model model) { Student student = studentService.getStudentById(id); model.addAttribute("student", student); return "studentDetail"; } @GetMapping("/add") public String showAddForm(Model model) { Student student = new Student(); model.addAttribute("student", student); return "addStudentForm"; } @PostMapping("/add") public String addStudent(@ModelAttribute("student") Student student) { studentService.addStudent(student); return "redirect:/student/list"; } @GetMapping("/{id}/edit") public String showEditForm(@PathVariable int id, Model model) { Student student = studentService.getStudentById(id); model.addAttribute("student", student); return "editStudentForm"; } @PostMapping("/{id}/edit") public String updateStudent(@PathVariable int id, @ModelAttribute("student") Student student) { student.setId(id); studentService.updateStudent(student); return "redirect:/student/list"; } @GetMapping("/{id}/delete") public String deleteStudent(@PathVariable int id) { studentService.deleteStudent(id); return "redirect:/student/list"; } } ``` 在上述代码中,`StudentController`类使用`StudentService`来处理学生表的增删改查操作,并通过Spring MVC的注解来定义不同的请求处理方法。 接下来,你可以创建一个`StudentService`类来实现学生表的增删改查逻辑: ```java @Service public class StudentService { @Autowired private StudentDao studentDao; public List<Student> getAllStudents() { return studentDao.getAllStudents(); } public Student getStudentById(int id) { return studentDao.getStudentById(id); } public void addStudent(Student student) { studentDao.addStudent(student); } public void updateStudent(Student student) { studentDao.updateStudent(student); } public void deleteStudent(int id) { studentDao.deleteStudent(id); } } ``` 在上述代码中,`StudentService`类调用`StudentDao`接口中定义的方法来实现学生表的增删改查操作。 最后,你可以使用Spring的配置文件来配置JdbcTemplate和其他相关的组件。假设你使用的是XML配置方式,你可以创建一个名为`applicationContext.xml`的配置文件,并添加以下配置: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置数据库连接 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/db_name" /> <property name="username" value="db_username" /> <property name="password" value="db_password" /> </bean> <!-- 配置JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 扫描注解 --> <context:component-scan base-package="com.example.yourpackage" /> </beans> ``` 在上述配置中,你需要将`com.example.yourpackage`替换为你实际的包名。 以上是一个简单的示例,你可以根据你的实际需求进行适当的修改和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远方的、远方的、、、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值