18.14 系統(tǒng)初始化模塊
用戶登錄后,選擇“系統(tǒng)管理”→“系統(tǒng)初使化”菜單項(xiàng),進(jìn)入到系統(tǒng)初使化,在該頁面中將顯示提示信息,單擊【進(jìn)行系統(tǒng)初使化】按鈕,將進(jìn)行系統(tǒng)初使化操作。系統(tǒng)初始化頁面運(yùn)行結(jié)果如圖18.31所示。

圖18.31 系統(tǒng)初始化頁面運(yùn)行結(jié)果
18.14.1 創(chuàng)建系統(tǒng)初始化模塊的業(yè)務(wù)邏輯類
創(chuàng)建系統(tǒng)初始化模塊的業(yè)務(wù)邏輯類SysDAO,將其保存在com.dao包中,該類主要用于清空系統(tǒng)中的除用戶信息表以外的所有數(shù)據(jù)表和刪除用戶信息表中除超級用戶mr以外的全部用戶。值得注意的是:在刪除存在關(guān)聯(lián)關(guān)系的數(shù)據(jù)表時(shí),需要先刪除子表信息,再刪除主表信息,否則將發(fā)生錯誤。
系統(tǒng)初始化模塊的業(yè)務(wù)邏輯類SysDAO的關(guān)鍵代碼如下。
例程18-136:光盤\mr\18\MaterialManage\src\com\action\SysDAO .java
public class SysDAO {
public SysDAO(){
}
private Session session = null;
public int sysinitialize(){
session = MySession.openSession(); //打開Session
Transaction tx = null;
int rtn = 0;
try {
tx=session.beginTransaction();
//刪除用戶信息
session.createQuery("DELETE UserForm where name<>'mr'").executeUpdate();
session.createQuery("DELETE GetUseForm").executeUpdate(); //清空部門領(lǐng)用信息表
session.createQuery("DELETE DamageForm").executeUpdate(); //清空部門報(bào)損信息表
session.createQuery("DELETE CheckForm").executeUpdate(); //清空審核信息表
session.createQuery("DELETE InStorageForm").executeUpdate(); //清空入庫信息表
session.createQuery("DELETE StockDetailForm").executeUpdate(); //清空采購明細(xì)表
session.createQuery("DELETE StockMainForm").executeUpdate(); //清空采購主表
session.createQuery("DELETE ProviderForm").executeUpdate(); //清空供應(yīng)商信息表
session.createQuery("DELETE LoanForm").executeUpdate(); //清空物資借出信息表
session.createQuery("DELETE StorageForm").executeUpdate(); //清空庫存信息表
session.createQuery("DELETE BranchForm").executeUpdate(); //清空部門信息表
session.createQuery("DELETE GoodsForm").executeUpdate(); //清空商品信息表
rtn=1;
tx.commit();
}catch(Exception e){
if(tx!=null){
tx.rollback();
}
e.printStackTrace();
System.out.println("系統(tǒng)初使化時(shí)的錯誤信息:"+e.getMessage());
rtn=0;
} finally {
MySession.closeSession(session);
}
return rtn;
}
}
18.14.2 系統(tǒng)初始化頁面設(shè)計(jì)
系統(tǒng)初使化模塊共包括兩個JSP頁面,一個是用于顯示提示信息的initialize.jsp,另一個是用于執(zhí)行系統(tǒng)初使化操作的處理頁initialize_deal.jsp。由于initialize.jsp頁面比較簡單,此處不作介紹,下面介紹如何實(shí)現(xiàn)initialize_deal.jsp頁。
在執(zhí)行系統(tǒng)初使化操作的處理頁initialize_deal.jsp中,首先使用<jsp:useBean>動作指令生成SysDAO類的一個實(shí)例對象sysDAO,然后通過該實(shí)例對象調(diào)用SysDAO類的sysinitialize()方法,最后根據(jù)返回結(jié)果顯示相應(yīng)的提示信息,具體代碼如下。
例程18-137:光盤\mr\18\MaterialManage\defaultroot\initialize_deal.jsp
<%@ page contentType="text/html; charset=gb2312" language="java"%>
<jsp:useBean id="sysDAO" class="com.dao.SysDAO" scope="request"/>
<%
int rtn=sysDAO.sysinitialize();
if(rtn==0){
out.println("<script>alert('系統(tǒng)初使化失敗!');window.location.href='initialize.jsp';</script>");
}else{
out.println("<script>alert('系統(tǒng)初使化成功!\\r當(dāng)前系統(tǒng)中只有mr一個用戶,請重新登錄!');window.
location.href='index.jsp'</script>");
}
%>
18.15 疑難問題分析與解決
18.15.1 在Struts中解決中文亂碼
通常情況下解決中文亂碼采用的是編寫一個將ISO-8859-1編碼轉(zhuǎn)換為gb2312編碼的方法,然后在出現(xiàn)亂碼的位置調(diào)用該方法即可達(dá)到解決中文亂碼的目的,但是這樣做很不方便。Struts提供了一個快速解決中文亂碼的方法,那就是通過配置和擴(kuò)展RequestProcessor類實(shí)現(xiàn)。下面將詳細(xì)介紹在Struts中解決中文亂碼的方法。
(1)創(chuàng)建SelfRequestProcessor.java類文件,該類繼承了RequestProcessor類,并重寫processPreprocess()方法,在該方法中設(shè)置Request對象的請求編碼為gb2312編碼,具體代碼如下。
例程18-138:光盤\mr\18\MaterialManage\src\com\action\SelfRequestProcessor.java
package com.action;
import org.apache.struts.action.RequestProcessor;
import javax.servlet.http.*;
import java.io.*;
public class SelfRequestProcessor extends RequestProcessor {
public SelfRequestProcessor() {
}
protected boolean processPreprocess(HttpServletRequest request,HttpServletResponse response){
try {
request.setCharacterEncoding("gb2312");
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
return true;
}
}
(2)在struts-config.xml文件中利用<controller>元素配置自定義控制器組件SelfRequest Processor,用于對請求的參數(shù)進(jìn)行轉(zhuǎn)碼,具體代碼如下:
<controller processorClass="com.action.SelfRequestProcessor" />
配置<controller>元素主要是為了能讓Struts識別開發(fā)者自定義的控制器組件。
18.15.2 部門匯總模塊SQL語句解析
在部門匯總模塊中需要將部門領(lǐng)用信息和部門報(bào)損信息按部門進(jìn)行匯總并統(tǒng)計(jì)各部門正在使用物資的數(shù)量和金額,這可以通過以下SQL語句實(shí)現(xiàn):
select g.name,g.spec,g.unit,g.price,t.branchname,t.lyamount,t.bsamount,
(t.lyamount-t.bsamount) zyamount from tb_goods g inner join ( select goodsid,branchname,
sum(bsamount) bsamount,sum(lyamount) lyamount from(select getuse.goodsid,0 as bsamount,
sum(getuse.number) as lyamount,branch.name as branchname from tb_getuse getuse inner join
tb_branch branch on getuse.branchid=branch.id group by branch.name,getuse.goodsid
union select damage.goodsid,sum(damage.damagenum) as bsamount,0 as lyamount,
branch.name as branchname from tb_damage damage inner join
tb_branch branch on damage.branchid=branch.id group by branch.name,damage.goodsid ) as t
group by goodsid,branchname) as t on g.id=t.goodsid
下面將對上面的SQL語句進(jìn)行詳細(xì)的分析。
(1)查詢部門信息的SQL語句如下:
select * from tb_getuse
執(zhí)行結(jié)果如圖18.32所示。

圖18.32 部門信息
(2)查詢部門領(lǐng)用信息的SQL語句如下:
select * from tb_getuse
執(zhí)行結(jié)果如圖18.33所示。

圖18.33 部門領(lǐng)用信息
(3)通過INNER JOIN子句將部門領(lǐng)用信息表和部門信息表進(jìn)行關(guān)聯(lián),具體SQL語句如下:
select * from tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id
執(zhí)行結(jié)果如圖18.34所示。

圖18.34 與部門信息表關(guān)聯(lián)后的部門領(lǐng)用信息
(4)根據(jù)部門名稱和物資ID對關(guān)聯(lián)后的部門領(lǐng)用信息進(jìn)行分組并統(tǒng)計(jì)部門領(lǐng)用各物資的數(shù)量,具體SQL語句如下:
select getuse.goodsid,sum(getuse.number) as lyamount,branch.name as branchname from tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id group by branch.name,getuse.goodsid
執(zhí)行結(jié)果如圖18.35所示。
(5)在步驟(4)中的SQL語句的輸出結(jié)果中添加一個新的列bsamount,該列的值均為0,具體SQL語句如下:
select getuse.goodsid,0 as bsamount,sum(getuse.number) as lyamount,branch.name as branchname from
tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id
group by branch.name,getuse.goodsid
執(zhí)行結(jié)果如圖18.36所示。

圖18.35 分組統(tǒng)計(jì)后的信息 圖18.36 添加bsamount列后的信息
(6)查詢部門報(bào)損信息的SQL語句如下:
select * from tb_damage
執(zhí)行結(jié)果如圖18.37所示。

圖18.37 部門報(bào)損信息
(7)通過INNER JOIN子句將部門報(bào)損信息表和部門信息表進(jìn)行關(guān)聯(lián),具體SQL語句如下:
select * from tb_damage damage inner join tb_branch branch on damage.branchid=branch.id
執(zhí)行結(jié)果如圖18.38所示。

圖18.38 與部門信息表關(guān)聯(lián)后的部門報(bào)損信息
(8)根據(jù)部門名稱和物資ID對關(guān)聯(lián)后的部門報(bào)損信息進(jìn)行分組并統(tǒng)計(jì)部門報(bào)損各物資的數(shù)量,具體SQL語句如下:
select damage.goodsid,sum(damage.damagenum) as bsamount,branch.name as branchname from
tb_damage damage inner join tb_branch branch on damage.branchid=branch.id group by
branch.name,damage.goodsid
執(zhí)行結(jié)果如圖18.39所示。

圖18.39 分組統(tǒng)計(jì)后的信息 圖18.40 添加lyamount列后的信息
(9)在步驟(8)中的SQL語句的輸出結(jié)果中添加一個新的列l(wèi)yamount,該列的值均為0,具體SQL語句如下:
select damage.goodsid,sum(damage.damagenum) as bsamount,0 as lyamount,
branch.name as branchname from tb_damage damage inner join
tb_branch branch on damage.branchid=branch.id group by branch.name,damage.goodsid
執(zhí)行結(jié)果如圖18.40所示。
(10)通過UNION子句將步驟(5)和步驟(9)的結(jié)果合并,具體SQL語句如下:
select getuse.goodsid,0 as bsamount,sum(getuse.number) as lyamount,branch.name as branchname from
tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id group by
branch.name,getuse.goodsid
union
select damage.goodsid,sum(damage.damagenum) as bsamount,0 as lyamount,
branch.name as branchname from tb_damage damage inner join
tb_branch branch on damage.branchid=branch.id group by branch.name,damage.goodsid
執(zhí)行結(jié)果如圖18.41所示。
(11)對步驟(10)的合并結(jié)果進(jìn)行分組統(tǒng)計(jì),具體SQL語句如下:
select goodsid,branchname,sum(bsamount) bsamount,sum(lyamount) lyamount from(
select getuse.goodsid,0 as bsamount,sum(getuse.number) as lyamount,branch.name as branchname from
tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id group by
branch.name,getuse.goodsid
union
select damage.goodsid,sum(damage.damagenum) as bsamount,0 as lyamount,branch.name as branchname
from tb_damage damage inner join tb_branch branch on damage.branchid=branch.id
group by branch.name,damage.goodsid
) as t group by goodsid,branchname
執(zhí)行結(jié)果如圖18.42所示。

圖18.41 合并后的結(jié)果 圖18.42 分組統(tǒng)計(jì)后的結(jié)果
(12)將步驟(10)的分組統(tǒng)計(jì)結(jié)果與物資信息表tb_goods通過INNER JOIN子句進(jìn)行關(guān)聯(lián),具體SQL語句如下:
select g.name,g.spec,g.unit,g.price,t.branchname,t.lyamount,t.bsamount from tb_goods g inner join (
select goodsid,branchname,sum(bsamount) bsamount,sum(lyamount) lyamount from(
select getuse.goodsid,0 as bsamount,sum(getuse.number) as lyamount,branch.name as branchname from
tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id group by
branch.name,getuse.goodsid
union
select damage.goodsid,sum(damage.damagenum) as bsamount,0 as lyamount,branch.name as branchname
from tb_damage damage inner join tb_branch branch on damage.branchid=branch.id
group by branch.name,damage.goodsid
) as t group by goodsid,branchname
) as t on g.id=t.goodsid
執(zhí)行結(jié)果如圖18.43所示。

圖18.43 分組統(tǒng)計(jì)后的結(jié)果
(13)在步驟(12)的分組統(tǒng)計(jì)結(jié)果的基礎(chǔ)上添加一個新的輸出列zyamount,該列的值為領(lǐng)用數(shù)量減去報(bào)損數(shù)量,即正在使用數(shù)量,具體SQL語句如下:
select g.name,g.spec,g.unit,g.price,t.branchname,t.lyamount,t.bsamount,(t.lyamount-t.bsamount) zyamount
from tb_goods g inner join (
select goodsid,branchname,sum(bsamount) bsamount,sum(lyamount) lyamount from(
select getuse.goodsid,0 as bsamount,sum(getuse.number) as lyamount,branch.name as branchname from
tb_getuse getuse inner join tb_branch branch on getuse.branchid=branch.id group by
branch.name,getuse.goodsid
union
select damage.goodsid,sum(damage.damagenum) as bsamount,0 as lyamount,branch.name as branchname
from tb_damage damage inner join tb_branch branch on damage.branchid=branch.id
group by branch.name,damage.goodsid
) as t group by goodsid,branchname
) as t on g.id=t.goodsid
執(zhí)行結(jié)果如圖18.44所示。

圖18.44 最后執(zhí)行結(jié)果