java批量处理数据库语句_Java项目中调用bat批处理进行多用户数据库备份

Java项目中调用bat批处理配合使用BCP进行多用户数据的备份

一、项目需求

最近项目中需要对数据库(Sql Server系列数据库)进行备份。项目中的需求不是简单的整个数据库的备份,而是根据用户来备份,具体的备份策略如下:

①系统为某一赛事管理类型的系统,整个系统分为几部分,前半部分的处理是在服务器上处理,后半部分的处理,是在用户自己的客户端中处理。不同的赛事对应不同的用户,用户将需要的数据提交给系统进行处理。

②系统在处理完数据之后,用户可以导出自己赛事相关的数据了,这个导出实际上做的就是个备份数据库,只不过只备份属于自己的数据库。然后下载系统的处理结果,很显然,各个用户的数据是不相同的。

③用户下载自己备份的数据库文件(这些个文件会打包成zip压缩包),再导入自己的客户端系统中。

整个系统使用的关键是:程序中调用bcp命令的时候传递用户相关的参数过去就OK了。处理流程如图1-1所示:

71f15886897578236f83bb71779e68e9.png

图1-1 处理流程

二、解决方案

本文提出的是使用Runtime.getRuntime().exec()调用批处理文件,程序中传递相关参数给bcp命令。关于BCP命令的详解,微软的MSDN上面写的非常的详细,在此就不赘述了!下面的一段话引用自微软的msdn上面的一段介绍:

bcp 实用工具可以在 Microsoft SQL Server 实例和用户指定格式的数据文件间大容量复制数据。使用 bcp 实用工具可以将大量新行导入 SQL Server 表,或将表数据导出到数据文件。除非与 queryout 选项一起使用,否则使用该实用工具不需要了解 Transact-SQL 知识。若要将数据导入表中,必须使用为该表创建的格式文件,或者必须了解表的结构以及对于该表中的列有效的数据类型。

三、系统的实现

实现主要分为批处理文件的编写和Java程序中的调用两部分,这两部分完成之后,第一部分中的后续问题就好解决了。

①批处理编写:

编写的批处理文件如下,也就是使用bcp工具来进行备份

这里只列出部分表,代码都是一样的,使用的时候稍微修改下即可!@Title 根据userId导出的表

@bcp "SELECT * FROM sportSys.dbo.competitions wheresportSys.dbo.competitions.userId="+%1 queryout %2competitions.xls -T -c>>%3log.txt

@echo competitions表备份已完成!>>%3log.txt

@bcp "SELECT * FROM sportSys.dbo.item wheresportSys.dbo.item.userId="+%1 queryout %2item.xls -T -c>>%3log.txt

@echo item表备份已完成!>>%3log.txt

@bcp "SELECT * FROM sportSys.dbo.itemType wheresportSys.dbo.itemType.userId="+%1 queryout %2itemType.xls -T -c>>%3log.txt

@echo itemType表备份已完成!>>%3log.txt

@bcp "SELECT * FROM sportSys.dbo.agenda wheresportSys.dbo.agenda.userId="+%1 queryout %2agenda.xls -T -c>>%3log.txt

@echo agenda表备份已完成!>>%3log.txt

@bcp "SELECT * FROM sportSys.dbo.allroundInfo wheresportSys.dbo.allroundInfo.userId="+%1 queryout %2allroundInfo.xls -T -c>>%3log.txt

@echo allroundInfo表备份已完成!>>%3log.txt

@bcp "SELECT * FROM sportSys.dbo.athlete wheresportSys.dbo.athlete.userId="+%1 queryout %2athlete.xls -T -c>>%3log.txt

@echo athlete表备份已完成!>>%3log.txt

@exit

下面,我们来分析下这个批处理

bcp "SELECT * FROM sportSys.dbo.competitions wheresportSys.dbo.competitions.userId="+%1 queryout %2competitions.xls -T -c>>%3log.txt

bcp 这个是语法

双引号里面写的是Sql语句

