使用EasyExcel+Spring+Mybatis完成简单的向数据库导入Excel文件

EasyExcel

EasyExcel是什么?
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
github地址

1、EasyExcel+Spring+Mybatis的简单使用

## 1.1新建一个Module,在pom文件添加需要的依赖

 	<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.58</version>
      <scope>test</scope>
    </dependency>
    <!--Alibaba-EasyExcel-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>2.1.1</version>
    </dependency>
    <!--单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--mybatis-spring集成依赖-->
 	<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.20</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.12</version>
    </dependency>
    
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.8</version>
      <scope>compile</scope>
    </dependency>

1.2、设计与excel对应的表

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(11) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `sex` varchar(3) DEFAULT NULL,
  `email` varchar(32) DEFAULT NULL,
  
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1.3在resources目录下创建jdbc.properties,设置jdbc连接数据库的参数

jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=abc123

1.4在resources目录下创建applicationContext.xml

 <?xml version="1.0" encoding="UTF-8"?>
<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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--把数据库的配置信息写在独立的文件,便于修改数据库的配置内容
    -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--声明数据源dataSource,作用连接数据库-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">

       <!--使用属性配置文件中的数据,语法${key}-->
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--声明是mybatis中提供的sqlsession-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--set注入,把数据库连接池付给了datasource属性-->
        <property name="dataSource" ref="myDataSource"/>
        <!--mybatis主配置文件的位置
            configLocation的属性是resource类型,读取配置文件的
            的赋值时使用value ,classpath:文件位置
        -->
        <property name="configLocation" value="classpath:mybatis.xml"/>
    </bean>

    <!--创建dao对象使用SQL session的getmapper
        在内部调用getmapeer生成每个到接口的代理对象
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定SQL sessionfactory对象的id-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--指定包名包名是dao接口所在的包名
            MapperScannerConfigurer会扫描包中接口的所有接口,把每个接口都执行
            一次getmapper方法得到每个dao接口的对象,创建好的对象放到spring容器里
        -->
        <property name="basePackage" value="你的dao接口所在的包名"/>
    </bean>
</beans>

2、创建与数据库表对应的java实体类

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import java.util.Date;
@Getter
@Setter
@ToString
@NoArgsConstructor
public class DemoData {
	/**
     * 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
    */
    @ExcelProperty("id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("生日")
    @DateTimeFormat("yyyy-MM-dd")
    private Date birthday;
    @ExcelProperty("性别")
    private String sex;
    @ExcelProperty("邮箱")
    private String email;
}

3、创建DAO目录,编写与数据库交互的DemoDAO接口

import org.springframework.stereotype.Service;

import java.util.List;
@Service
public interface DemoDAO {
	//保存数据到数据库的方法
    int save(DemoData demoData);
}

3.1在同目录下创建DemoDAO.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="DemoDAO的绝对路径">
    <insert id="save">
        insert into user values (#{id},#{name},#{birthday},#{sex},#{email})
    </insert>
</mapper>

4、创建Service目录,编写操作DAO的ExcelService接口

public interface ExcelService {
    int addUser(DemoData demoData);
}

4.1、实现ExcelService接口,并重写方法操作DAO

import java.util.List;

public class ExcelServiceImpl implements ExcelService {
    private DemoDAO demoDAO;

    public void setDemoDAO(DemoDAO demoDAO) {
        this.demoDAO = demoDAO;
    }
    @Override
    public int addUser(DemoData demoData) {
        int nums = demoDAO.save(demoData);
        return nums;
    }
}

5、编写DemoDataListener监听类

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.List;

public class DemoDataListener extends AnalysisEventListener<DemoData> {
    /**
     * 每隔10条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 10;
    List<DemoData> list = new ArrayList<>();
    
    /**
     * 这个每一条数据解析都会来调用
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        System.out.println("解析到一条数据:"+data);
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }

    }
    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        System.out.println("所有数据解析完成!");
    }
    /**
     * 加上存储数据库
     */
    private void saveData() {
        String config = "applicationContext.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        ExcelService demodataService = (ExcelService) ac.getBean("demodataService");
        
        System.out.println("{}条数据,开始存储数据库!"+ list.size());
        for (DemoData demoData : list) {
            System.out.println("list里的:"+demoData);
            demodataService.addUser(demoData);
        }
        System.out.println("存储数据库成功!");
    }
}

5.1、回到applicationContext.xml添加bean标签声明Service

 	<!--声明service-->
	<bean id="demodataService" class="ExcelServiceImpl的全限定名称">
        <property name="demoDAO" ref="demoDAO"/>
    </bean>

6、编写测试类

public class Readtest {
    @Test
    public void readTest() {
        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
        String fileName ="excel文件地址";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();

    }
}

7.测试结果

Excel表格数据:
使用EasyExcel+Spring+Mybatis完成简单的向数据库导入Excel文件_第1张图片
数据库表导入结果图:
使用EasyExcel+Spring+Mybatis完成简单的向数据库导入Excel文件_第2张图片

你可能感兴趣的:(Java)