excel导入就是将excel里面的数据转换组织形式,对数据库表进行映射更改
导入的开始——内容读取与解析
重点看解析,解析的关键在于如何找到所需要的字段内容,可以通过以下方法
- 表头名:通过表头名定位字段数据所在
- 位置:事先确定好每个字段所在的位置
个人更为倾向于通过位置的方式。位置不需要考虑表头名的格式处理,而且更为清晰与明确,比表头名更加稳定。表头名可能被被改,而位置即使被改,也很容易调整回来
用户侧,应提供Excel内容映射对象。这样的对象既可以以结构体形式展现,也可以以位置、表头名映射阐明
事先正确性校验
在开始导入之前必须确定excel各行各列与预期数据类型、范围、必要性吻合
分类来说,对于通用型校验,比如对于年龄,那就是应该是数字;对于邮箱,那应该就要符合邮箱格式。那么对这些通用型,可以通过比如tag指明存在的校验方法
而对于特殊业务类的,便提供相应切面,让用户注册校验方法
开发者视角——excel即二维数组
二维数组能构建什么关系呢?
- 一组无关联关系的一维数组
- 树结构
- 图
一般而言就是一维数组与树
关系如何映射
一维数组
从一组一维数组的角度出发,最简单的情况其实是excel与数据表的一一对应
当然,实际情况很少有这么简单的,总是会存在
- excel多些字段:直接忽略多的就好
- 要自动生成内容的情况:按照情况生成
- excel与数据库表并不一一对应:为每一行定义行类型,根据行类型进行导入
- 与其他Excel存在关联关系:创建唯一id进行匹配关联
树结构
树必须要考虑到数据表的树实现
- 邻接表模型:通过父节点id进行关联
- 路径枚举:将所有路径,比如1/5/9全部记录下来
- 嵌套集合:类似于线段树,每个节点记录其范围。比如lft、rgt记录范围,只要在这个范围的就是该节点的子节点
- 闭包表模型:使用一个辅助表来记录节点之间的所有祖先-后代关系
一般而言只有临接表模型,因此本设计暂只考虑该模型
基于临接表模型的Excel形式可以有以下几种
-
与临接表模型一致对应:这种最简单的,最多处理下唯一键转为数据库表id
-
列出所有路径:每一列对应树的一层,通过节点或者节点路径去唯一确定。
一般由上至下进行导入
-
列出所有父子关系:就是一列父节点,一列子节点,然后列举出所有这种父子关系
- 获取所有节点
- 根据父子关系,将子节点加入到父节点中
- 当所有父子关系都完成之后,树也建立完成
-
嵌套集合:一般也不会用这种格式的,但这种格式的好处就是不需要额外多余的父关系
- 按节点start升序,节点end降序排序。那么这样保证了父节点一定在子节点前面
- 建立虚拟根节点,并加入栈中
- 遍历排序后的节点,若当前节点不在不在栈顶的节点范围内,说明栈顶元素不再有子节点了,出栈
- 将当前节点作为当前栈顶节点的子节点
- 入栈当前节点
-
模拟树形:就是在Excel中模拟树的结构
按照层级一层层进行构建
总而言之,无论是一维数组,还是树的导入,都是将excel形式转为为抽象数据结构的过程
导入——用户侧的实现
从用户侧来看,框架开放Excel解析、校验、处理之后的导入点,那么用户可在该导入点进行数据转换与实质导入工作。
比如在传入Excel映射对象,之后用户侧切入点便将之转换为数据库表对象,然后新增到数据库中
事后正确性校验
对于一个框架能做的有
对于数据增减
- 数据数量增减差异检验
- 偏移量部分数据校验
对于数据更新
- 根据主键部分数据校验
对于关联型校验
-
简单资源管理型:即资源管理表直接连接多具体资源表
需要校验的:是否能连接到对应具体资源表、资源表数量是否正确
-
简单树型:即内容挂在叶节点上
需要检验的:叶节点下是否含有目标内容
当然更关键的是对excel生产格式进行规范,使尽可能将格式更适合于导入
中间件
考虑到实际场景
- 导入输出依然Excel
- 导入输出为sql文件
那么便可以在框架上支持中间件功能,那么就可以支持多样化的场景需要
具体而言,中间件可提供以下切面
- 校验之后,导入之前
- 单行、单节点数据导入之后
- 全部数据导入之后
例如对于输出sql文件的中间件,便可以在单行、单节点数据导入之后,使用方便可传输转换之后的表结构,然后交予中间件去生成sql语句。在全部数据导入之后,将所有生成的sql语句写入文件中
特性
对于excel导入框架存在一些应该本身具有的特性,那么这些特性是可以直接配置是否使用、如何使用
比如
- 批量导入
- 并发导入
- 输出进度
- 存在部分可跳过行数据
在实现上,仍然可以利用中间件的接口,在各个切面支撑功能
例如对于进度输出特性,便可以在校验之后,导入之前获取总数据量,然后单行、单节点数据导入之后汇报当前进度信息