%1、%2、%3是要传递给bat文件的参数

%1表示第一个参数,%2表示第二个参数,%3表示第三个参数。

本人的这三个参数的意思分别是:

第一个参数:查询条件

第二个参数:导出文件保存的位置

第三个参数:输出日志保存的位置

②Java程序中调用

导出文件publicString backUp()throwsException {

try{

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

Map session = ActionContext.getContext().getSession();

String userId = session.get("userId").toString();

String homeDir1 = request.getSession().getServletContext()

.getRealPath("/");

//Runtime.getRuntime().exec("notepad");

Runtime.getRuntime().exec(

"cmd /k start /b "+homeDir1+"backUp\\backupBy.bat"+" "+ userId +" "+

homeDir1+"download"+File.separatorChar + userId+File.separatorChar+" "+

homeDir1+"download"+File.separatorChar + userId+File.separatorChar);

}catch(IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

returnINPUT;

}

returnSUCCESS;

}

Java中调用命令行程序,的方式就是第11行Runtime.getRuntime().exec(

"cmd /k start /b "+homeDir1+"backUp\\backupBy.bat"+" "+ userId +" "+

homeDir1+"download"+File.separatorChar + userId+File.separatorChar+" "+

homeDir1+"download"+File.separatorChar + userId+File.separatorChar);

Runtime:

每个 Java 应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime方法获取当前运行时。

应用程序不能创建自己的 Runtime 类实例。public Process exec(String command)

throws IOException在单独的进程中执行指定的字符串命令。

这是一个很有用的方法。对于 exec(command) 形式的调用而言,其行为与调用 exec(command, null, null) 完全相同。

参数:

command - 一条指定的系统命令。

返回:

一个新的 Process 对象,用于管理子进程

抛出:

SecurityException - 如果安全管理器存在,并且其 checkExec 方法不允许创建子进程

IOException - 如果发生 I/O 错误

NullPointerException - 如果 command 为 null

IllegalArgumentException - 如果 command 为空

另请参见:

exec(String[], String[], File), ProcessBuilder

为了使调用bat文件来运行的时候,不至于弹出一个黑框,

加入/b参数 即可解决!

③导入

bcp sportSys.dbo.competitions in %1competitions.xls -c -t

以上便是导入的指令! 同样也可以设置将待导入的文件全部放在目录中,然后导入即可!

④压缩成Zip文件-工具类(网上有写好的ZipUtil)

packagecom.yaxing.util;

importjava.io.BufferedInputStream;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.util.jar.JarEntry;

importjava.util.jar.JarOutputStream;

importjava.util.jar.Manifest;

