JAVA对SQL SERVER 2000的备份和恢复-从C/S到B/S(3)

 

       上篇文章我们用Swing的知识做了一个关于数据备份和恢复的桌面应用,现在我们就着手做一个WEB应用。这个简单,JSP就可以搞定了。但是且慢,我们知道,HTTP协议是无状态的,传统的WEB应用不管是提交表单,还是超链接或者JS跳转都会刷新页面,这样如果页面操作稍微复杂一点,是很难在重新请求后还维持着原有状态的。那么我们看着Swing的窗口就会发呆:能不能将WEB应用做的跟桌面应用一样及时响应局部刷新呢?

 

       我们想一想,Swing桌面应用为什么可以局部刷新?哦,Swing桌面应用中没有无状态的HTTP协议,也不存在WEB服务器,而Java语言又具有访问文件和数据库服务器的能力,所以完全可以通过Swing桌面组件的事件监听机制来动态更新用户界面。那么,我们想起来了,在WEB浏览器端的网页界面上,也可以使用一种带有事件驱动模型的语言:Javascript!它不是也可以操作DOM来更新网页吗?!可是,现在的问题在于,Javascript并不具有访问文件和数据库服务器的能力,也就是说,Javascript只是一种客户端的脚本语言,它没有办法得到存储在文件或者数据库上的动态数据,也没有办法将用户填充的数据存放到这些存储介质上。真是头疼,怎么办?JavascriptJava?恩。在WEB浏览器端可以利用Javascript的事件驱动机制,在WEB服务器端能够使用Java语言写JSP或者Servlet组件来访问数据库!这样的话,要是可以在Web浏览器端的Javascript代码中调用Web服务器上的Java代码,就像是Java代码就在浏览器中一样。那不就大功告成了吗?哈哈,有思路了。能够非常优秀地做到这一点的,就是一款Ajax的框架—DWRDirect Web Remoting)!

 

       Ajax(Asynchronous JavaScript and XML)我们应该不陌生了,它彻底颠覆了传统WEB应用的模式,极大地改善了用户体验。在Ajax之前,我们就是提交请求—等待—提交请求—等待的周而复始,有了Ajax之后,我们的操作和对服务器请求就可以异步地进行,再也不用枯燥地等待了。如果大家以前没有使用Ajax的经验并且对它有兴趣,请参阅拙作:http://blog.csdn.net/lenotang/archive/2008/07/22/2692926.aspx 。那么,什么叫异步呢?举一个生活中的例子:我们程序员写代码,写的口渴了就倒水喝,而在我们倒水的时候是无法继续写代码的。也就是说,写代码和倒水是同步(按照一定先后顺序)进行的。这也就是传统WEB应用的模式。但是,如果我们有一个很贤惠(注意,这里许老师所说的贤惠并不是指闲在家里什么都不会^_^!)的女朋友在身边,情况就完全不一样了。敲代码,口渴了,一个眼神或者一个响指,茶就到了嘴边。也就是说,茶是你女朋友帮忙在倒,她在倒茶的时候你的代码不用停下来。这就是异步(同一时间做多件事情)。Ajax应用里面就有个类似女朋友这样的角色—XMLHttpRequest对象!各位,现在体验到有女朋友的好处了吧。(当然,女朋友比较凶悍的,切勿模仿,否则,非但没有茶喝,头上还可能长丘陵!)

 

       呵呵,我们来看看DWR吧!DWR包含2个主要部分:

1.一个运行在服务器端的Java Servlet,它处理请求并且向浏览器返回响应。

2.运行在浏览器端的JavaScript,它发送请求而且还能动态更新网页。

 

