在公司业务中,经常会遇到读取解析文件并保存内容到数据库的任务需求,一般文件里第一行记录着数据数目(行数)或标题或表头。不管怎样,对于后端人员,重要的是了解文件的统一规范,文件用途,文件结构,将表格的数据内容(一般为表头以下的数据)一字不差地存到数据库。
对文件的解析过程,除了对各种流的操作外,一般会自定义对象利用反射接收每一行数据,再将转化后的对象保存至数据库。
例如:一张记录着某超市一天交易数据的账单表,表主体的每一行数据对应着每一条‘账单项’,这时我们可以根据每一列数据对应的表头属性创建‘账单项’对象(checkItem),将每一行记录数据值作为对象的属性值逐个赋值。
工具类实现如下,并非能运用于各种项目,不同文件编写规范不同,这边仅供参考~
package com.dongdong.demo.web.util;
import com.dongdong.demo.web.service.annotation.Code2Desc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* 字符串数据转化对象
*/
public class DataUtils {
private static Logger logger = LoggerFactory.getLogger(DataUtils.class);
/**
* 枚举类所在包名路径
*/
private static final String EnumPackagePath = "com.dongdong.demo.web.service.enums";
/**
* 字符串转为对象,默认枚举类code为String类型;字符串转化后的数组长度与对象属性数组长度一致(对象属性数 - 忽视属性数 = String数组长度),属性顺序与数组元素顺序一一对应
* @param line 需转为对象的数据字符串内容
* @param seperator 分隔符
* @param clazz 对应'转换结果对象'class对象
* @param <T> 对象类型
* @param num 忽视对象前几个属性,即设置前几个属性无需赋值转化
* @return 返回对象
*/
public static <T> T Str2Obj(String line, String seperator, Class<T> clazz , Integer num){
T item = null;
try {
//字符串转为字符串数组
String[] val = line.split(seperator);
//实例化对象
item = clazz.newInstance();
//获取属性列表
Field[] fields = clazz.getDeclaredFields();
//遍历字符串数组,逐个将数组元素为对象属性赋值
for (int i = 0; i < val.length; i++) {
if (val[i] != null && !val[i].trim().equals("")) {
//一般对象会有自身的唯一标识id属性且实现了serializable接口的对象会增多一个序列号,固对象属性列表长度会大于字符串数组长度,一旦超过了说明当前对象转化完毕,结束循环停止赋值。
if (num+i >= fields.length) {
break;
}
//获取需要赋值的属性
Field field = fields[num+i];
field.setAccessible(true);
//判断对象属性类型 如果类型为Integer类型转换为Integer类型赋值
//如果不是Integer类型转换为其他string类型赋值,之后逻辑判断同上
if (field.getType() == Integer.class) {
field.set(item, new Integer(val[i]));
continue;
} else if (field.getType() &#