从CSV到数据库(简易)

需求:客户上传CSV文档,要求CSV文档内容查重/插入/更新相关数据。
框架:jdbcTemplate、commons-io、
DB:oracle

相关依赖:
这里本来打算用的2.11.0,无奈正式项目那边用老版本1.3.1,新版本对类型支持和转换好一点。不过无伤大雅。

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.1</version>
        </dependency>

CSV文档格式:

Xxx Code,Yerial,OP
600001,2024082400305, OP20240818_XDFD
600001,2024082400306, OP20240818_XDFD
600001,2024082400307, OP20240818_XDFD
600001,2024082400308, OP20240818_XDFD
600001,2024082400309, OP20240818_XDFD
600001,2024082400310, OP20240818_XDFD
600001,2024082400311, OP20240818_XDFD
600001,2024082400312, OP20240818_XDFD
600001,2024082400313, OP20240818_XDFD
600001,2024082400314, OP20240818_XDFD
600001,2024082400315, OP20240818_XDFD
600001,2024082400316, OP20240818_XDFD
600001,2024082400317, OP20240818_XDFD
600001,2024082400318, OP20240818_XDFD
600001,2024082400319, OP20240818_XDFD
600001,2024082400320, OP20240818_XDFD
600001,2024082400321, OP20240818_XDFD
600001,2024082400322, OP20240818_XDFD
600001,2024082400323, OP20240818_XDFD
600001,2024082400324, OP20240818_XDFD
600001,2024082400325, OP20240818_XDFD

接口:

MultipartFile接受CSV文件

    @PostMapping("/import")
    public ResponseEntity<BaseResponse<?>> importCSV(@RequestBody MultipartFile files) {
        xxxService.importSerial(files);
        return new ResponseEntity<>(new BaseResponse<>(), HttpStatus.OK);
    }

前段需要在Request-Body中以form-data的形式上传文档
在这里插入图片描述

CSV解析

简单转成Json

    private String convertCsvToJson(MultipartFile multipartFile) throws IOException {
        // read csv as list
        List<String> lines = IOUtils.readLines(multipartFile.getInputStream(), "UTF-8");

        List<List<String>> data = lines.stream()
                .skip(1) // skip label line
                .filter(line -> !line.trim().isEmpty()) // filtering empty line
                .map(line -> Arrays.asList(line.split(",")))
                .collect(Collectors.toList());

        return objectMapper.writeValueAsString(data);
    }

转换后是这样的:
注意这是print出来的json对象,本来应该是json字符串。

[
    ["600001","2024082400305","OP20240818_XDFD"],
    ["600001","2024082400306","OP20240818_XDFD"],
    ["600001","2024082400307","OP20240818_XDFD"],
    ["600001","2024082400308","OP20240818_XDFD"],
    ["600001","2024082400309","OP20240818_XDFD"],
    ["600001","2024082400310","OP20240818_XDFD"],
    ["600001","2024082400311","OP20240818_XDFD"],
    ["600001","2024082400312","OP20240818_XDFD"],
    ["600001","2024082400313","OP20240818_XDFD"],
    ["600001","2024082400314","OP20240818_XDFD"],
    ["600001","2024082400315","OP20240818_XDFD"],
    ["600001","2024082400316","OP20240818_XDFD"],
    ["600001","2024082400317","OP20240818_XDFD"],
    ["600001","2024082400318","OP20240818_XDFD"],
    ["600001","2024082400319","OP20240818_XDFD"],
    ["600001","2024082400320","OP20240818_XDFD"],
    ["600001","2024082400321","OP20240818_XDFD"],
    ["600001","2024082400322","OP20240818_XDFD"],
    ["600001","2024082400323","OP20240818_XDFD"],
    ["600001","2024082400324","OP20240818_XDFD"],
    ["600001","2024082400325","OP20240818_XDFD"]
]

以clob参数的形式传到oracle存储过程中处理

    public void import(MultipartFile files) {
        final int[] status = new int[1];
        Object result = jdbcTemplate.execute(new ConnectionCallback<Object>() {
            @Override
            public Object doInConnection(Connection con) throws SQLException, DataAccessException {
                CallableStatement cs = con.prepareCall("{call TEST_PACKAGE.pro_add_csv_data(?, ?)}");
                Clob clob = con.createClob(); // 创建一个Clob对象
                try {
                    String s = convertCsvToJson(files); // csv 转 json字符串
                    clob.setString(1, s); // 把json字符串封装进clob对象中
                    cs.setClob(1, clob);  // 入参
                    cs.registerOutParameter(2, Types.INTEGER); // 出参
                    cs.execute();
                    status[0] = cs.getInt(2); // 取结果
                } catch (IOException e) {
                    throw new RuntimeException("Import failed.");
                }
                return null;
            }
        });
    }