我们要想使用这个Ajax的框架,首先还是老规矩,导入第三方JARdwr.jar,然后在web.xml上做DwrServlet的配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <servlet>

        <servlet-name>dwr-invoker</servlet-name>

        <servlet-class>

            org.directwebremoting.servlet.DwrServlet

        </servlet-class>

        <init-param>

            <param-name>debug</param-name>

            <param-value>true</param-value>

        </init-param>

    </servlet>

 

    <servlet-mapping>

        <servlet-name>dwr-invoker</servlet-name>

        <url-pattern>/dwr/*</url-pattern>

    </servlet-mapping>

    <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

</web-app>

除此之外,我们还要做一个dwr.xml放在WEB-INF目录下,里面就可以注册类别,配置JavascriptJava的映射。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE dwr PUBLIC

    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"

    "http://getahead.org/dwr/dwr20.dtd">

<dwr>

    <allow>

        <create creator="new" javascript="OperaDAO">

            <param name="class"

                value="com.wepull.model.OperationDAO">

            </param>

        </create>

    </allow>

</dwr>

最后,我们就可以写一个HTML文件backupRestore.html来完成我们的工作(里面要include几个JS文件):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>测试DWR操作数据库</title>

<style type="text/css">

body {

    font-size: 12px;

    font-family: "宋体", arial;

    color:#33333;

}

 

table select {

    width: 150px;

    background: #cecece;

    border: 5px solid red;

    padding: 0px;

    margin: 0px;

}

 

#showMsg {

    width: 360px;

    color: red;

}

 

.opeBtn {

    font-size: 12px;

    border: 1px solid #cecece;

    cursor: hand;

}

.ope {

    font-size: 12px;

    border: 1px solid #cecece;

}

h1{

    color:red;

}

</style>

<script type="text/javascript" src="/dwrDB/dwr/interface/OperaDAO.js"></script>

<script type="text/javascript" src="/dwrDB/dwr/engine.js"></script>

<script type="text/javascript" src="/dwrDB/dwr/util.js"></script>

<!-- 

<script type="text/javascript" src="js/OperaDAO.js"></script>

<script type="text/javascript" src="js/engine.js"></script>

<script type="text/javascript" src="js/util.js"></script>

-->

<script type="text/javascript">

//页面加载后,获取并显示全部数据库

window.onload = getDatabases;

function getDatabases(){

//Web浏览器端的Javascript代码调用Web服务器上的Java代码,就像是Java代码就在浏览器中一样。这就是DWR提供的功能!

OperaDAO.getDatabases(callbackDb);

$("database").onchange=function(){

showDataTable(this.value);

DWRUtil.addOptions("showMsg", new Array("选择数据库"+this.value+",列出下属数据表!"));

$("bkdbBtn").disabled=false;

$("rsdbBtn").disabled=false;

$("dtdbBtn").disabled=false;

$("bakAllBtn").disabled=false;

};

}

//回调函数,参数为调用返回值。在这里我们可以动态更新网页。

function callbackDb(list){

DWRUtil.removeAllOptions("database");

DWRUtil.addOptions("database", list);

}

//显示全部数据表

function showDataTable(dbName){

OperaDAO.getTableNames(dbName,callbackTable);

$("dataTable").onchange=function(){

$("bakBtn").disabled = false;

DWRUtil.addOptions("showMsg", new Array("选择数据表"+this.value+",您可以执行备份的操作!"));

};

}

function callbackTable(list){

DWRUtil.useLoadingMessage("wait....");

DWRUtil.removeAllOptions("dataTable");

if(list==null||list==""){

DWRUtil.addOptions("showMsg", new Array("该数据库没有数据表!"));

$("bakBtn").disabled = true;

return;

}

DWRUtil.addOptions("dataTable", list);

}

//清空表格名称列表

function clearDataTable(){

$("dataTable").length=0;

}

//显示全部数据文件

function showDataFile(){

if($("database").value==""){

DWRUtil.addOptions("showMsg", new Array("请先选择对应的数据库!"));

return;

}

$("resAllBtn").disabled = false;

OperaDAO.getDataFilePath($("database").value,callbackFile);

$("dataFile").onchange=function(){

$("resBtn").disabled = false;

DWRUtil.addOptions("showMsg", new Array("选择数据文件"+this.value+",您可以执行恢复的操作!"));

};

}

function callbackFile(list){

DWRUtil.useLoadingMessage("wait....");

DWRUtil.removeAllOptions("dataFile");

if(list==null){

DWRUtil.addOptions("showMsg", new Array("该数据库没有对应的数据备份文件!"));

$("resBtn").disabled = true;

return;

}

DWRUtil.addOptions("dataFile", list);

DWRUtil.addOptions("showMsg", new Array("显示"+$("database").value+"数据库下对应的所有数据文件!"));

}

//备份数据表

function backupDataTable(cond){

var tbNames = new Array();

var dataTables = $("dataTable");

if(cond==1){

for(var i = 0;i<dataTables.length;i++){

    tbNames[i]=dataTables[i].value;

}

}else{

var count = 0;

for(var i = 0;i<dataTables.length;i++){

if(dataTables[i].selected){

    tbNames[count]=dataTables[i].value;

    count++;

}

}

if(count==0){

DWRUtil.addOptions("showMsg", new Array("请选择您要备份的数据表!"));

return;

}

}

if(confirm("您确信要备份对应表的数据文件吗?")){

changeDisabled(true,true,true,true,true,true,true,true);

OperaDAO.backupTables($("database").value,tbNames,callbackBackup);

}

}

 

function callbackBackup(list){

DWRUtil.addOptions("showMsg", list);

changeDisabled(false,false,true,true,false,false,false,true);

 

}

//恢复数据文件

function restoreDataFile(cond){

var fNames = new Array();

var dataFiles = $("dataFile");

if(cond==1){

for(var i = 0;i<dataFiles.length;i++){

    fNames[i]=dataFiles[i].value;

}

}else{

var count = 0;

for(var i = 0;i<dataFiles.length;i++){

if(dataFiles[i].selected){

    fNames[count]=dataFiles[i].value;

    count++;

}

}

if(count==0){

DWRUtil.addOptions("showMsg", new Array("请选择您要恢复的数据文件!"));

return;

}

 

}

OperaDAO.restoreFiles($("database").value,fNames,callbackRestore);

}

 

function callbackRestore(list){

DWRUtil.removeAllOptions("showMsg");

DWRUtil.addOptions("showMsg", list);

}

function clearMsg(){

DWRUtil.removeAllOptions("showMsg");

}

//备份整个数据库

function backupDatabase(){

if($("database").value==""){

DWRUtil.addOptions("showMsg", new Array("请先选择对应的数据库!"));

return;

}

if(confirm("您确信要备份整个数据库"+$("database").value+"?")){

$("bkdbBtn").disabled=true;

OperaDAO.backupDatabase($("database").value,callbackBkDB);

}

}

function callbackBkDB(list){

DWRUtil.addOptions("showMsg", list);

$("bkdbBtn").disabled=false;

}

//恢复整个数据库

function restoreDatabase(){

if($("database").value==""){

DWRUtil.addOptions("showMsg", new Array("请先选择对应的数据库!"));

return;

}

if(confirm("您确信要恢复整个数据库"+$("database").value+"?")){

$("rsdbBtn").disabled=true;

OperaDAO.restoreDatabase($("database").value,callbackrsDB);

}

}

function callbackrsDB(list){

DWRUtil.addOptions("showMsg", list);

$("rsdbBtn").disabled=false;

}

//分离数据库

function detachDatabase(){

if($("database").value==""){

DWRUtil.addOptions("showMsg", new Array("请先选择对应的数据库!"));

return;

}

if(confirm("您确信要分离数据库"+$("database").value+"?")){

$("dtdbBtn").disabled=true;

OperaDAO.detachDatabase($("database").value,callbackdetachDB);

}

}

function callbackdetachDB(list){

//分离完数据库刷新数据库列表

getDatabases();

clearDataTable();

DWRUtil.addOptions("showMsg", list);

}

//附加数据库

function attachDatabase(){

if($("attDBName").value==""){

DWRUtil.addOptions("showMsg", new Array("请先填写要附加的数据库名!"));

$("attDBName").focus();

return;

}

if(confirm("您确信要附加数据文件到数据库"+$("attDBName").value+"?")){

$("atdbBtn").disabled=true;

OperaDAO.attachDatabase($("attDBName").value,$("dFile").value,$("lFile").value,callbackattachDB);

}

}

function callbackattachDB(list){

//附加完数据库刷新数据库列表

getDatabases();

clearDataTable();

DWRUtil.addOptions("showMsg", list);

$("atdbBtn").disabled=false;

}

 

function judgeDBName(dbName){

//DWRUtil.addOptions("showMsg", new Array("正在填写..."+dbName.value));

for(var i=0;i< $("database").length;i++){

if($("database")[i].value==dbName.value){

$("atdbBtn").disabled = true;

return;

}

}

$("atdbBtn").disabled = false;

}

//改变每个按钮的可操作性

function changeDisabled(flag1,flag2,flag3,flag4,flag5,flag6,flag7,flag8){

$("bakBtn").disabled=flag1;

$("bakAllBtn").disabled=flag2;

$("resBtn").disabled=flag3;

$("resAllBtn").disabled=flag4;

$("bkdbBtn").disabled=flag5;

$("rsdbBtn").disabled=flag6;

$("dtdbBtn").disabled=flag7;

$("atdbBtn").disabled=flag8;

}

</script>

</head>

<body>

<center>

<h1>数据库操作关系重大,请您务必小心谨慎!</h1>

</center>

附加数据库名:

<input class="ope" type="text" name="attDBName" onkeyup="judgeDBName(this)">

<input class="ope" type="file" name="dFile">

<input class="ope" type="file" name="lFile">

<br>

<table>

    <tr>

       <td>数据库</td>

       <td>数据表</td>

       <td><input class="opeBtn" type="button" value="显示数据备份文件"

           onclick="showDataFile()"></td>

       <td><input class="opeBtn" type="button" value="清空信息显示区" onclick="clearMsg()"></td>

    </tr>

    <tr>

       <td><select id="database" size="20">

       </select></td>

       <td><select id="dataTable" size="20" multiple>

       </select></td>

       <td><select id="dataFile" size="20" multiple>

       </select></td>

       <td><select id="showMsg" size="20" multiple>

       </select></td>

    </tr>

    <tr>

       <td colspan="4"><input id="bakBtn" class="opeBtn" type="button"

           value="备份选择数据表" onclick="backupDataTable(0)" disabled> <input

           id="bakAllBtn" class="opeBtn" type="button" value="备份全部数据表"

           onclick="backupDataTable(1)" disabled> <input id="resBtn"

           class="opeBtn" type="button" value="恢复选择文件"

           onclick="restoreDataFile(0)" disabled> <input id="resAllBtn"

           class="opeBtn" type="button" value="恢复全部文件"

           onclick="restoreDataFile(1)" disabled></td>

    </tr>

    <tr>

       <td colspan="4"><input id="bkdbBtn" class="opeBtn" type="button"

           value="备份数据库" onclick="backupDatabase()" disabled> <input

           id="rsdbBtn" class="opeBtn" type="button" value="恢复数据库"

           onclick="restoreDatabase()" disabled> <input id="dtdbBtn"

           class="opeBtn" type="button" value="分离数据库" onclick="detachDatabase()"

           disabled> <input id="atdbBtn" class="opeBtn" type="button"

           value="附加数据库" onclick="attachDatabase()" disabled></td>

    </tr>

</table>

</body>

</html>

 

我这里为了方便起见,就把CSSJS都写在上面的 HTML文件中,这里大家要注意,dwrDB是我们WEB工程的名字,OperaDAO.js要和dwr.xml上的配置一致。我们怎么知道DWR的配置无误呢?启动服务器,在浏览器的地址栏上输入:http://localhost:8080/dwrDB/dwr ,如果看到DWR框架能够识别OperaDAO就代表Ok了。大家可以看到DWR的使用是非常便利的,并且真的很神奇。不是吗?在我们的Javascript里面调用Java对象的方法轻而易举,它向使用者屏蔽了JavascriptJava,也就是客户端和服务器端之间的界限!使用一个回调函数就得到了服务器端Java方法的返回内容。是不是非常棒?!好了,大家要好好地揣摩一下代码,把这个理解了之后,也可以系统地学习一下DWR这个优秀的框架。下一篇文章,我们将看到DWRSpring这两个优秀框架的强强联手!

你可能感兴趣的:(JavaScript,java,sql,数据库,function,server,database)