springboot-利用反射调用service层方法从Excel读取数据写入数据库报错:java.lang.NullPointerException,小坑一个

最近在做一个小项目,需要从读取Excel数据写入到数据库。利用的是easyExcel的read方法,通过实现了ReadListener接口的监听器去调用service层方法实现数据持久化操作。
但业务表那么多,本身在读取过程中不需要做任何操作,只要数据从Excel读出来直接写到mysql就可以,因此不想给每个表都写一个监听器,通过泛型加反射的方式实现类的匹配和方法调用。
我的方案是:
1.前台选择Excel文件,并指定要解析的sheet页,可以是索引标识,也可以是sheet名称;
2.前台选择解析的模板名称,也就是mysql内置业务表经过ORM映射得到的类名;
3.将这些信息通过restfull方式传递到后台controller层接收,专门创建一个controller类来处理这些请求,执行EasyExcel.read方法;
4.调用带泛型且实现了ReadListener接口的监听器,处理持久化业务逻辑,根据前台传入的表对象类名,利用反射创建对应的service方法,并调用insert方法,将得到的表对象List集合持久化到mysql中。
流程并不复杂,其中有两个关键点:
1.业务数据表对象对应的service类命名必须保持一致,以便能够通过表对象类名经过简单的string操作就能得到对应的service类对象;
2.每一个业务表对象对应的service层业务逻辑类都必须创建一个同名方法,用于反射机制根据这个方法名创建持久化方法。
大致方向搞清楚了,开撸。
先创建一个业务表对象Pojo

@Data
public class TestExcelHandleTB {
   
	
	@ExcelIgnore
    private Integer id;

	@ExcelProperty("姓名")
    private String name;

	@ExcelProperty("年龄")
    private Integer ago;

	@ExcelProperty("性别")
    private String gender;

	@ExcelProperty("是否已婚")
    private Boolean married;

	@ExcelProperty("创建日期")
    private Date createtime;

	@ExcelIgnore
    private String note;
}

我这里是在eclipse通过generator创建的对象,然后引入了lombok。在导入数据的过程中,我们忽略了索引行id和备注行note,id我们会根据自己的规则去创建。
接下来创建一个service层类,处理持久化逻辑,将来监听器反射要创建的就这这个service对象,他会根据监听器获取到的数据调用

@Service
public class TestExcelHandleTBService {
   

	@Autowired
	private TestExcelHandleTBMapper tehtm;
		
	@Transactional
	public int insert(List<TestExcelHandleTB> list) {
   
		for (TestExcelHandleTB teh : list) {
   
			int flag = tehtm.insert(teh);
		}	
		return 0;		
	}
}

这里有两点说明:
1.每个Mapper都会对应一个属于自己的service类,利用@Autowired注解导入generator创建的Mapper接口,当然这里的话就是有多少个业务表就得创建多少个service层对应的处理类,这个不能偷懒了,反正就算没有Excel导入需求,你也得写service类和方法,这个不能偷懒;
2.因为是generator创建的Mapper,没有batch方法,只能通过insert一个一个的往里写;
3.一定要加个事务@Transactional,因为表中所有记录的持久化需要包含在一个事务里处理。
接下来是个重点,监听器,这里有一个坑,反射的坑,稍不注意,就调入陷阱,先来看监听器的实现逻辑

public class TestExcelHandleTBListenerT<T> implements ReadListener<T> {
   

	/**
	 * 每隔100条,清理list
	 */
	private 

你可能感兴趣的:(springboot,java,数据库,spring,boot)