存储过程

PROCEDURE pro_add_csv_data(v_data_list IN CLOB,v_status OUT NUMBER) 
AS 
    v_code VARCHAR2(10);  
    v_yerial VARCHAR2(20);
    v_op VARCHAR2(20);
    v_cur SYS_REFCURSOR;
    EXC_EXIST EXCEPTION;
    v_count NUMBER;
    v_ref VARCHAR2(30) := TO_CHAR(SYSDATE, 'YYYYMMDDHH24MI');
BEGIN    
	-- 解析成表
    OPEN v_cur FOR    
        SELECT jt.*      
        FROM (    
            SELECT j.*    
            FROM JSON_TABLE(    
                v_data_list , '$[*]' COLUMNS (
                    code VARCHAR2(10) PATH '$[0]',        
                    yerial VARCHAR2(20) PATH '$[1]',        
                    op VARCHAR2(20) PATH '$[2]'        
                )              
            ) j    
        ) jt;  
    -- 遍历插入
    LOOP FETCH v_cur INTO v_code, v_yerial, v_op;  
    EXIT WHEN v_cur%NOTFOUND;
            INSERT INTO table_one
            VALUES( v_code,
                    v_yerial,
                    v_op
                   );
    END LOOP;
    
    COMMIT;
    CLOSE v_cur;
    v_status := 0;
EXCEPTION  
    WHEN EXC_EXIST THEN 
        ROLLBACK;
        v_status:=2;
    WHEN OTHERS THEN
        ROLLBACK;
        v_status:=1;
END pro_add_csv_data;

完美

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

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

相关文章

整数之间的赋值问题

前言&#xff1a;我们在初学C语言的时候&#xff0c;总是避免不了一些数据类型的转换&#xff0c;例如int-->char&#xff0c;char-->int&#xff0c;如果我们仅仅只学习这些语法&#xff0c;而不去了解底层原理&#xff0c;对于这些输出的内容&#xff0c;我们可能会感觉…

集成建筑5G商城为建筑行业开拓新方向

集成建筑5G商城为建筑行业开拓新方向 建筑业在我国有着悠久的发展历史&#xff0c;近年来&#xff0c;伴随着我国经济的快速增长、城镇化步伐加快&#xff0c;我国房地产、建筑业持续增长&#xff0c;建筑业显现出巨大的发展潜力。建筑行业近年来始终保持较高的增长速度。根据…

拉格朗日插值法的推导

1、插值的基本定义   设函数 y f ( x ) yf(x) yf(x)在区间 [ a , b ] [a,b] [a,b]上有定义&#xff0c;且已知它在 n 1 n1 n1个互异点 a ≤ x 0 < x 1 < . . . < x n ≤ b a\leq x_0<x_1<...<x_n\leq b a≤x0​<x1​<...<xn​≤b上的函数值 y 0 …

房产证上加名?手把手教你操作,省钱又省心!

随着《民法典》的实施&#xff0c;房产的权属问题愈发受到重视。夫妻双方及其亲属常希望能在房产证上增添自己的名字&#xff0c;以保障各自的权益。那么&#xff0c;房产证上到底能写几个名字呢&#xff1f;以下是对这一问题的详细解答。 一、房产证命名无固定限制 在购房时&…

MAB规范(1):概览介绍

前言 MATLAB的MAAB&#xff08;MathWorks Automotive Advisory Board&#xff09;建模规范是一套由MathWorks主导的建模指南&#xff0c;旨在提高基于Simulink和Stateflow进行建模的代码质量、可读性、可维护性和可重用性。这些规范最初是由汽车行业的主要厂商共同制定的&…

手写HTML字符串解析成对应的 AST语法树

先看效果 展示如下&#xff1a; HTML模版 转成ast语法树后 在学习之前&#xff0c;我们需要了解这么一个问题&#xff0c;为什么要将HTML字符串解析成对应的 AST语法树。 为什么&#xff1f; 语法分析&#xff1a;HTML字符串是一种标记语言&#xff0c;其中包含了大量的标签…

电动汽车电子系统架构

电动汽车的普及正在稳步发展&#xff0c;供应链的各个环节也在发生变化。它涵盖了制造电动汽车零件的原材料、化学品、电池和各种组件。与此同时&#xff0c;汽车充电基础设施也参与其中&#xff0c;它们正经历一个历史性的阶段&#xff0c;经过彻底的重新设计。它们的电气化以…

Echarts实现半圆形饼图,Echarts实现扇形图

效果预览,此处的双半圆扇形图是使用v-for循环的出来的 dom部分 <template><div><div class="mainDiv"><div class="headTit">全校平台最近作业</div><div class="loopSubject"><div id="app"…

