工具类-csv文件导入数据库思路

首先,让我们来看下数据库建表语句:

CREATE TABLE behavior_reports (id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '报告ID',report_type VARCHAR(50) NOT NULL COMMENT '报告类型(daily, weekly, monthly)',start_date DATE NOT NULL COMMENT '开始日期',end_date DATE NOT NULL COMMENT '结束日期',total_users INT DEFAULT 0 COMMENT '总用户数',active_users INT DEFAULT 0 COMMENT '活跃用户数',total_visits INT DEFAULT 0 COMMENT '总访问量',avg_duration INT DEFAULT 0 COMMENT '平均停留时长(秒)',bounce_rate DECIMAL(5,2) DEFAULT 0 COMMENT '跳出率(%)',conversion_rate DECIMAL(5,2) DEFAULT 0 COMMENT '转化率(%)',retention_rate DECIMAL(5,2) DEFAULT 0 COMMENT '留存率(%)',report_data JSON COMMENT '详细报告数据',created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',INDEX idx_report_type (report_type),INDEX idx_date_range (start_date, end_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='行为分析报告表';

然后,引入依赖opencsv

        <dependency><groupId>com.opencsv</groupId><artifactId>opencsv</artifactId><version>5.7.1</version></dependency></dependencies>

实现步骤

1、创建一个工具类CsvImportUtil

package com.useranalysis.util;import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvValidationException;
import com.useranalysis.entity.BehaviorReport;
import com.useranalysis.mapper.BehaviorReportMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;/*** CSV 数据导入工具类* 用于将 CSV 文件数据导入到数据库中*/
@Slf4j
@Component
@RequiredArgsConstructor
public class CsvImportUtil {private final BehaviorReportMapper behaviorReportMapper;/*** 导入行为分析报告数据* @param csvFilePath CSV 文件路径* @return 导入的记录数*/public int importBehaviorReports(String csvFilePath) {int importCount = 0;//1、借助CSVReader读取CSV文件try (CSVReader reader = new CSVReader(new FileReader(csvFilePath))) {// 2、跳过CSV文件的表头reader.readNext();//3、逐行解析 CSV 文件,把每行数据转换为 BehaviorReport 对象。String[] line;List<BehaviorReport> reports = new ArrayList<>();//4、把解析后的 BehaviorReport 对象添加到列表中while ((line = reader.readNext()) != null) {try {BehaviorReport report = parseBehaviorReport(line);reports.add(report);importCount++;//5、每100条记录批量插入一次if (reports.size() >= 100) {behaviorReportMapper.batchInsert(reports);reports.clear();}} catch (Exception e) {log.error("解析行数据失败: {}", String.join(",", line), e);}}//6、插入剩余不足100条的记录if (!reports.isEmpty()) {behaviorReportMapper.batchInsert(reports);}log.info("成功导入 {} 条行为分析报告数据", importCount);} catch (IOException | CsvValidationException e) {log.error("导入 CSV 文件失败: {}", csvFilePath, e);throw new RuntimeException("导入 CSV 文件失败", e);}//7、返回导入的记录数return importCount;}/*** 解析单行 CSV 数据为 BehaviorReport 对象* @param line CSV 行数据* @return BehaviorReport 对象*/private BehaviorReport parseBehaviorReport(String[] line) {DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");DateTimeFormatter timestampFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//创建 BehaviorReport 对象BehaviorReport report = new BehaviorReport();//设置 BehaviorReport 对象的属性report.setId(Long.parseLong(line[0]));report.setReportType(line[1]);report.setStartDate(LocalDate.parse(line[2], dateFormatter));report.setEndDate(LocalDate.parse(line[3], dateFormatter));report.setTotalUsers(Integer.parseInt(line[4]));report.setActiveUsers(Integer.parseInt(line[5]));report.setTotalVisits(Integer.parseInt(line[6]));report.setAvgDuration(Integer.parseInt(line[7]));report.setBounceRate(new BigDecimal(line[8]));report.setConversionRate(new BigDecimal(line[9]));report.setRetentionRate(new BigDecimal(line[10]));report.setReportData(line[11]);report.setCreatedAt(LocalDateTime.parse(line[12], timestampFormatter));//返回 BehaviorReport 对象return report;}
} 

2、创建实体类BehaviorReport

package com.useranalysis.entity;import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.math.BigDecimal;@Data
@NoArgsConstructor
@AllArgsConstructor
public class BehaviorReport {private Long id;private String reportType;private LocalDate startDate;private LocalDate endDate;private Integer totalUsers;private Integer activeUsers;private Integer totalVisits;private Integer avgDuration;private BigDecimal bounceRate;private BigDecimal conversionRate;private BigDecimal retentionRate;private String reportData;private LocalDateTime createdAt;
} 

3、创建mapper接口BehaviorReportMapper

package com.useranalysis.mapper;import com.useranalysis.entity.BehaviorReport;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;@Mapper
public interface BehaviorReportMapper {/*** 批量插入行为分析报告数据* @param reports 报告数据列表* @return 插入的记录数*/int batchInsert(@Param("reports") List<BehaviorReport> reports);
} 

4、创建xml映射BehaviorReportMapper.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.useranalysis.mapper.BehaviorReportMapper"><insert id="batchInsert" parameterType="java.util.List">INSERT INTO behavior_reports (id, report_type, start_date, end_date, total_users, active_users,total_visits, avg_duration, bounce_rate, conversion_rate,retention_rate, report_data, created_at) VALUES <foreach collection="reports" item="report" separator=",">(#{report.id}, #{report.reportType}, #{report.startDate},#{report.endDate}, #{report.totalUsers}, #{report.activeUsers},#{report.totalVisits}, #{report.avgDuration}, #{report.bounceRate},#{report.conversionRate}, #{report.retentionRate}, #{report.reportData},#{report.createdAt})</foreach></insert>
</mapper> 

使用方法

1、首先,确保已经创建了数据库表

2、在需要导入数据的地方调用

@Autowired
private CsvImportUtil csvImportUtil;// 在需要导入数据的地方调用
String csvFilePath = "src/main/resources/static/CSV_test/behavior_reports.csv";
int importCount = csvImportUtil.importBehaviorReports(csvFilePath);

csv直接导入数据库中

1、创建数据库表

2、编写测试类或controller接口

测试类CsvImportTest

package com.useranalysis;import com.useranalysis.util.CsvImportUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;@SpringBootTest
@ActiveProfiles("test")
public class CsvImportTest {@Autowiredprivate CsvImportUtil csvImportUtil;@Testpublic void testImportCsv() {// CSV文件路径String csvFilePath = "src/main/resources/static/CSV_test/behavior_reports.csv";// 导入数据int importCount = csvImportUtil.importBehaviorReports(csvFilePath);// 打印导入结果System.out.println("成功导入 " + importCount + " 条记录");}
} 

controller接口CsvImportController

package com.useranalysis.controller;import com.useranalysis.util.CsvImportUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api/csv")
@RequiredArgsConstructor
public class CsvImportController {private final CsvImportUtil csvImportUtil;@PostMapping("/import")public ResponseEntity<String> importCsv() {try {String csvFilePath = "src/main/resources/static/CSV_test/behavior_reports.csv";int importCount = csvImportUtil.importBehaviorReports(csvFilePath);return ResponseEntity.ok("成功导入 " + importCount + " 条记录");} catch (Exception e) {return ResponseEntity.internalServerError().body("导入失败:" + e.getMessage());}}
} 

3、使用命令执行

运行测试类

mvn test -Dtest=CsvImportTest

通过api接口导入

curl -X POST http://localhost:8080/api/csv/import

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

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

相关文章

软件工程之软件开发模型(瀑布、迭代、敏捷、DevOps)

1. 瀑布模型&#xff08;Waterfall Model&#xff09; 定义与流程 瀑布模型是线性顺序的开发流程&#xff0c;包含需求分析、设计、编码、测试、维护等阶段&#xff0c;每个阶段完成后才能进入下一阶段&#xff0c;类似“瀑布流水”逐级推进。 核心特点 严格阶段划分&#…

FreeRTOS与RT-Thread内存分配对比分析

一、动态内存分配策略 ​FreeRTOS ​分配算法多样性&#xff1a;提供5种动态内存管理算法&#xff08;heap_1至heap_5&#xff09;&#xff0c;覆盖从简单到复杂的场景。例如&#xff1a; heap_1&#xff1a;仅支持分配不支持释放&#xff0c;适用于固定任务栈分配。heap_4&…

202519 | Mybatis-Plus

快速入门 MyBatis-Plus&#xff08;简称 MP&#xff09;是 MyBatis 的增强工具&#xff0c;它在 MyBatis 的基础上只做增强不做改变&#xff0c;简化了开发&#xff0c;提高了效率。以下是 MyBatis-Plus 的快速入门指南&#xff0c;帮助您快速上手使用。 1. 环境准备 JDK&…

Linux C语言调用第三方库,第三方库如何编译安装

在 Linux 环境下使用 C 语言调用第三方库时&#xff0c;通常需要先对第三方库进行编译和安装。以下为你详细介绍一般的编译安装步骤&#xff0c;并给出不同类型第三方库&#xff08;如使用 Makefile、CMake 构建系统&#xff09;的具体示例。 一般步骤 1. 获取第三方库源码 …

linux基本命令(1)--linux下的打包命令 -- tar 和gzip

tar 解压 &#xff0c;打包 语法&#xff1a;tar [主选项辅选项] 文件或者目录 使用该命令时&#xff0c;主选项是必须要有的&#xff0c;它告诉tar要做什么事情&#xff0c;辅选项是辅助使用的&#xff0c;可以选用。 主选项&#xff1a; c 创建新的档案文件。如果用户想备…

Python 序列构成的数组(对序列使用+和_)

对序列使用和* Python 程序员会默认序列是支持 和 * 操作的。通常 号两侧的序列由 相同类型的数据所构成&#xff0c;在拼接的过程中&#xff0c;两个被操作的序列都不会被 修改&#xff0c;Python 会新建一个包含同样类型数据的序列来作为拼接的结果。 如果想要把一个序列…

[ C语言 ] | 从0到1?

目录 认识计算机语言 C语言 工欲善其事必先利其器 第一个C语言代码 这一些列 [ C语言 ] &#xff0c;就来分享一下 C语言 相关的知识点~ 认识计算机语言 我们说到计算机语言&#xff0c;语言&#xff0c;就是用来沟通的工具&#xff0c;计算机语言呢&#xff1f;就是我们…

【通道注意力机制】【SENet】Squeeze-and-Excitation Networks

0.论文摘要 卷积神经网络建立在卷积操作的基础上&#xff0c;通过融合局部感受野内的空间和通道信息来提取有意义的特征。为了增强网络的表示能力&#xff0c;最近的一些方法展示了增强空间编码的好处。在本研究中&#xff0c;我们专注于通道关系&#xff0c;并提出了一种新颖…

kubernetes Calico(CNI) NetworkPolicy 流量管理 设置networkpolicy 策略 下集

1、kubernetes 网络策略&#xff08;网络隔离策略&#xff09; Network Policy 是 Kubernetes 中用于控制 Pod 之间网络通信的一种机制。它通过定义规则&#xff0c;限制哪些 Pod 或外部实体可以与目标 Pod 通信&#xff08;基于标签、命名空间、端口等&#xff09;。Network …

sqlmap基础命令总结

​注意事项:仅用于授权测试&#xff0c;避免非法使用。 目录 ​一、基础命令 ​二、数据库信息获取 ​三、绕过 WAF/IDS ​四、文件系统与系统命令 ​五、高级功能与优化 ​六、实战示例 ​一、基础命令 ​检测注入点 sqlmap -u "http://target.com/index.php?id1&…

Unity光线传播体积(LPV)技术实现详解

一、LPV技术概述 光线传播体积(Light Propagation Volumes)是一种实时全局光照技术&#xff0c;通过将场景中的间接光信息存储在3D网格中&#xff0c;实现动态物体的间接光照效果。 核心优势&#xff1a; 实时性能&#xff1a;相比传统光照贴图&#xff0c;支持动态场景 硬件…

SpringBoot (一) 自动配置原理

目录 一 自动配置 1:数据源的手动配置 1:SpringBoot的自动配置 二 自动配置的完整流程&#xff1a;&#xff08;底层&#xff09; 1. 场景化依赖与Starter机制 2. 主程序入口与注解驱动 3. 自动配置类的加载与筛选 4. 自动配置类的实现逻辑 5. 自动配置的触发与执行流…

OJ题:移动零

双指针法 c 语言实现 void moveZeroes(int* nums, int numsSize) {int dest,cur; //创建临时指针和目标指针destcur0;//出初始化while(cur<numsSize)//遍历{if(nums[cur]!0){swap(&nums[cur],&nums[dest]);cur;dest;}else{cur;}}} 思路是建立两个指针&#xff0…

pycharm终端操作远程服务器

pycharm项目已经连接了远程服务器&#xff0c;但是打开终端&#xff0c;却依旧显示的是本地的那个环境&#xff0c;也就是说没有操作远程的那个环境。只能再使用Xshell去操作远程环境&#xff0c;很麻烦&#xff0c;找了下教程。 来源&#xff1a;https://blog.csdn.net/maolim…

(头歌作业—python)3.2 个人所得税计算器(project)

第1关&#xff1a;个人所得税计算器 任务描述 本关任务&#xff1a;编写一个个人所得税计算器的小程序。 相关知识 个人所得税缴纳标准 2018 年 10 月 1 日以前&#xff0c;个税免征额为 3500 元/月&#xff0c;调整后&#xff0c;个税免征额为 5000 元/月&#xff0c; 7 级超…

Redis场景问题1:缓存穿透

Redis 缓存穿透是指在缓存系统&#xff08;如 Redis&#xff09;中&#xff0c;当客户端请求的数据既不在缓存中&#xff0c;也不在数据库中时&#xff0c;每次请求都会直接穿透缓存访问数据库&#xff0c;从而给数据库带来巨大压力&#xff0c;甚至可能导致数据库崩溃。下面为…

CUDA Memory Fence 函数的功能与硬件实现细节

CUDA Memory Fence 函数的功能与硬件实现细节 Memory Fence 的基本功能 CUDA中的memory fence函数用于控制内存操作的可见性顺序&#xff0c;确保在fence之前的内存操作对特定范围内的线程可见。主要功能包括&#xff1a; 排序内存操作&#xff1a;确保fence之前的内存操作在…

实战篇Redis

黑马程序员的Redis的笔记&#xff08;后面补一下图片&#xff09; 【黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目】https://www.bilibili.com/video/BV1cr4y1671t?p72&vd_source001f1c33a895eb5ed820b9a4…

Reactive编程:什么是Reactive编程?Reactive编程思想

文章目录 **1. Reactive编程概述****1.1 什么是Reactive编程&#xff1f;****1.1.1 Reactive编程的定义****1.1.2 Reactive编程的历史****1.1.3 Reactive编程的应用场景****1.1.4 Reactive编程的优势** **1.2 Reactive编程的核心思想****1.2.1 响应式&#xff08;Reactive&…

异步转同步,实现一个消息队列

有一个场景&#xff0c;需要实现一个消息队列&#xff0c;要求 1&#xff0c;3&#xff0c;4 秒后&#xff0c;依次打印 1&#xff0c;2&#xff0c;3&#xff0c;如下&#xff1a; 其实考察的是怎么用同步的方式实现异步。 本文总结了四种方式实现&#xff1a;常规嵌套、prom…