1. 安装数据库(文章中使用的为MySQL)
2. 安装配置Java的jdk
3. 下载Java的数据库jar包
https://dev.mysql.com/downloads/windows/installer/8.0.html
使用Platform independent 下载任意一个都可
解压并将其jar文件放入项目lib文件夹下(没有可以自己创建一个)
并在项目配置的库中加入对该jar文件的依赖
4. 前期准备结束,接下来开始写代码
5. 首先准备一个Excel表,并将其转为.csv格式
6. 将该csv表转为utf-8编码,不修改编码将会出现乱码
此处Office用户可以直接通过另存为修改编码
WPS用户在进行表格编码修改时较为麻烦(WPS不提供该功能)
可以先另存为.csv文件,之后将其后缀改为.txt(不显示后缀的可以自行百度)
通过记事本打开,在另存为时,修改编码为utf-8
之后再修改后缀为.csv
7. 读取Excel文件
List<List<String>> data=new ArrayList<List<String>>();
//读取excel指定sheet中的各行数据,存入二维数组,不包括首行
try {
BufferedReader read = new BufferedReader(new FileReader("E:\\data.csv"));//换成你的文件名
String line = read.readLine();//首行标题不要
int index=0;
while((line=read.readLine())!=null){
String item[] = line.split(",");//CSV格式文件为逗号分隔符文件,这里根据逗号切分
if(item.length<10){
String ret[]=new String[10];
for(int i=0;i<item.length;i++){
ret[i]=item[i];
}
for(int i=item.length;i<10;i++){
ret[i]="null";
}
item=ret;
}
if(item.length>10){
System.out.println(1);
}
if(data.size()==2610){
System.out.println(1);
}
data.add(Arrays.asList(item));
index++;
}
} catch (Exception e) {
e.printStackTrace();
}
注意:此处曾遇到两个问题:
(1)表格中数据包含逗号,而此处采用逗号分隔
解决办法:将表格中的逗号转为中文逗号,而split参数使用英文逗号
(2)表格中可能由于数据原因,会出现空的格子
解决办法:在
String item[] = line.split(",");
后添加对数组长度的判断,并补齐
if(item.length<10){
String ret[]=new String[10];
for(int i=0;i<item.length;i++){
ret[i]=item[i];
}
for(int i=item.length;i<10;i++){
ret[i]="null";
}
item=ret;
}
8. 将数据处理为树型数据(注意此处每一级都有两个数据项,因此width变量值为2,该数据可以更改)
// 定义主键id 对应数据库中主键
Short index = 1;
Short parentId = null;//定义父id,第一级数据的父id为0
String levelName = null;//分类名称
String code=null;//分类对应数据
// tempMap为临时变量,记录那些已经添加过了 key为CatName+层级 value 为记录对象,用于查询非第一级数据的parentId
Map<Integer, Category> tempMap = new HashMap<>();
// 记录最终需要插入数据库的数据
List<DataItem> insertDatas = new ArrayList<DataItem>();
DataItem level = null;
int allCols = datas.get(0).size();//获取导入数据的列数
int width=2;
for (int column = 0; column < allCols; column+=width)
{//先对每一层级遍历
for (int i = 0; i < datas.size(); i++)
{//对该层级的每一项遍历,找到不同的项
Integer key1;
List<String> rows = datas.get(i);
//设置层级的关联关系,用于获取parentId
if (column == 0)
{
// 如果是第一列,parentid 默认为0
parentId = (short) 0;
}
else
{
// 如果不是一列,则在tempMap中寻找对应的父类id作为parentid
String key=rows.get(column-width) + "_" + String.valueOf(column/2);
key1=key.hashCode();
parentId = tempMap.get(key1.intValue()).getCodeId();
}
code = rows.get(column);
levelName=rows.get(column+1);
//tempMap中没有记录过则表示是要插入的数据
String key=code + "_" + (column + width)/2;
Integer a=key.hashCode();
if (!tempMap.containsKey(a.intValue()))//没有该数据
{
level = new Category();
level.setCodeId(index++);
level.setLevelName(levelName);
level.setCode(code);
level.setParentId(parentId);
level.setGrade(Byte.valueOf(String.valueOf((column + width)/2)));
a=key.hashCode();
tempMap.put(a.intValue(), level);
//添加到最终要导入的列表中
insertDatas.add(level);
}
}
}
//批量插入数据库中
insertJDBC(insertDatas);
static class DataItem{//代码中使用的类,用于存储数据项
Short codeId;
String code;
String name;
Short parentId;
int grade;
public short getCodeId() {
return codeId;
}
public void setCodeId(Short aShort) {
this.codeId=aShort;
}
public void setLevelName(String levelName) {
this.name=levelName;
}
public void setParentId(Short parentId) {
this.parentId=parentId;
}
public void setGrade(Byte valueOf) {
this.grade=valueOf;
}
public void setCode(String code) {
this.code=code;
}
}
注意:此处遇到的问题有:
(1)Map的containsKey不起作用
出错原因:需要重写equal和hashCode
解决方法:
1 重写equal和hashCode(比较麻烦)
2(代码中使用的是第二种,推荐这种)利用String的hashCode函数获取字符串的hashCode,并将intValue值作为key,屏蔽底层,可以正常使用containsKey
String key=rows.get(column-width) + "_" + String.valueOf(column/2);
key1=key.hashCode();
parentId = tempMap.get(key1.intValue()).getCodeId();
9. 将数据导入数据库
static void insertJDBC(List<Category> list){
Connection con;
//jdbc驱动
String driver="com.mysql.cj.jdbc.Driver";
//数据库接口3306,数据库名为icd
String url="jdbc:mysql://localhost:3306/icd?&useSSL=false&serverTimezone=UTC";
String user="root";//登录用户名
String password="********";//密码
try {
//注册JDBC驱动程序
Class.forName(driver);
//建立连接
con = DriverManager.getConnection(url, user, password);
if (!con.isClosed()) {
System.out.println("数据库连接成功");
}
Statement stmt= con.createStatement();
for(int k=0;k<list.size();k++) {
int codeId = list.get(k).codeId;
String code = list.get(k).code;
String name = list.get(k).name.replace("\'","\'"+"\'");
Short parentId = list.get(k).parentId;
int grade = list.get(k).grade;
String sql = "insert into icdnine VALUES(" + codeId +",'"+ code +"','"+ name +"',"+ (int)parentId +","+ grade + ")";
boolean ret = stmt.execute(sql);
}
con.close();
} catch (ClassNotFoundException e) {
System.out.println("数据库驱动没有安装");
} catch (SQLException e) {
e.printStackTrace();
System.out.println("数据库连接失败");
}
}
此处遇到的问题有:
(1)sql语句中需要使用字符串变量
解决方法:
在字符串变量前后加单引号’,再进行字符串拼接
即+" ’ " +string+" ’ "+
String sql = "insert into table VALUES(" + codeId +",'"+ code +"','"+ name +"',"+ (int)parentId +","+ grade + ")";
(2) 数据中有单引号,导致sql语句出错
解决方法:
将单引号replace为两个单引号
因为在sql语句中,两个单引号将被读为单引号
String name = list.get(k).name.replace("\'","\'"+"\'");
参考链接:
https://blog.youkuaiyun.com/zyq1084577627/article/details/78727623/