反射获取成员变量

目录 利用反射获取成员变量 ​编辑 代码实现 获取class对象 获取成员变量 获取单个成员变量 获取成员变量的名字 获取权限修饰符 获取成员变量的数据类型 获取成员变量记录的值 修改对象里面记录的值 利用反射获取成员变量 代码实现 Student类&#xff1a; 获取clas…

JVM学习-类加载过程(二)

Initialization初始化阶段 为类的静态变量赋予正确的初始值 具体描述 类的初始化是类装载的最后一个阶段&#xff0c;如果前面的步骤没有问题&#xff0c;那么表示类可以顺利装载到系统中&#xff0c;此时&#xff0c;类才会开始执行Java字节码(即&#xff0c;到了初始化阶段…

使用YOLOv10训练自己的数据集

1. yolov10源码下载 THU-MIG/yolov10: YOLOv10: Real-Time End-to-End Object Detection (github.com)https://github.com/THU-MIG/yolov10?tabreadme-ov-file 2. 环境配置 预先安装好ANACONDA、PyCharm或者VSCode等基本软件。参考以下博客&#xff1a; 史上最全最详细的An…

六一礼物怎么选?来用python采集几套试卷送给小朋友们吧

马上要六一了&#xff0c;想一想我小时候的儿童节老师大概率都会布置一些试卷&#xff0c;所以也算是渡过了一个很"快乐"的童年呢。 所以今天这篇文章来采集一下试卷网中的试卷&#xff0c;快来学习一下&#xff0c;然后采集几套试卷送给你身边还在上学的小朋友们吧…

《面试笔记》——MySQL终结篇30

三大范式&#xff1f; 第一范式&#xff1a;字段具有原子性&#xff0c;不可再分&#xff08;字段单一职责&#xff09; 第二范式&#xff1a;满足第一范式&#xff0c;每行应该被唯一区分&#xff0c;加一列存放每行的唯一标识符&#xff0c;称为主键&#xff08;都要依赖主…

系统架构设计师【第10章】: 软件架构的演化和维护 (核心总结)

文章目录 10.1 软件架构演化和定义的关系10.1.1 演化的重要性10.1.2 演化和定义的关系 10.2 面向对象软件架构演化过程10.2.1 对象演化10.2.2 消息演化10.2.3 复合片段演化10.2.4 约束演化 10.3 软件架构演化方式的分类10.3.1 软件架构演化时期10.3.2 软件架构静态演…

第二十五章新增H5基础(以及视频~兼容)

1.HTML5中新增布局标签 HTML5新增了页眉&#xff0c;页脚&#xff0c;内容块等文档结构相关标签&#xff0c;可以使文档结构更加清晰明了。 1.新增的结构标签 1、<header>标签 定义文档或者文档中内容块的页眉。通常可以包含整个页面或一个内容区域的标题&#xff0c…

【Java】刚刚!突然!紧急通知!垃圾回收!

【Java】刚刚&#xff01;突然&#xff01;紧急通知&#xff01;垃圾回收&#xff01; 文章目录 【Java】刚刚&#xff01;突然&#xff01;紧急通知&#xff01;垃圾回收&#xff01;从C语言的内存管理引入&#xff1a;手动回收Java的垃圾回收机制引用计数器循环引用问题 可达…

支付宝支付-Java基于沙箱环境实现支付宝支付

一、支付宝沙箱环境介绍 沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境&#xff0c;开发者在沙箱环境中调用接口无需具备所需的商业资质&#xff0c;无需绑定和开通产品&#xff0c;同时不会对生产环境中的数据造成任何影响。合理使用沙箱环境&#xff0c;可以…

7-Django项目--账号管理

目录 templates/admin_role/admin_list.html ​编辑 templates/admin_role/add_modify.html views/admin_role.py 账号管理----> 账号添加 views.py 身份修改 views.py 重置密码 views.py templates/admin_role/admin_list.html {% extends "index/index.ht…

[有监督学习] 7.详细图解随机森林

随机森林 随机森林&#xff08;random forest&#xff09;是将多个模型综合起来创建更高性能模型的方法&#xff0c;既可用于回归&#xff0c;也可用于分类。同样的算法有梯度提升&#xff08;gradient boosting&#xff09;等在机器学习竞赛中很受欢迎的算法。 通过学习随机森…

SpringBoot整合jasypt加密配置文件敏感信息

SpringBoot整合jasypt加密配置文件敏感信息 在项目中我们需要对配置文件的一些敏感信息进行加密处理&#xff0c;比如数据库账户密码&#xff0c;避免直接暴露出来&#xff0c;这种场景常常用于生产环境&#xff0c;我们不想让开发人员知道生产库的密码&#xff0c;有运维人员…