publicclassZipUtil {

protectedstaticbyte[] buf =newbyte[1024];

/**

* 私有构造函数防止被构建

*/

privateZipUtil() {

}

/**

* 遍历目录并添加文件.

*

* @param jos

*            - JAR 输出流

* @param file

*            - 目录文件名

* @param pathName

*            - ZIP中的目录名

* @throws IOException

* @throws FileNotFoundException

*/

privatestaticvoidrecurseFiles(finalJarOutputStream jos,

finalFile file,finalString pathName)throwsIOException,

FileNotFoundException {

// 文件夹则往下遍历

if(file.isDirectory()) {

finalString sPathName = pathName + file.getName() +"/";

jos.putNextEntry(newJarEntry(sPathName));

finalString[] fileNames = file.list();

if(fileNames !=null) {

for(inti =0; i < fileNames.length; i++) {

recurseFiles(jos,newFile(file, fileNames[i]), sPathName);

}

}

}

// 读取文件到ZIP/JAR文件条目

else{

// 使用指定名称创建新的 ZIP/JAR 条目

finalJarEntry jarEntry =newJarEntry(pathName + file.getName());

finalFileInputStream fin =newFileInputStream(file);

finalBufferedInputStream in =newBufferedInputStream(fin);

// 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处。

jos.putNextEntry(jarEntry);

intlen;

while((len = in.read(buf)) >=0) {

// 将字节数组写入当前 ZIP 条目数据

jos.write(buf,0, len);

}

in.close();

// 关闭当前 ZIP 条目并定位流以写入下一个条目

jos.closeEntry();

}

}

/**

* 创建 ZIP/JAR 文件.

*

* @param directory

*            - 要添加的目录

* @param zipFile

*            - 保存的 ZIP 文件名

* @param zipFolderName

*            - ZIP 中的路径名

* @param level

*            - 压缩级别(0~9)

* @throws IOException

* @throws FileNotFoundException

*/

publicstaticvoidmakeDirectoryToZip(finalFile directory,

finalFile zipFile,finalString zipFolderName,finalintlevel)

throwsIOException, FileNotFoundException {

FileOutputStream fos =null;

try{

// 输出文件流

fos =newFileOutputStream(zipFile);

}catch(finalException e) {

// 建立打包后的空文件

newFile(zipFile.getParent()).mkdirs();

zipFile.createNewFile();

fos =newFileOutputStream(zipFile);

}

// 使用指定的 Manifest 创建新的 JarOutputStream。清单作为输出流的第一个条目被写入

finalJarOutputStream jos =newJarOutputStream(fos,newManifest());

jos.setLevel(checkZipLevel(level));

finalString[] fileNames = directory.list();

if(fileNames !=null) {

for(inti =0; i < fileNames.length; i++) {

// 对一级目录下的所有文件或文件夹进行处理

recurseFiles(jos,newFile(directory, fileNames[i]),

zipFolderName ==null?"": zipFolderName);

}

}

// 关闭 ZIP 输出流和正在过滤的流。

jos.close();

}

/**

* 检查并设置有效的压缩级别,避免压缩级别设置错的异常

*

* @param level

*            - 压缩级别

* @return 有效的压缩级别或者默认压缩级别

*/

publicstaticintcheckZipLevel(finalintlevel) {

if(level <0|| level >9) {

return7;

}else{

returnlevel;

}

}

publicstaticvoidmain(finalString args[])throwsFileNotFoundException,

IOException {

// makeDirectoryToZip();

finalString homeDir = System.getProperty("user.dir");

System.out.println(homeDir);

finalFile zipFile =newFile(homeDir,"download"+ File.separatorChar

+"test.zip");

finalFile pagesDirectory =newFile(homeDir,"src");

System.out.println("Making zip file from folder /src to "+ zipFile);

ZipUtil.makeDirectoryToZip(pagesDirectory, zipFile,"",9);

System.out.println("Zip file "+ zipFile +" has been made.");

}

}

⑤Struts2执行Action里面的方法

publicString execute()throwsException {

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

Map session = ActionContext.getContext().getSession();

String userId = session.get("userId").toString();

finalString homeDir = request.getSession().getServletContext()

.getRealPath("/");// 打包后文件的位置及名称

finalFile zipFile =newFile(homeDir,"download"+ File.separatorChar

+ userId + File.separatorChar + userId +"bak.zip");// 要打包的文件夹路径

// if((new File(userId).isDirectory())){

// System.out.println("文件夹"+userId+"已存在!创建失败!");

// }else{

// new File(userId).mkdir();

// System.out.println("创建文件夹"+userId+"成功!");

// }

finalFile pagesDirectory =newFile(homeDir,"download/"+ userId);

LOG.info("Making zip file from folder /"+ userId +" to "+ zipFile);// 压缩文件

ZipUtil.makeDirectoryToZip(pagesDirectory, zipFile,"",9);

LOG.info("Zip file "+ zipFile +" has been made.");

response.sendRedirect("../download/"+ userId +"/"+ userId

+"bak.zip");

returnnull;

// return super.execute();

}

压缩文件创建之后,返回该压缩包,提供用户下载!用户将下载的文件导入客户端系统中,即可,

四、总结

本文总结了Java中调用批处理文件,给批处理文件传递参数的使用方法。依据此,可以实现项目中多种用途的数据备份。

