事先声明,这篇设计也是因为编辑时间较长,被JAVAEYE给拦截了。这个是实现后的设计文档。
背景:
SPA以及相关基础数据导出是产品的一个附加功能组件,能够将系统的SPA以及相关数据导入导出到安装在其它平台上,实现SPA的导入导出。
解决问题:
主要有两个:
1. 数据库中数据的导入导出。
由于SPA的数据导出到新数据库的时候,原来的数据即时存在的话,也要进行删除,因此,就是直接的数据导入导出的问题。
2. 和数据库相关文件的导入导出问题。
由于SPA中有很多表和很多文件相关联,那么一项处理要求就是将SPA相关联的文件备份出来,然后导入到对应系统的相应目录下。由于不需要保留目标平台的数据,因此,这方面的处理就简单了,直接将系统文件备份出来,覆盖到目标目录就可以了。
不牵涉到改变文件名的问题。
总体来讲,要解决的问题和之前的预想相比,要简单了很多。
设计方案:
1. hibernate +dom4jSession + XML + XPATH+ANT来完成数据库的备份。将数据库的数据通过Hibernate的配置文件,转换为XML的实体,存储在XML文件中。
在隐射文件里面,通过配置node节点,定义这个实体对应的xml文件应该是什么样的。我这里的定义很简单。dingy定义类为node="BaseLine"元素,id定义为@Id属性,属性也转换为下级的元素节点。
在xml中,就是
在Hibernate中,将实体转换为实体,比较方便,主要的操作是取得Session的时候,用EntityMode.DOM4J的方式去取得。返回得到Element列表,怎么将Element组装成Document就不用多讲了。
在导入回去的时候,相当好办。
这是将该node更新回数据库,更新方式是覆盖已有的数据,如果存在的话:)
什么叫覆盖已有?就是数据库ID相同的记录,直接覆盖就OK了。
2. 文件的导入导出
将xml文件压缩为一个文件,其它的各类文件分别也压缩为多个文件,然后统一添加到一个大的压缩文件中。导出的步骤相反。分为两步:
a. 需要借助Ant的Zip和Expand API。
b. 在压缩文件中添加Entry,以及解析Entry,需要用到JAVA提供的文件压缩API。
这个名字其实起得不好。compressFile也是压缩之意,这里的意思是将file添加到Zip的一个入口。
相应的,unCompressFile方法是:
后记:该程序是在前人程序的基础上开发的,据说是之前的牛人写的程序。即便这样,要理解别人的程序还是很难的。特别象我这样,想要理解程序的来龙去脉的时候,更显得艰难。我在不停的Refactor中前行,才能摸清楚程序的意思。
只有维护的时候,才想到如果有一份需求和设计文档就好了。这个完全不是设计文档,也不是程序的流程。思之,想之……
背景:
SPA以及相关基础数据导出是产品的一个附加功能组件,能够将系统的SPA以及相关数据导入导出到安装在其它平台上,实现SPA的导入导出。
解决问题:
主要有两个:
1. 数据库中数据的导入导出。
由于SPA的数据导出到新数据库的时候,原来的数据即时存在的话,也要进行删除,因此,就是直接的数据导入导出的问题。
2. 和数据库相关文件的导入导出问题。
由于SPA中有很多表和很多文件相关联,那么一项处理要求就是将SPA相关联的文件备份出来,然后导入到对应系统的相应目录下。由于不需要保留目标平台的数据,因此,这方面的处理就简单了,直接将系统文件备份出来,覆盖到目标目录就可以了。
不牵涉到改变文件名的问题。
总体来讲,要解决的问题和之前的预想相比,要简单了很多。
设计方案:
1. hibernate +dom4jSession + XML + XPATH+ANT来完成数据库的备份。将数据库的数据通过Hibernate的配置文件,转换为XML的实体,存储在XML文件中。
xml 代码
- <class
- name="Baseline"
- table="baseline"
- node = "Baseline"
- >
- <id
- name="Id"
- type="integer"
- column="ID"
- node = "@Id"
- >
- <generator class="org.hibernate.id.IncrementGenerator"/>
- id>
- <property
- name="UserMetricsId"
- column="USER_METRICS_ID"
- type="integer"
- not-null="false"
- node = "UserMetricsId"
- length="11"
- />
- ……
在xml中,就是
xml 代码
- <BaseLine Id="">
- <UserMetricsId>8UserMetricsId>
- BaseLine>
java 代码
- session = sessionFactory.openSession();
- dom4jSession = session.getSession(EntityMode.DOM4J);
- dom4jSession.createQuery(xpath).list();
在导入回去的时候,相当好办。
java 代码
- dom4jSession.replicate(className, node,ReplicationMode.OVERWRITE);
什么叫覆盖已有?就是数据库ID相同的记录,直接覆盖就OK了。
2. 文件的导入导出
将xml文件压缩为一个文件,其它的各类文件分别也压缩为多个文件,然后统一添加到一个大的压缩文件中。导出的步骤相反。分为两步:
a. 需要借助Ant的Zip和Expand API。
java 代码。
- private void zipFiles(File destFile, String dataPath, List includeFiles) {
- Project project = new Project();
- Zip zip = new Zip();
- zip.setProject(project);
- zip.setTaskName("default");
- zip.setDestFile(destFile);
- FileSet fs = new FileSet();
- fs.setDir(new File(dataPath));
- if(includeFiles!=null && includeFiles.size()>0){
- for (Iterator iter = includeFiles.iterator(); iter.hasNext();) {
- String element = (String) iter.next();
- fs.setIncludes(element);
- }
- }
- zip.addFileset(fs);
- zip.setCompress(true);
- zip.setEncoding("GBK");
- zip.execute();
- }
java 代码
- /**
- * 将源文件unzip到目的文件,覆盖安装。
- * @param srcFile
- * @param destFile
- */
- public void unzipFile(File srcFile, File destFile){
- Project project = new Project();
- Expand expand = new Expand();
- expand.setProject(project);
- expand.setSrc(srcFile);
- expand.setEncoding("GBK");
- expand.setOverwrite(true);
- expand.setDest(destFile);
- expand.execute();
- }
b. 在压缩文件中添加Entry,以及解析Entry,需要用到JAVA提供的文件压缩API。
java 代码
-
- public void compressFile(File file,String entryName) throws IOException{
- zos.putNextEntry(new ZipEntry(entryName));
- BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
- int n = 0;
- while (n != -1) {
- n = bis.read();
- if (n != -1) {
- zos.write(n);
- }
- }
- bis.close();
- zos.closeEntry();
- }
相应的,unCompressFile方法是:
java 代码
- public void unCompress(ZipFile zipFile, String entryName, File destFile) throws IOException{
- ZipEntry ze = zipFile.getEntry(entryName);
- if(ze!=null){
- BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(ze));
- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
- int n = 0;
- while (n != -1) {
- n = bis.read();
- if (n != -1) {
- bos.write(n);
- }
- }
- bos.close();
- bis.close();
- }
- }
后记:该程序是在前人程序的基础上开发的,据说是之前的牛人写的程序。即便这样,要理解别人的程序还是很难的。特别象我这样,想要理解程序的来龙去脉的时候,更显得艰难。我在不停的Refactor中前行,才能摸清楚程序的意思。
只有维护的时候,才想到如果有一份需求和设计文档就好了。这个完全不是设计文档,也不是程序的流程。思之,想之……