国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
MVC模式的設計思想
MVC模式是一種近年來使用比較廣泛的為許多IT廠家和開發(fā)者所認可的一種設計模式,它和Web應用程序并沒有直接的關系(事實上,它在很多非WEB應用程序中得到了使用),它不僅使得系統(tǒng)層次分明、職責清晰,而且使得系統(tǒng)更易于維護。在MVC模式中的三個關鍵部件及其主要功能職責是:
The Model Component:主要負責業(yè)務域的業(yè)務目標的實現(xiàn)。
The View Component:主要負責對業(yè)務域的數據展現(xiàn)給客戶端。
The Controller Component:主要負責控制系統(tǒng)流程和用戶輸入狀態(tài)
在基于Java技術的Web應用程序中,Model部分的主要組件是JavaBean和EJB,View部分的主要組件是HTML和JSP程序,Controller部分的主要組件是Servlet部分。
下面列出了一些使用MVC模式的好處:
1、        它將業(yè)務邏輯與展現(xiàn)分離開來,避免了將業(yè)務邏輯與展現(xiàn)混雜在一起帶來的顯示的不一致性和業(yè)務邏輯代碼重復地分布在用于展現(xiàn)的代碼中。
2、        層次清晰,易于開發(fā)者對這三個部分分工與協(xié)作,易于維護者識別不同的層次實施不同的維護策略。
3、        系統(tǒng)具有更好的重用性,包括用戶界面的重用和業(yè)務邏輯處理包的重用,特別是業(yè)務邏輯處理包,如果遵循相應的java規(guī)范,它不僅可以在web應用程序中使用,而且可以在包括桌面、分布式環(huán)境下的得到重用。
4、        系統(tǒng)更易于擴展和移植。
5、        系統(tǒng)更易于維護。
6、        采用MVC模式開發(fā)的系統(tǒng)更健壯。
7、        對于大型的應用程序優(yōu)勢更為明顯。
談到設計模式,可以想一下我們常用的jsp+bean和jsp+servlet+bean的模式
JSP Model1
JSP Model2
上圖中,JSP Model1即JSP+JavaBean的模式,在這種模式下,處理客戶端的請求和將輸出展現(xiàn)給客戶端都是由JSP頁面負責的,在模式1中,整個過程沒有Servlet的參與,它將主要的業(yè)務邏輯放到JavaBean中實現(xiàn),而將頁面展現(xiàn)和請求控制交給JSP處理。
不可否認jsp的開發(fā)模式簡化了開發(fā)Web應用程序的復雜度,但是其缺點是顯而易見的,由于jsp是在html中嵌入java代碼的方式實現(xiàn)的,不可避免地,它也面臨很多問題:如頁面展現(xiàn)與業(yè)務邏輯混合在一起,仍然無法在開發(fā)過程中將不同的角色更清晰地區(qū)分開來;jsp頁面中將會夾雜大量的java代碼,維護變得困難;同時,業(yè)務邏輯的改動也將面臨動一發(fā)而影響全局的窘境。
JSP Model2即JSP+Servlet+JavaBean的模式,它和模式1的最大不同是它多了Servlet層,用于控制用戶的請求和將JavaBean的業(yè)務輸出傳遞給JSP來展現(xiàn),這樣就將數據展現(xiàn)、業(yè)務控制、業(yè)務邏輯實現(xiàn)分離開來,這就是早期的MVC(Model-View-Control)模式。顯然,這種模式相對于jsp+bean的模式來說應用程序更具擴展性和靈活性,并且更易于維護。但是這種簡單的MVC模式也有缺點,第一、沒有成熟的MVC框架中所帶有的各種強大和實用的功能,第二、配置文件不好管理,成熟的MVC框架支持多配置文件,而servlet的配置都寫在web.xml中,這會導致web.xml文件難以管理。因此有必要掌握一種成熟的MVC的開發(fā)框架。
對于現(xiàn)有較成熟的Model-View-Control(MVC)框架而言,其解決的主要問題有下面幾部分:
1. 將Web頁面中的輸入元素封裝為一個(請求)數據對象。
2. 根據請求的不同,調度相應的邏輯處理單元,并將(請求)數據對象作為參數傳入。
3. 邏輯處理單元完成運算后,返回一個結果數據對象。
4. 將結果數據對象中的數據與預先設計的表現(xiàn)層相融合并展現(xiàn)給用戶。
數據封裝和持久性
在MVC的設計思想中,數據在不同層之間的傳遞是以數值對象的形式進行封裝的,這里的數值對象是指不同層之間傳輸數據的容器,在不同的層中數據的傳輸應該封裝在數值對象中(不可能把resultSet對象用于各層數據的傳遞,這有背于MVC的設計思想),這樣能夠提高網絡傳輸效率(減少傳輸次數),同時使得維護更方便。
通常數值對象就是一個Bean,它對數據庫中的表或視圖的字段進行了封裝,一個數值對象可以看成表或視圖中的一條記錄。
一個簡單的數據對象
public class User{
private String bh;
private String name;
public String getName() {
return name;
}
public String getBh() {
return bh;
}
public void setName(String name) {
this.name = name;
}
public void setBh(String bh) {
this.bh = bh;
}
public User() {
}
}
通常我們會這樣做,
控制器在接收提交請求后將request對象中提交過來的數據封裝在User的實例中
User user = new User();
user.setBh(request.getParameter(“bh”));
user.setName(request.getParameter(“Name”));
然后將該數據對象作為參數傳遞給邏輯Bean或直接用數據訪問對象來執(zhí)行業(yè)務操作,
UserDAO userDAO = new UserDAO();
userDAO.insertUser(user);
User user = userDAO.getUser(request.getParameter(“bh”));
List userList = userDAO.getUserList();
數據底層的訪問在UserDAO中進行,打開數據連接connection,查詢得到結果集resultset將數據封裝在User的實例中,關閉連接返回數值對象,或者調用statement對象進行更新操作。操作完畢后由控制器將獲取的數值對象發(fā)往頁面。
public User getUser(String id)throws SQLException{
Connection conn = null;
try{
conn = this.ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from user where id='" + id +"'");
User user = null;
if (rs.next()) {
user = new User();
user.setBh(rs.getString("bh"));
user.setBh(rs.getString("name"));
}
return user;
}
finally{
conn.close();
}
}
對于單條記錄用user對象實例封裝,那么對于多條記錄集則是以List集合的形式進行封裝,List集合中的每個對象就是一個user對象實例,
public List getUserList() throws SQLException {
Connection conn = null;
try {
conn = this.ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from user");
List userList = new ArrayList();
while (rs.next()) {
User user = new User();
user.setBh(rs.getString("bh"));
user.setBh(rs.getString("name"));
userList.add(user);
}
return userList;
}
finally {
conn.close();
}
}
上面的例子只是說明了MVC模式中的數據封裝的思想,如果按照上面的例子寫,你會發(fā)現(xiàn)要寫好多的數值對象來映射數據庫的表,對于查詢的得到的結果集都要手動進行封裝,一旦數據庫的表發(fā)生了變化,那么改起來將非常的繁瑣,因此在實際運用中應該采取效率更高的數據封裝辦法,通過Map對象代替數值對象并配合合適的數據持久層的支持就可以達到數據封裝的自動化,從而提高我們的開發(fā)效率。
綜上所述,選擇合適的MVC框架和數據持久層作為我們項目中的開發(fā)模式是很有必要的,通過對現(xiàn)在流行的MVC框架和數據持久層的了解,Spring+Ibatis的開發(fā)模式是很適合的一種。
Spring的優(yōu)點
Spring提供了一套成熟而全面的基礎框架,站在應用開發(fā)的實際角度來說,其最大的優(yōu)勢在于:Spring是一個從實際項目開發(fā)經驗中抽取的,可高度重用的應用框架。
Spring Framework中目前最引人注目的,也就是名為控制反轉(IOC =Inverse Of Control)或者依賴注入(DI =Dependence Injection)的設計思想。
IoC,就是由容器控制程序之間的關系,而非傳統(tǒng)實現(xiàn)中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。所謂依賴注入,即組件之間的依賴關系由容器在運行期決定,形象的來說,即由容器動態(tài)的將某種依賴關系注入到組件之中,實現(xiàn)了組件真正意義上的即插即用。這也是Spring最具價值的特性之一
但是,光一個單純的設計模式并不能使得Spring如此成功,而Spring最成功的地方也并不僅僅在于采用了IOC/DI的設計。
首先,Spring涵蓋了應用系統(tǒng)開發(fā)所涉及的大多數技術范疇,包括MVC、ORM以及RemoteInterface等,這些技術往往貫穿了大多數應用系統(tǒng)的開發(fā)過程。Spring從開發(fā)者的角度對這些技術內容進行了進一步的封裝和抽象,使得應用開發(fā)更為簡便。
其次,Spring并非一個強制性框架,它提供了很多獨立的組件可供選擇。
Spring的基本配置和基礎對象使用方法
Ibatis的優(yōu)點
Ibatis的基本配置和核心對象使用方法
Ibatis在Spring中的配置和運用
Jstl表現(xiàn)技術的運用
實例
結合于Spring和Ibatis的實際運用我寫了一個例子,例子中實現(xiàn)了一個簡單的登錄過程和一個訂貨單的主從表形式的增、刪、改、查功能,以供大家參考。
我使用了Spring中的AbstractController控制器作為整個程序的基本的控制器,之所以這樣做是考慮到簡單實用的目的,同時能夠實現(xiàn)主從表形式的數據輸入,對于事務管理直接用ibatis中提供的事務管理功能,jsp頁面統(tǒng)一存放在WEB-INF\view\下面,這樣可以防止用戶直接通過地址欄來訪問jsp頁面,jsp頁面上用到的js腳本都以js文件的形式include到頁面中,對于頁面上的數據都以jstl的標簽來輸出達到頁面簡潔的目的。
配置文件說明
/WEB-INF/web.xml文件
程序運行的主要配置文件,配置了各種系統(tǒng)變量,對spring的加載,日志的加載等等
/WEB-INF/applicationContext.xml文件
啟動時由spring加載系統(tǒng)中用到的各種bean
/WEB-INF/main-config.xml文件
對系統(tǒng)管理模塊中的請求/處理單元的配置
/WEB-INF/indent-config.xml文件
對訂貨單模塊中的請求/處理單元的配置
/WEB-INF/sqlMapConfig.xml文件
Ibatis的核心配置文件
WEB-INF\classes\com\ user.xml文件
用戶模塊的sql語句的映射文件
WEB-INF\classes\com\ common.xml文件
公用模塊的sql語句的映射文件
WEB-INF\classes\com\ indent.xml文件
訂貨單模塊的映射文件
對于系統(tǒng)中用到的控制器,我首先對AbstractController進行了抽象,編寫了SimpleController類,在SimpleController類中我加入了各控制器中都要用到的公用屬性和公用的bean,并抽象出AbstractController的
public abstract ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception;方法
其它各模塊則繼承自SimpleController,實現(xiàn)該方法,這樣就可以使用SimpleController類中的各種屬性和方法。
程序運行的具體流程如下
首先訪問站點的入口web/index.jsp文件
<%@ include file="/WEB-INF/view/inc/head.jsp" %>
<%-- Redirected because we can't set the welcome page to a virtual URL. --%>
<c:redirect url="/loginInit.do"/>
文件中首先include了對jstl標簽庫的引用/WEB-INF/view/inc/head.jsp文件
<%@ page session="true"%>
<%@ taglib prefix="spring" uri="/WEB-INF/spring.tld"%>
<%@ taglib prefix="c"   uri="/WEB-INF/c.tld" %>
<%@ taglib prefix="fmt" uri="/WEB-INF/fmt.tld" %>
<c:redirect url="/loginInit.do"/>標簽是重定向標簽,該標簽發(fā)出請求動作/loginInit.do到web容器,web容器依據web.xml中定義的請求映射動作
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
將該動作交由main所定義的系統(tǒng)管理模塊的引擎進行調度
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/main-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
該引擎接收到請求動作后,將該動作分發(fā)至系統(tǒng)管理邏輯處理單元就是/WEB-INF/main-config.xml文件
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/loginInit.do">loginController</prop>
<prop key="/loginSubmit.do">loginController</prop>
</props>
</property>
</bean>
main-config.xml文件通過urlMapping中定義的請求動作與控制器的映射
<prop key="/loginInit.do">loginController</prop>
將動作交由loginController所定義的控制器處理
<bean id="loginController" class="com.manage.LoginController">
<property name="bean"><ref bean="bean"/></property>
<property name="sqlMap"><ref bean="sqlMap"/></property>
<property name="formView"><value>login</value></property>
<property name="successView"><value>main</value></property>
<property name="mainField">
<list>
<value>usercode</value>
<value>password</value>
</list>
</property>
</bean>
該控制器引用了applicationContext.xml文件中加載的bean和sqlMap實例
<property name="bean"><ref bean="bean"/></property>
<property name="sqlMap"><ref bean="sqlMap"/></property>
以及對控制器處理請求后返回的視圖屬性的定義
<property name="formView"><value>login</value></property>
<property name="successView"><value>main</value></property>
com.manage.LoginController控制器主要實現(xiàn)了
public ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception 方法,該方法主要是對請求動作進行處理并返回一個ModelAndView對象,ModelAndView類包含了邏輯單元返回的結果數據集和表現(xiàn)層信息
public ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
log.info(request.getMethod());
Map model = new HashMap();
Map userForm =null;
Map userInfo = null;
if(isGet(request)){
userForm =  new HashMap();
userForm.put("usercode","A1118");
userForm.put("password","123");
model.put("userForm",userForm);
return new ModelAndView(formView,model);
}
else{
userForm = (Map)bean.fillMap(mainField, request);
try{
sqlMap.startTransaction();
userInfo = (Map)sqlMap.queryForObject("user.selectUser", userForm.get("usercode"));
sqlMap.commitTransaction();
}
finally{
sqlMap.endTransaction();
}
if(userInfo == null){
model.put("message", "沒有找到該用戶");
model.put("userForm", userForm);
returnView = formView;
}
else{
model.put("message", "登錄成功");
model.put("userInfo", userInfo);
returnView = successView;
printMap(userInfo);
request.getSession().setAttribute("userInfo", userInfo);
}
return new ModelAndView(returnView, model);
}
}
這里我是用一個控制器對登錄的初始化動作和登錄提交動作進行控制,通過
if(isGet(request))來區(qū)分,初始化動作中將用戶信息封裝在model中并通過
return new ModelAndView(formView,model);
formView是請求動作返回的視圖,在配置文件中已經定義了
<property name="formView"><value>login</value></property>
model是返回的結果數據集
將返回的視圖和數據集交由urlMapping,urlMapping會根據applicationContext.xml中定義的
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
<property name="prefix"><value>/WEB-INF/view/</value></property>
<property name="suffix"><value>.jsp</value></property>
</bean>
viewResolver在返回的視圖的字符串加上前綴/WEB-INF/view/和后綴.jsp,即
/WEB-INF/view/login.jsp,
然后通過main的調度引擎返回到login頁面
<%@ page contentType="text/html; charset=GBK" %>
<%@ include file="/WEB-INF/view/inc/head.jsp" %>
<html>
<head>
<title>
login
</title>
<%@ include file="/WEB-INF/view/inc/css-js.inc" %>
</head>
<body bgcolor="#ffffff">
<spring:message code="title"/>
<spring:message code="fff"/>
<form action="/loginSubmit.do" method="POST">
<table width="100%" height="100%">
<tr>
<td  align="center" valign="middle">
<c:if test="${message!=null}">
<h4><c:out value="${message}" /></h4><br>
</c:if>
用戶編號:<input type="text" name="usercode" value="<c:out value="${userForm.usercode}"/>"/>
<br/>
用戶密碼:<input type="text" name="password" value="<c:out value="${userForm.password}"/>"/>
<br/> <input type="submit" value="ok"/>
</td>
</tr>
</table>
</form>
</body>
</html>
Login頁面上使用了jstl的標簽進行輸出。這樣一個登錄初始化的過程就完成,
登錄提交的原理和登錄初始化的運行原理一樣,
在登錄提交過程中我也是使用的com.manage.LoginController控制器,在提交過程中我通過
userForm = (Map)bean.fillMap(mainField, request);方式將頁面提交過來的表單數據封裝在
userForm中的(訂貨單模塊中都是用bean.fillMap和bean.fillMaps來封裝請求參數的),,這里的mainField是一個字符串數組,由LoginController的父類SimpleController中定義,bean也是在SimpleController定義的
mainField的作用是設置表單提交過來的字段,通過在配置文件中定義,這樣可以避免硬編碼,
<property name="mainField">
<list>
<value>usercode</value>
<value>password</value>
</list>
</property>
Bean的作用是將請求的表單中的數據以key和value 形式封裝在Map中
在提交過程中我使用了ibatis中的核心組件sqlMap,也是在配置文件中定義的
<property name="sqlMap"><ref bean="sqlMap"/></property>
SqlMap的調用方法如下
try{
sqlMap.startTransaction();開啟事務
userInfo = (Map)sqlMap.queryForObject("user.selectUser", userForm.get("usercode"));
sqlMap.commitTransaction();提交事務
}
finally{
sqlMap.endTransaction();結束事務
}
(Map)sqlMap.queryForObject("user.selectUser", userForm.get("usercode"));方法用于查詢用戶的信息,”
user.selectUser”是對應于user.xml映射文件中的selectUser對sql語句的映射,userForm.get("usercode")是輸入的參數
<select id="selectUser" parameterClass="java.lang.String" resultClass="java.util.HashMap">
<![CDATA[
select * from v_BsUserRole where userCode = #userCode#
]]>
</select>
Id就是調用sql的引用名,
parameterClass是輸入的參數
resultClass是返回的結果集封裝的類
sqlMap.queryForObject會根據輸入的sql的引用名來完成查詢和數據封裝工作,
如果找到記錄,則封裝在resultClass定義的對象中返回,沒有找到則返回null
執(zhí)行完畢后,LoginController會返回main頁面或login頁面。
整個程序中運行的流程大致相同,下面將對ibatis的使用進行說明
示例中我使用了以下幾種查詢和數據庫的操作
l         查詢訂貨單記錄
查詢單條記錄在訂貨單修改時用到,類為
com.indent.IndentModController
訂貨單是主從表關系,因此需要配置主表查詢語句和從表查詢語句
sql的映射文件為indent.xml文件
<select id="getIndent" parameterClass="java.lang.String" resultClass="java.util.HashMap">
<![CDATA[
select sellID, sellIDShow, dealerCode, dealerName, orderCode, orderName, orderDate,
sumSellNum, sumFeeSell, source, sourceExplain, status, statusExplain,remark
from V_OS_Sell where sellID = #sellID#
]]>
</select>
<select id="getIndentList" parameterClass="java.lang.String" resultClass="java.util.HashMap">
<![CDATA[
select partCode, partName, unit, priceSell, numStorage, orderNum, orderSum
from V_OS_SellList where sellID = #sellID#
]]>
</select>
Id:程序中對sql的引用名
parameterClass:輸入參數,
resultClass:封裝每條記錄的類
對于查詢一條記錄時ibatis直接返回resultClass中定義的封裝數據的對象
對于查詢多條記錄,ibatis會將每條記錄封裝在resultClass定義的對象實例中然后將所有這所對象封裝在List中返回
Map indent = null;
List indentList = null;
try{
sqlMap.startTransaction();
indent=(Map)sqlMap.queryForObject("indent.getIndent",sellID);訂貨單主表記錄
indentList = sqlMap.queryForList("indent.getIndentList",sellID);訂貨單從表記錄
sqlMap.commitTransaction();
}
finally{
sqlMap.endTransaction();
}
l         動態(tài)條件查詢
動態(tài)條件查詢是指通過查詢頁面提交的動態(tài)條件來組合不同的sql語句
我們以前是通過
String sql =”select * from table where bh=’dd’”
If(request. getParameter(“par”)!=null&& request. getParameter(“par”). length()>0){
sql += “ and field = ‘”+ request. getParameter(“par”)+”’”;
}
…….
這種方式來組合的
考慮到這個問題,ibatis引入了動態(tài)映射機制
在訂貨單查詢就用到了這種動態(tài)條件查詢,對應的類是com.indent.IndentQueryController
首先我通過
indentForm = (Map)bean.fillMap(mainField, request);方法將查詢條件封裝在Map中
然后將這個查詢條件的對象交給sqlMap查詢
partCount = ((Integer) sqlMap.queryForObject("indent.getIndentQueryCount", indentForm)).intValue();獲得了查詢的記錄數
indentList=sqlMap.queryForList("indent.getIndentQuery", indentForm, skipResult, PAGE_SIZE);獲得了分頁的記錄集
sql映射是
<select id="getIndentQueryCount" parameterClass="java.util.Map" resultClass="java.lang.Integer">
<![CDATA[
select count(sellID) from os_sell
where (depotCode = #depotCode#) and (oldSellID is null) and (status='1')
]]>
<dynamic prepend="AND">
<isNotEmpty prepend="AND" property="sellID">
<![CDATA[(sellID like '%'+#sellID#+'%')]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="dealerName">
<![CDATA[(dealerName like '%'+#dealerName#+'%')]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="orderCode">
<![CDATA[(orderCode = #orderCode#)]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="orderDate1">
<![CDATA[(orderDate >= #orderDate1#)]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="orderDate2">
<![CDATA[(orderDate <= #orderDate2#)]]>
</isNotEmpty>
</dynamic>
</select>
<select id="getIndentQuery" parameterClass="java.util.Map" resultClass="java.util.HashMap">
<![CDATA[
select sellID, sellIDShow, dealerName, sumSellNum, sumFeeSell,
orderName, orderDate, sourceExplain from V_OS_Sell
where (depotCode = #depotCode#) and (oldSellID is null) and (status='1')
]]>
<dynamic prepend="AND">
<isNotEmpty prepend="AND" property="sellID">
<![CDATA[(sellID like '%'+#sellID#+'%')]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="dealerName">
<![CDATA[(dealerName like '%'+#dealerName#+'%')]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="orderCode">
<![CDATA[(orderCode = #orderCode#)]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="orderDate1">
<![CDATA[(orderDate >= #orderDate1#)]]>
</isNotEmpty>
<isNotEmpty prepend="AND" property="orderDate2">
<![CDATA[(orderDate <= #orderDate2#)]]>
</isNotEmpty>
</dynamic>
<![CDATA[
order by orderDate desc, sellID desc
]]>
</select>
對于動態(tài)映射的配置,大家可以看<ibatis開發(fā)指南>的31-34頁里面講得很清楚
l         操作語句
操作語句包括訂貨單的插,改,刪
這里只說一下訂貨單的插入過程,類是com.indent.IndentAddSaveController
首先IndentAddSaveController在獲得提交保存的請求后,將訂貨單主表信息封裝在map,從表信息封裝在list中
Map indent = (Map)bean.fillMap(mainField,request);
List indentList = bean.fillMaps(childField,request);
然后通過事務管理,插入訂貨單主表信息,循環(huán)插入訂貨單子表信息
try{
sqlMap.startTransaction();
sqlMap.insert("indent.insertIndent",indent);
for (int i = 0; i < indentList.size(); i++) {
indentPart = (Map)indentList.get(i) ;
indentPart.put("sellID",sellID);
sqlMap.insert("indent.insertIndentList",indentPart);
}
sqlMap.commitTransaction();
}
finally{
sqlMap.endTransaction();
}
對應的sql配置是
<insert id="insertIndent" parameterClass="java.util.Map">
<![CDATA[
insert into OS_Sell
(sellID,dealerCode,dealerName,depotCode,orderCode,orderDate,
sumSellNum,sumFeeSell,source,status,remark,isBack)
values(#sellID#,#dealerCode#,#dealerName#,#depotCode#,#orderCode#,#orderDate#,
#sumSellNum#,#sumFeeSell#,#source#,'1',#remark#,'2');
]]>
</insert>
<insert id="insertIndentList" parameterClass="java.util.Map">
<![CDATA[
insert into OS_SellList
(sellID, partCode, partName, unit, priceSell, orderNum)
values
(#sellID#, #partCode#, #partName#, #unit#, #priceSell#, #orderNum#)
]]>
</insert>
l         調用存儲過程
存儲過程的調用在訂貨單新建過程中用到,訂貨單新建時首先要獲得一個唯一的ID號
對應的類是com.indent. IndentAddController
首先我將存儲過程需要用到的參數封裝在map中,提交給sqlMap執(zhí)行存儲過程
Map parMap = null;
try {
sqlMap.startTransaction();
parMap = new HashMap();
parMap.put("type","X");
parMap.put("depot","A1118");
parMap.put("code",null);
sqlMap.update("common.getCode",parMap);
sqlMap.commitTransaction();
}
finally {
sqlMap.endTransaction();
}
String sellID=(String)parMap.get("code");
SqlMap會根據common.getCode所定的parameterMap
<parameterMap id="getCodeParameters" class="java.util.Map" >
<parameter property="type" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
<parameter property="depot" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
<parameter property="code" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT" nullValue=""/>
</parameterMap>
<procedure id="getCode" parameterMap="getCodeParameters">
<![CDATA[
{call ProcGetMaxId(?,?,?)}
]]>
</procedure>
的輸入輸出參數來定義存儲過程中的參數
這里我將code這個字段定義為OUT型,那么存儲過程執(zhí)行后會將返回的唯一的ID號存儲在code中,在程序中就通過
String sellID=(String)parMap.get("code");可以得到了。
l         注意一點
sqlMap的執(zhí)行默認情況下是自動提交的,在沒有用
try {
sqlMap.startTransaction();
………..
sqlMap.commitTransaction();
finally {
sqlMap.endTransaction();
}
進行事務管理時
每執(zhí)行一個更新,查詢,等數據訪問方法時都會打開,和關閉一次連接,
因此,在一個動作中多次調用sqlMap的數據訪問方法時都應該用事務來管理,不管是查詢,還是更新。
《spring開發(fā)指南》中需要重點看的章節(jié)
l         Spring Bean封裝機制 19-28頁 要會配置Bean
l         Spring 高級特性 29-64頁 要明白其中的登錄例子的流程
《ibatis開發(fā)指南》中需要重點看的章節(jié)
l         ibatis配置 11-16頁
l         SqlMapClient基本操作示例 16-17頁 例1-例6
l         OR 映射 19-25頁
l         動態(tài)映射 31-34頁
l         事務管理-基于JDBC的事務管理機制 35-36頁
附:
表結構
BS訂貨單主表
CREATE TABLE [dbo].[OS_Sell] (
[SellID] [nvarchar] (17) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[DealerCode] [nvarchar] (6) COLLATE Chinese_PRC_CI_AS NULL ,
[DealerName] [nvarchar] (60) COLLATE Chinese_PRC_CI_AS NULL ,
[DepotCode] [nvarchar] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[StockID] [nvarchar] (17) COLLATE Chinese_PRC_CI_AS NULL ,
[OrderCode] [nvarchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
[OrderDate] [datetime] NULL ,
[SumSellNum] [numeric](9, 1) NULL ,
[SumFeeSell] [numeric](10, 2) NULL ,
[ChangeCode] [nvarchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
[ChangeDate] [datetime] NULL ,
[AuditCode] [nvarchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
[AuditDate] [datetime] NULL ,
[OutCode] [nvarchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
[OutDate] [datetime] NULL ,
[Source] [char] (1) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Status] [char] (1) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Remark] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
[IsBack] [char] (1) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[OldSellID] [nvarchar] (17) COLLATE Chinese_PRC_CI_AS NULL ,
[BackStatus] [nvarchar] (1) COLLATE Chinese_PRC_CI_AS NULL ,
[InvoiceCode] [nvarchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
[InvoiceNO] [nvarchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[InvoiceDate] [datetime] NULL
) ON [PRIMARY]
BS訂貨單從表
CREATE TABLE [dbo].[OS_SellList] (
[SellID] [nvarchar] (17) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[PartCode] [nvarchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[PartName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Unit] [nvarchar] (4) COLLATE Chinese_PRC_CI_AS NULL ,
[PriceSell] [numeric](8, 2) NULL ,
[OrderNum] [numeric](9, 1) NULL ,
[OutNum] [numeric](9, 1) NULL ,
[BackNum] [numeric](9, 1) NULL
) ON [PRIMARY]
總部庫存表
CREATE TABLE [dbo].[O_Storage] (
[DepotCode] [nvarchar] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[PartCode] [nvarchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[PartName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Unit] [nvarchar] (4) COLLATE Chinese_PRC_CI_AS NULL ,
[ProviderCode] [nvarchar] (4) COLLATE Chinese_PRC_CI_AS NULL ,
[NumStorage] [numeric](9, 1) NULL ,
[NumFreeze] [numeric](9, 1) NULL ,
[PriceCost] [numeric](8, 2) NULL ,
[PricePact] [numeric](8, 2) NULL ,
[PriceMove] [numeric](8, 2) NULL ,
[PriceStatus] [char] (1) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[StorageCode] [nvarchar] (14) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
視圖
--BS中的用戶角色視圖
--姜敏
CREATE       view v_BsUserRole
as
select
a.dealerCode,--經銷商編號
a.areaCode,--區(qū)域編號
a.dealerName,--經銷商名稱
a.depotName,--倉庫名稱
a.kind,--等級分類
a.status as dealerStatus,--經銷商狀態(tài)
a.upDealerCode,--上級經銷商代碼
b.userCode,--用戶代碼
b.userName,--用戶姓名
LOWER(b.password) as password ,--用戶密碼
b.lindType,--聯(lián)系方式
b.status as userStatus,--用戶狀態(tài)
b.isAdmin,--是否管理員
c.roleCode,--角色編號
c.roleName--角色名稱
from
p_dealer a
inner join p_user b on a.dealercode=b.depotcode
left outer join
(select a.roleCode, a.roleName, b.userCode
from r_bsRole a inner join r_bsRoleUser b on a.RoleCode = b.RoleCode) c
on b.userCode=c.userCode
訂貨單主表視圖
CREATE  VIEW dbo.V_OS_Sell
AS
SELECT a.sellID, right(a.sellID,10) as sellIDShow, a.dealerCode, a.dealerName, f.areaCode, f.areaName, a.depotCode,
h.dealerName AS depotName, a.stockID, a.orderCode, b.userName AS orderName,
CONVERT(char(10), a.orderDate, 120) AS orderDate, cast(a.sumSellNum AS int)
AS sumSellNum, a.sumFeeSell, a.changeCode, g.userName AS changeName,
CONVERT(char(10), a.changeDate, 120) AS changeDate, a.auditCode,
c.userName AS auditName, CONVERT(char(10), a.auditDate, 120) AS auditDate,
a.outCode, d .userName AS outName, CONVERT(char(10), a.outDate, 120) AS outDate,
a.source, (CASE a.source WHEN '1' THEN '轉單' WHEN '2' THEN '自制' END)
AS sourceExplain, a.status,
(CASE a.status WHEN '1' THEN '已訂貨' WHEN '2' THEN '已轉單' WHEN '3' THEN '已審核'
WHEN '4' THEN '已出庫' WHEN '5' THEN '已發(fā)運' WHEN ' 6 ' THEN '已確認' END)
AS statusExplain, a.remark, a.isBack,
(CASE a.isBack WHEN '1' THEN '是' WHEN '2' THEN '否' END) AS isBackExplain,
a.oldSellID, a.backStatus,
(CASE a.backStatus WHEN '1' THEN '未審核' WHEN '2' THEN '已審核' WHEN '3' THEN '已退貨'
END) AS backStatusExplain
FROM OS_Sell a INNER JOIN
P_User b ON a.orderCode = b.userCode INNER JOIN
P_Dealer e ON a.dealerCode = e.dealerCode INNER JOIN
P_Dealer h ON a.depotCode = h.dealerCode LEFT OUTER JOIN
P_Area f ON e.AreaCode = f.AreaCode LEFT OUTER JOIN
P_User c ON a.auditCode = c.userCode LEFT OUTER JOIN
P_User d ON a.outCode = d .userCode LEFT OUTER JOIN
P_User g ON a.changeCode = g.userCode
訂貨單從表視圖
/*
平臺銷售單子表
姜敏
*/
CREATE           view V_OS_SellList
as
select
a.sellID, --銷售單ID
a.partCode, --零件號
a.partName, --零件名稱
a.unit, --計量單位
a.priceSell, --銷售價(合同成本價)
isnull((select top 1 pricePact from o_storage where depotCode='000001' and partCode = a.partCode),0) as factPrice,--當前的總部的銷售價
cast(isnull((select top 1 numStorage from o_storage where depotCode = '000001' and partcode = a.partcode),0) as int) as numStorage,  --當前庫存數量
cast(a.orderNum as int) as orderNum, --訂貨數量
a.priceSell*orderNum as orderSum, --訂貨金額
cast(a.outNum as int) as outNum, --出庫數量
a.priceSell*outNum as outSum, --出庫金額
cast(a.backNum as int) as backNum, --累計退票數量
a.priceSell*backNum as backSum, --累計退票金額
cast((a.orderNum+a.backNum) as int) as canBackNum, --可退數量
(a.orderNum+a.backNum)*a.priceSell as canBackSum--可退金額
from
OS_SellList a
inner join OS_Sell b on a.sellID = b.sellID
存儲過程
--取單據號的存儲過程--
CREATE    PROCEDURE ProcGetMaxId
@LX char(1),@CK nvarchar(6),@Code nvarchar(17) output
AS
Declare @i bigint,@No Varchar(11)
begin tran
Select @i=count(*) from P_MaxId where  (Code = @LX) and (DepotCode=@CK)
if @i>0
begin
set @i=0
Select @i=IDNO
FROM P_MaxId
WHERE (CONVERT(Varchar, CurrDate, 1) = CONVERT(Varchar, GETDATE(), 1))   AND
(Code = @LX) and (DepotCode=@CK)
if @i=0
begin
Set @No=Convert(Varchar,Getdate(),112)+'001'
Update P_MaxId Set CurrDate=GetDate(),IDNO=Convert(bigint,@No) where  (Code = @LX) and (DepotCode=@CK)
end
else
begin
Update P_MaxId Set CurrDate=GetDate(),IDNO=IDNO+1 where  (Code = @LX) and (DepotCode=@CK)
end
Select @No=Convert(varchar,IDNO) from P_MaxId where (Code = @LX) and (DepotCode=@CK)
end
else
begin
Set @No=Convert(Varchar,Getdate(),112)+'001'
Insert P_MaxId(Code,DepotCode,CurrDate,IDNO) Values( @LX,@CK,GetDate(),Convert(bigint,@No) )
end
commit tran
set @Code= @CK+'_'+@LX+subString(@No,3,9)
--return 1
GO
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
SqlServer 數據分頁的存儲過程--我的窩
步步為營 .NET三層架構解析 二、數據庫設計
數據庫干貨:整理SQLServer非常實用的腳本
正確設置與使用SQL Server的字符集(Collation,即排序規(guī)則)
精妙SQL語句
[java]log4j寫sql server數據庫日志的統(tǒng)一寫法
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服