欢迎各位交流,如有更好的方法,欢迎指出,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mycat和应用程序集成_企业应用程序集成简介

mycat和应用程序集成本文是我们名为“ EAI的Spring集成 ”的学院课程的一部分。 在本课程中&#xff0c;向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来&#xff0c;您将深入研究Spring Integration的基础知识&#xff0c;例如通道&#xff0c;转…

activemq和jms_带有ActiveMQ和Maven的JMS Sender应用程序

activemq和jms我们已经看到了如何使用ActiveMQ和Maven创建JMS Receiver应用程序 。 让我们看看我们如何类似地创建JMS Sender应用程序 。 web.xml与创建接收器应用程序时使用的相同&#xff1a; <web-app xmlns"http://java.sun.com/xml/ns/javaee"xmlns:xsi&qu…

java经纬度曲线简化_JAVA 后台计算 经纬度 最短距离

1、 代码块package com.ilogie.tms.util;import java.io.IOException;import java.math.BigDecimal;import java.text.MessageFormat;public class LocationUtils {// 以下为 获得 两点之间最短距离private static final BigDecimal EARTH_RADIUS MathUtil.toBigDecimal(6378.…

java ee的小程序_在Java EE应用程序中实现自动重试

java ee的小程序最初&#xff0c;我想将此博客称为“ 具有拦截器驱动的重试策略的灵活超时 ”&#xff0c;但后来我认为它太“繁重”。 该声明以及修改后的标题应该&#xff08;希望&#xff09;使您了解此帖子可能谈论的内容;-) 触发 这篇文章主要由我在较早的一篇文章中收到…

jboss eap 7_EAP 7 Alpha和Java EE 7入门

jboss eap 7红帽JBoss企业应用程序平台7&#xff08;JBoss EAP 7&#xff09;是基于开放标准构建并符合Java Enterprise Edition 7规范的中间件平台。 它建立在WildFly等经过验证的创新开源技术之上&#xff0c;这将使Java EE 7的开发更加容易。 这是有关如何开始使用最新ALPHA…

为什么说php单线程,php单线程的缺点是什么?

PHP即“超文本预处理器”&#xff0c;是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言&#xff0c;与C语言类似&#xff0c;是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习&#xff0c;使用广泛&#xff0c;主要适用于Web开发领…

openshift 部署_在OpenShift上部署Java EE微服务

openshift 部署我昨天用WildFly Swarm在博客上发布了有关简单JAX-RS微服务的博客。 您学习了如何使用Maven构建所谓的“胖子”&#xff0c;还使用Maven Docker插件对我们的微服务进行了Docker化并在Docker Machine上本地运行。 这是在本地测试事物的好方法。 到目前为止&#x…

apache.camel_Apache Camel 2.16发布–十大亮点

apache.camelApache Camel 2.16于上周五发布。 这篇博客文章是我尝试在此新版本中进行前10名&#xff08;加1作为奖励&#xff09;的亮点。 1.动态到 来自骆驼用户的最常见的常见问题是&#xff0c;如何将消息发送到端点&#xff0c;uri应该使用消息中的动态值&#xff08;例…

设计模式示例_责任链设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

edmonds算法matlab,匈牙利算法的matlab实现

匈牙利算法算法简介算法原理算法实现(附代码)测试算法简介下面摘用百度百科中的解释。匈牙利算法(Hungarian method)是由匈牙利数学家Edmonds于1965年提出&#xff0c;因而得名。匈牙利算法是基于Hall定理中充分性证明的思想&#xff0c;它是二分图匹配最常见的算法&#xff0c…

java jooq_将Java EE与jOOQ结合使用的初学者指南

java jooqJava EE附带了自己的持久性API&#xff1a;JPA。 当您想要将RDBMS实体&#xff08;表/关系&#xff09;映射到Java实体&#xff08;类&#xff09;时&#xff0c;JPA最强大&#xff0c;主要遵循1&#xff1a;1映射策略。 其背后的思想是&#xff0c;业务逻辑通常不像关…

php扩展 waf,基于PHP扩展的WAF实现

访问一下看看结果&#xff1a;可以看到ls命令成功的执行了&#xff0c;也就是说我们的正常文件是不会被拦截的&#xff0c;而只有upload目录中的文件会被拦截&#xff0c;这样做又会引发另一个弊端&#xff0c;倘若攻击者通过某种方法将shell写入正常的文件中&#xff0c;或是与…

junit4 集成测试_使用JUnit规则进行干净的集成测试

junit4 集成测试JUnit Rules的优势&#xff0c;尤其是在进行集成测试时&#xff0c;几乎不能被高估。 在本文中&#xff0c;我们将阐明ExternalResource扩展的有用性。 在我们必须使用抽象外部资源的第三方库的情况下&#xff0c;这简化了灯具控制。 作为示例&#xff0c;我们将…

多项式在matlab中的应用,matlab的应用-多项式函数及多项式拟合

matlab的应用-多项式函数及多项式拟合 Matlab 的应用- 多项式函数及多项式拟合 本节将向大家简要介绍 matlab 在多项式处理方面的应用。 多项式函数主要有&#xff1a; roots 求多项式的根 poly 特征多项式 polyval 多 项式的计算 poly2str(p, x )多项式代换 polyfit 多项式曲线…

乐惠科技php面试题,程序员中的奇葩,使用php构建魔兽世界

这是用PHP编写的魔兽世界服务器。现在它已经调试了登录服务器的过程。目前的魔兽世界客户端是2.4.3_8606。服务器列表和帐户密码数据需要查询AUTH库。世界服务器身份验证过程已完成&#xff0c;数据包加密已完成后续进程正在开发中......数据库文件在根目录: sql/sql.7z今天在群…

javafx窗体程序_JavaFX真实世界应用程序:EIZO CuratOR Caliop

javafx窗体程序JavaFX Real-World应用程序第四号称为Caliop 。 它是EIZO为医院手术室开发的CuratOR解决方案的前端。 前端在壁挂式控制台上运行&#xff0c;并允许操作团队查找有关患者的信息&#xff0c;控制各种视频源到不同显示器的路由&#xff0c;录制视频&#xff0c;拍摄…

java8 streams_Java 8 Streams:过滤和谓词否定

java8 streams最近&#xff0c;有关LJC 邮件列表的成员在流中.filter方法中使用谓词否定的有趣讨论&#xff0c;因此我认为值得在博客文章中进行总结。 讨论是关于使用.filter和否定谓词的方法。 这篇文章的代码可以在我的github帐户中找到 。 也许这就是您可能会想到的方式&…

hystrix熔断 简介_Hystrix简介– Hello World

hystrix熔断 简介在以前的博客文章中&#xff0c;我介绍了需要像Netflix Hystrix这样的库的动机。 在这里&#xff0c;我将跳入一些非常基本的方法来开始使用Hystrix&#xff0c;并在更复杂的用例中进行跟进。 你好&#xff0c;世界 以下是“ Hystrix命令”的一个简单的Hello …

php中哪个函数用于读取文件,PHP内置函数fget读取文件

php fgets()函数从文件指针读取一行语法:fgets(file,length)参数说明必需的. 指定姚要读取的文件长度可选. 指定姚都区的字节数. 默认值为102字节从文件所指向的文件中读取一行&#xff0c;并返回最大长度为1个字节的字符串. 遇到换行符(包含在返回值中&#xff0c;)&#xff0…

c++返回指针时候注意提防_提防Java中的函数式编程!

c返回指针时候注意提防这对函数式编程并不会造成太大的影响&#xff0c;这真棒。 这是关于某些实践的警告&#xff0c;您很可能会将其应用于您的代码&#xff0c;而这是完全错误的&#xff01; 。 高阶函数对于函数式编程是必不可少的&#xff0c;因此&#xff0c;谈论它们将帮…