今天改完了bug就开始考虑起怎么优化数据导入的程序了。我们的系统构架要求客户端不能执行sql语句,所有的数据库操作都要通过ejb来实现。我这个数据导入就麻烦了,因为是大量数据的导入,如果采用ejb的方式一条一条的导入,速度会很慢。
所以我采取了定义一个SessionBean,在SessionBean中定义一个executeSQL方法,接受两个参数,一个是sql语句(可能带参数),和一个参数值数组。这样客户端就可以直接通过sql语句操纵数据库了。但是问题也就来了,如果每条数据都调用executeSQL访问一次数据库,这样不仅会造成频繁的事务启动,速度很慢,而且由于各个数据库插入操作之间是在不同的ejb调用中进行的,所以无法保证事务。我优化的重点当然也就在这两点上。项目紧急,我不能对构架做太大的改动了,因为毕竟以前的实现方式可以导入数据了,我就琢磨着在不做大规模改动的情况下进行优化,将风险降低到最小。
系统中所有ejb都是基于接口的,比如上边定义的executeSQL方法就定义在IImportDataFacade接口中,ejb实现这个接口,客户端通过工厂方法ImportDataFactory.getInstance()访问这个接口(ImportDataFactory.getInstance()返回IImportDataFacade类型)。好,我就从他下手。定义一个ImportDataDecorate类,让他也实现IImportDataFacade接口,它的executeSQL实现不是吧sql提交到数据库,而是把它缓存起来,等所有插入语句执行完毕后将缓存的sql语句一次性提交到我定义的一个新的接口方法中(此方法含有一个sql数组的发那个法),这样就可以保证事务和速度了。
我是怎么实现对系统改动最小呢?对了,我只要把所有调用ImportDataFactory.getInstance().executeSQL()的地方替换成new ImportDataDecorate(ImportDataFactory.getInstance()).executeSQL(),哈哈,改动很小吧,而且一旦发现这种实现方式不可行,那么只要将ImportDataDecorate.executeSQL()的实现改成直接提交到数据库就好了,其他调用根本不用变。设计模式很伟大呀,只不过我都不知道我用的这是什么模式,Proxy 还是Decorator?不知道,反正解决问题了,呵呵。