项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库

时间:2023-01-08 13:24:53

将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库

写在前面:本文用的语言是java;数据库是MySql;

需求:在实际项目中,经常会被客户要求,做批量导入数据;一般的简单的单表数据,可以直接通过Navicat的导入功能,将Excel表格信息直接导入;单实际情况是——需要导入的数据要分别保存在对应的多张表中,其中一张主表,多张关联副表,这个时候再用Navicat的导入功能,无法满足需求! 本文总结一种方法处理这种批量录入多表数据;如下。

核心思路:将Excel数据表中的数据,保存到TXT中;通过脚本读取TXT中的数据,写成对应的sql语句;在Navicat运行sql语句,实现保存目的;

为了展示完整的操作步骤,我准备了一个简单的业务需求:保存学生基本信息和学生选课信息;原始EXCEL数据在一张表里;需要将数据分别保存在student_info和select_class两张数据表中

具体操作步骤:

1.准备Excel原始数据:Excel原始数据有一定的格式要求,要求每列信息必须明确(1表示选课0表示没选),如下图:

项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库

将Excel数据复制到TXT中,如下;

项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库

2.准备初始化数据表;

CREATE TABLE `student_info` (
`student_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '学生id',
`name` varchar(10) DEFAULT NULL,
`sex` varchar(1) DEFAULT NULL,
`age` int(2) DEFAULT NULL,
PRIMARY KEY (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `select_class` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'id',
`student_id` int(10) DEFAULT NULL COMMENT '学生id',
`class_name` varchar(10) DEFAULT NULL COMMENT '课程名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

初始化的数据表数据表,如下:

项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库

3.编写脚本(核心步骤),代码如下: 

package com.fh.readfile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class TestFileReadUtil {
private static int Number = 0;
/**
* 功能:Java读取txt文件的内容 步骤:1:先获得文件句柄 2:获得文件句柄当做是输入一个字节码流,需要对这个输入流进行读取
* 3:读取到输入流后,需要读取生成字节流 4:一行一行的输出。readline()。 备注:需要考虑的是异常情况
* @param filePath
* 文件路径[到达文件:如: D:\aa.txt]
* @return 将这个文件按照每一行切割成数组存放到list中。
*/
public static List<String> readTxtFileIntoStringArrList(String filePath) {
List<String> list = new ArrayList<String>();
try {
File file = new File(filePath);
if (file.isFile() && file.exists()) { // 判断文件是否存在
InputStreamReader read = new InputStreamReader(new FileInputStream(file));// 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
while ((lineTxt = bufferedReader.readLine()) != null) {
list.add(lineTxt);
}
bufferedReader.close();
read.close();
} else {
System.out.println("找不到指定的文件");
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
e.printStackTrace();
}
return list;
}
//学生基本信息sql语句模板
private static String studentMainInfoSql = "insert into student_info(student_id,name,sex,age)value(${student_id},'${name}','${sex}',${age});";//注意'${name}'需要单引号,表示是字符串,否则生成的sql语句会出错
//学生选课信息sql语句模板
private static String selectClassInfoSql= "insert into select_class(id,student_id,class_name) value(${id},${student_id},'${class_name}');";
//Excel数据表头
private static final String[] HEAD_ARRAY = new String[]{"Name","Sex","Age","Chinese","Math","English","Science"};
//根据表头名称获取列索引索引"Name","Sex","Age","Chinese","Math","English","Science"分别是0 1 2 3 4 5 6
private static int getIndex(String headName){
for(int i=0;i<HEAD_ARRAY.length;i++){
String head = HEAD_ARRAY[i];
if(head.equals(headName)){
return i;
}
}
return -1;
}
//生成学生基本信息sql语句方法
private static void createStudentInfo(List<String>lineList){
int student_id =Number;//定义student_id的起始值
for(String line:lineList){//遍历每一行数据
student_id++;
String[] array = line.split("\t");//将每一行数据根据空格拆分成数组
//将sql模板中的value值是用真实数据替换(使用replace()方法)
String studentInfoSql = studentMainInfoSql.replace("${student_id}", student_id+"").
replace("${name}", array[getIndex("Name")]).
replace("${sex}", array[getIndex("Sex")]).
replace("${age}", array[getIndex("Age")]);
//打印sql语句
System.out.println(studentInfoSql);
}
}
//生成学生选课信息sql语句
private static void createSelectClassInfo(List<String>lineList){
int student_id =Number;//定义student_id的起始值
int select_class_id =Number;//定义select_class_id的起始值
int startIndex = getIndex("Chinese");//获取选课信息列的首列索引
int endIndex = getIndex("Science");//获取选课信息列的末列索引
for(String line:lineList){//遍历每一行数据
student_id++;
String[] array = line.split("\t");//将每一行数据根据空格拆分成数组
for(int i=startIndex;i< (endIndex+1);i++){//遍历每一行数据中每个课程的选择情况
if(array[i].equals("1")){//如果是1,表示选择该课程,要生成对应的sql语句
select_class_id++;
String className =HEAD_ARRAY[i];
//生成学生选课信息sql语句
String selectClassSql = selectClassInfoSql.replace("${id}", select_class_id+"").
replace("${student_id}", student_id+"").
replace("${class_name}", className);
//打印 语句
System.out.println(selectClassSql);
}
}
}
}
//main方法,打印最终sql语句
public static void main(String[] args) {
//读取txt文件中的数据,格式是list集合
List<String> lineList = readTxtFileIntoStringArrList("txt/student.txt");
//去掉第一行数据,因为第一行数据是表头
lineList.remove(0);
//打印学生基本信息sql语句
createStudentInfo(lineList);
//打印学生选课数据sql语句
createSelectClassInfo(lineList); }
}

4.运行脚本,得到sql语句;如下:

insert into student_info(student_id,name,sex,age)value(1,'林俊杰','男',30);
insert into student_info(student_id,name,sex,age)value(2,'赵丽颖','女',28);
insert into student_info(student_id,name,sex,age)value(3,'胡歌','男',36);
insert into select_class(id,student_id,class_name) value(1,1,'Chinese');
insert into select_class(id,student_id,class_name) value(2,1,'Science');
insert into select_class(id,student_id,class_name) value(3,2,'Chinese');
insert into select_class(id,student_id,class_name) value(4,2,'Math');
insert into select_class(id,student_id,class_name) value(5,3,'English');
insert into select_class(id,student_id,class_name) value(6,3,'Science');

在navicat中运行sql语句,最终结果,如下;

项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库

5.总结:本案例是多表数据导入案例中最简单的一张,但是基本思路已经表达完整;再多的关联表,沿用select_class即可;

 

项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库的更多相关文章

  1. SQL Server从读写频繁的大表中删除大批量数据

    如果我们直接用delete from语句来删除读写频繁的大表中的数据,很有可能会因为where的条件是全表扫描从而导致整个表被锁住了.如果该表是读写频繁的生产库那简直就是一场灾难,所有的线上读写请求都 ...

  2. sqlserver数据将多个表或视图的数据合并到一个表或视图里的sql语句

    create view dbo.V_ZDUser_DDasselect * from dbo.V_ZDUser_DD1 union all select * from dbo.V_ZDUser_DD2 ...

  3. 表关联ID相同数据update修改

    UPDATE 表1 e,表2 c SET e.被修改字段='修改值为..' WHERE e.id=c.id

  4. Excel 数据导入SQL XML 自动生成表头

    去出差的时候应客户要求要要将Excel 文件内的数据批量导入到数据库中,而且有各种不同种类的表格,如果每一个表格多对应一个数据表的话, 按照正常的方法应该是创建数据表,创建数据库中映射的数据模型,然后 ...

  5. 循序渐进开发WinForm项目(5&rpar;--Excel数据的导入导出操作

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  6. SQL批量信息保存&lpar;XML格式字符串数据&rpar;

    /* *功能:SQL批量信息录入 *此存储过程获取表单信息,插入表中.*/CREATE  PROC [dbo].[sp_SaveToMX1]@XML text   --明细表XML字符串信息ASBEG ...

  7. Mysql导入excel数据,解决某些特殊字符乱码问题

    问题 做项目需要从excel表格导入到mysql的数据库表中,excel表格中的“规格”字段的“×”符号导入数据库表中,会出现部分数据的“×”这个符号会乱码,成“?”的形式. 解决方法 打开excel ...

  8. 将DataTable 覆盖到 SQL某表&lpar;包括表结构及所有数据&rpar;

    调用代码: string tableName = "Sheet1"; openFileDlg.ShowDialog(); DataTable dt = GeneralFun.Fil ...

  9. oracle xmltype导入并解析Excel数据 &lpar;一&rpar;创建表与序

    表说明: T_EXCEL_IMPORT_DATASRC: Excel数据存储表,(使用了xmltype存储Excel数据) 部分字段说明: BUSINESSTYPE: Excel模板类型,一个Exce ...

随机推荐

  1. validate插件深入学习-02 常用方法和validate对象的方法

    ①检查表单元素是否有效 valid() 在表单内添加<button id="check">检查</button> $('#check').click(fun ...

  2. 遇到bug怎么办

    最近第一个完整的项目的第一期快完成了.期间,我怀疑过无数次人生,给难兄难弟辣椒相互吐槽过.被我师父点播后觉得人和人差距怎么可以这么大数次. 终于!基本功能实现了. 今天不总结具体问题了,说一下调试过程 ...

  3. 股票k线

    与上一篇文章相比k线图主要的难点 1.tooltip的定制化显示: 当手指触摸手机屏幕上下拖动可能会手指的事件陷入图表无法进行上下拖动 tooltip:{followMouseMove} follow ...

  4. java中的包有那些 ???

    java.util工具包java.sql数据库包java.io输入输出流包java.net网络包java.lang基础包这些是基本的包,还有一些其他的例如集合,反射等的工具包,你可以去查一下java ...

  5. Java集合源码分析

    Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组.链表.栈.队列.集合.哈希表等.学习Java集合框架下大致可以分为如下五个部分:List列表.Set集合.Map映射.迭 ...

  6. 关于Eclipse中开发插件&lpar;二&rpar;

    原plugin.xml文件各个设置项的说明: 附上生成的文件代码: <?xml version="1.0" encoding="UTF-8"?> & ...

  7. Eclipse创建Maven Web项目 &plus; 测试覆盖率 &plus; 常见问题(2015&period;07&period;14——湛耀)

    Eclipse创建Maven web项目: 到此,并没有创建好,接下来一步步解决问题: 问题:无法创建src/main/java目录 解决: 右键项目选择[properties] 点击[OK] 问题: ...

  8. 一个初学者的辛酸路程-python操作SQLAlchemy-13

    前言 其实一开始写blog,我是拒绝的,但是,没办法,没有任何理由抗拒.今天呢,要说的就是如何使用Python来操作数据库. SQLAlchemy SQLAlchemy是Python编程语言下的一款O ...

  9. 解决记录:win10 无法安装VS2017,visual studio installer下载进度始终为0

    问题描述:win10 下无法安装VS2017,visual studio installer下载进度始终为0,点击取消按钮后,也没有反应,visual studio installer也关闭不掉: 具 ...

  10. Python爬虫入门教程 48-100 使用mitmdump抓取手机惠农APP-手机APP爬虫部分

    1. 爬取前的分析 mitmdump是mitmproxy的命令行接口,比Fiddler.Charles等工具方便的地方是它可以对接Python脚本. 有了它我们可以不用手动截获和分析HTTP请求和响应 ...