MVC模式的设计思想

C# MVC模式下,主从明细实体的实现,在视图里显示整个主体对象(包括明细表内容) 首先,我们先看模型如下: public class Activity { public int ActivityId { get; set; } public string Scope { get; set; } public string Name { get; set; } public string Type ... 阅读详情
 

MVC模式的设计思想

MVC模式是一种近年来使用比较广泛的为许多IT厂家和开发者所认可的一种设计模式,它和Web应用程序并没有直接的关系(事实上,它在很多非WEB应用程序中得到了使用),它不仅使得系统层次分明、职责清晰,而且使得系统更易于维护。在MVC模式中的三个关键部件及其主要功能职责是:

The Model Component:主要负责业务域的业务目标的实现。

The View Component:主要负责对业务域的数据展现给客户端。

The Controller Component:主要负责控制系统流程和用户输入状态

在基于Java技术的Web应用程序中,Model部分的主要组件是JavaBean和EJB,View部分的主要组件是HTML和JSP程序,Controller部分的主要组件是Servlet部分。

下面列出了一些使用MVC模式的好处:

1、        它将业务逻辑与展现分离开来,避免了将业务逻辑与展现混杂在一起带来的显示的不一致性和业务逻辑代码重复地分布在用于展现的代码中。

2、        层次清晰,易于开发者对这三个部分分工与协作,易于维护者识别不同的层次实施不同的维护策略。

3、        系统具有更好的重用性,包括用户界面的重用和业务逻辑处理包的重用,特别是业务逻辑处理包,如果遵循相应的java规范,它不仅可以在web应用程序中使用,而且可以在包括桌面、分布式环境下的得到重用。

4、        系统更易于扩展和移植。

5、        系统更易于维护。

6、        采用MVC模式开发的系统更健壮。

7、        对于大型的应用程序优势更为明显。

 

谈到设计模式,可以想一下我们常用的jsp+bean和jsp+servlet+bean的模式

JSP Model1

JSP Model2

上图中,JSP Model1即JSP+JavaBean的模式,在这种模式下,处理客户端的请求和将输出展现给客户端都是由JSP页面负责的,在模式1中,整个过程没有Servlet的参与,它将主要的业务逻辑放到JavaBean中实现,而将页面展现和请求控制交给JSP处理。

不可否认jsp的开发模式简化了开发Web应用程序的复杂度,但是其缺点是显而易见的,由于jsp是在html中嵌入java代码的方式实现的,不可避免地,它也面临很多问题:如页面展现与业务逻辑混合在一起,仍然无法在开发过程中将不同的角色更清晰地区分开来;jsp页面中将会夹杂大量的java代码,维护变得困难;同时,业务逻辑的改动也将面临动一发而影响全局的窘境。

JSP Model2即JSP+Servlet+JavaBean的模式,它和模式1的最大不同是它多了Servlet层,用于控制用户的请求和将JavaBean的业务输出传递给JSP来展现,这样就将数据展现、业务控制、业务逻辑实现分离开来,这就是早期的MVC(Model-View-Control)模式。显然,这种模式相对于jsp+bean的模式来说应用程序更具扩展性和灵活性,并且更易于维护。但是这种简单的MVC模式也有缺点,第一、没有成熟的MVC框架中所带有的各种强大和实用的功能,第二、配置文件不好管理,成熟的MVC框架支持多配置文件,而servlet的配置都写在web.xml中,这会导致web.xml文件难以管理。因此有必要掌握一种成熟的MVC的开发框架。

对于现有较成熟的Model-View-Control(MVC)框架而言,其解决的主要问题有下面几部分:

1. 将Web页面中的输入元素封装为一个(请求)数据对象。

2. 根据请求的不同,调度相应的逻辑处理单元,并将(请求)数据对象作为参数传入。

3. 逻辑处理单元完成运算后,返回一个结果数据对象。

4. 将结果数据对象中的数据与预先设计的表现层相融合并展现给用户。

 

数据封装和持久性

       在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或直接用数据访问对象来执行业务操作,

UserDAO userDAO = new UserDAO();

userDAO.insertUser(user);

       或

       User user = userDAO.getUser(request.getParameter(“bh”));

    List userList = userDAO.getUserList();

数据底层的访问在UserDAO中进行,打开数据连接connection,查询得到结果集resultset将数据封装在User的实例中,关闭连接返回数值对象,或者调用statement对象进行更新操作。操作完毕后由控制器将获取的数值对象发往页面。

  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模式中的数据封装的思想,如果按照上面的例子写,你会发现要写好多的数值对象来映射数据库的表,对于查询的得到的结果集都要手动进行封装,一旦数据库的表发生了变化,那么改起来将非常的繁琐,因此在实际运用中应该采取效率更高的数据封装办法,通过Map对象代替数值对象并配合合适的数据持久层的支持就可以达到数据封装的自动化,从而提高我们的开发效率。

综上所述,选择合适的MVC框架和数据持久层作为我们项目中的开发模式是很有必要的,通过对现在流行的MVC框架和数据持久层的了解,Spring+Ibatis的开发模式是很适合的一种。

Spring的优点

Spring提供了一套成熟而全面的基础框架,站在应用开发的实际角度来说,其最大的优势在于:Spring是一个从实际项目开发经验中抽取的,可高度重用的应用框架。

Spring Framework中目前最引人注目的,也就是名为控制反转(IOC =Inverse Of Control)或者依赖注入(DI =Dependence Injection)的设计思想。

IoC,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中,实现了组件真正意义上的即插即用。这也是Spring最具价值的特性之一

但是,光一个单纯的设计模式并不能使得Spring如此成功,而Spring最成功的地方也并不仅仅在于采用了IOC/DI的设计。

首先,Spring涵盖了应用系统开发所涉及的大多数技术范畴,包括MVC、ORM以及RemoteInterface等,这些技术往往贯穿了大多数应用系统的开发过程。Spring从开发者的角度对这些技术内容进行了进一步的封装和抽象,使得应用开发更为简便。

其次,Spring并非一个强制性框架,它提供了很多独立的组件可供选择。

 

Spring的基本配置和基础对象使用方法

略

Ibatis的优点

略

Ibatis的基本配置和核心对象使用方法

略

Ibatis在Spring中的配置和运用

略

Jstl表现技术的运用

略

实例

    结合于Spring和Ibatis的实际运用我写了一个例子,例子中实现了一个简单的登录过程和一个订货单的主从表形式的增、删、改、查功能,以供大家参考。

       我使用了Spring中的AbstractController控制器作为整个程序的基本的控制器,之所以这样做是考虑到简单实用的目的,同时能够实现主从表形式的数据输入,对于事务管理直接用ibatis中提供的事务管理功能,jsp页面统一存放在WEB-INF/view/下面,这样可以防止用户直接通过地址栏来访问jsp页面,jsp页面上用到的js脚本都以js文件的形式include到页面中,对于页面上的数据都以jstl的标签来输出达到页面简洁的目的。

配置文件说明

/WEB-INF/web.xml文件

程序运行的主要配置文件,配置了各种系统变量,对spring的加载,日志的加载等等

 

/WEB-INF/applicationContext.xml文件

启动时由spring加载系统中用到的各种bean

 

/WEB-INF/main-config.xml文件

对系统管理模块中的请求/处理单元的配置

 

/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文件

订货单模块的映射文件

 

对于系统中用到的控制器,我首先对AbstractController进行了抽象,编写了SimpleController类,在SimpleController类中我加入了各控制器中都要用到的公用属性和公用的bean,并抽象出AbstractController的

public abstract ModelAndView handleRequestInternal(HttpServletRequest request,

                                            HttpServletResponse response) throws Exception;方法

其它各模块则继承自SimpleController,实现该方法,这样就可以使用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"/>标签是重定向标签,该标签发出请求动作/loginInit.do到web容器,web容器依据web.xml中定义的请求映射动作

  <servlet-mapping>

    <servlet-name>main</servlet-name>

    <url-pattern>*.do</url-pattern>

  </servlet-mapping>

将该动作交由main所定义的系统管理模块的引擎进行调度

<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>

该引擎接收到请求动作后,将该动作分发至系统管理逻辑处理单元就是/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控制器主要实现了

  public ModelAndView handleRequestInternal(HttpServletRequest request,

                                    HttpServletResponse response) throws Exception 方法,该方法主要是对请求动作进行处理并返回一个ModelAndView对象,ModelAndView类包含了逻辑单元返回的结果数据集和表现层信息

  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))来区分,初始化动作中将用户信息封装在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

执行完毕后,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         动态条件查询

动态条件查询是指通过查询页面提交的动态条件来组合不同的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引入了动态映射机制

在订货单查询就用到了这种动态条件查询,对应的类是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>

 

对于动态映射的配置,大家可以看<ibatis开发指南>的31-34页里面讲得很清楚

 

l         操作语句

操作语句包括订货单的插,改,删

这里只说一下订货单的插入过程,类是com.indent.IndentAddSaveController

首先IndentAddSaveController在获得提交保存的请求后,将订货单主表信息封装在map,从表信息封装在list中

    Map indent = (Map)bean.fillMap(mainField,request);

    List indentList = bean.fillMaps(childField,request);

然后通过事务管理,插入订货单主表信息,循环插入订货单子表信息

    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执行存储过程

       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型,那么存储过程执行后会将返回的唯一的ID号存储在code中,在程序中就通过

String sellID=(String)parMap.get("code");可以得到了。

 

l         注意一点

sqlMap的执行默认情况下是自动提交的,在没有用

try {

  sqlMap.startTransaction();

  ………..

  sqlMap.commitTransaction();

}

    finally {

      sqlMap.endTransaction();

    }

进行事务管理时

每执行一个更新,查询,等数据访问方法时都会打开,和关闭一次连接,

因此,在一个动作中多次调用sqlMap的数据访问方法时都应该用事务来管理,不管是查询,还是更新。

 

《spring开发指南》中需要重点看的章节

l         Spring Bean封装机制 19-28页 要会配置Bean

l         Spring 高级特性 29-64页 要明白其中的登录例子的流程

 

《ibatis开发指南》中需要重点看的章节

l         ibatis配置 11-16页

l         SqlMapClient基本操作示例 16-17页 例1-例6

l         OR 映射 19-25页

l         动态映射 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,--区域编号

a.dealerName,--经销商名称

a.depotName,--仓库名称

a.kind,--等级分类

a.status as dealerStatus,--经销商状态

a.upDealerCode,--上级经销商代码

b.userCode,--用户代码

b.userName,--用户姓名

LOWER(b.password) as password ,--用户密码

b.lindType,--联系方式

b.status as userStatus,--用户状态

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 '已发运' 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

 

 

 

 

Android+SQlite《学生信息管理系统》(增删改查)源代码 虽然比较简单,但是实现了 界面登陆、增删改查等功能。有对android一些基本控件的应用: 比如:1.使用listview 控件来显示SQlite 数据库中的记录,并添加其上的长按时间响应(增删改) 2.使用下拉框控件 spinner进行按条件的查询 Android+SQlite 简单的《学生信息管理系统》(实现基本增删改查) 此代码中还有与其相对应的apk文件(在SIMS/bin目录中),大家可先行放手机上看一下效果。 希望对初学者有一定的帮助。(本人自己编写) 立即下载

相关推荐

基于java swing开发的桌面程序-学生信息管理系统,实现了增删改查

基于java swing开发的桌面程序-学生信息管理系统,实现了增删改查 包括用户的登陆注册等功能 项目采用技术: javabean+swing+jdbc+mysql进行开发 采用mvc的技术结构

C#中使用MVC架构(二)

C#中使用MVC模型架构(二) 实现数据访问层DAL 定义一个基本数据接口IBaseDao,作各数据访问的总中介,也就是说业务层只通过IBaseDao的接口对象,访问数据层,具体访问哪个数据模型操作类,是通过注入IBaseDao的实现类来完成的,可根据需要生成具体数据模型操作类,实现接口定义的抽象方法,封装操作具体数据模型的SQL语句。还需要定义一个数据访问操作类,封装基础数据操作。 1.新建数据访问类,实现sql-server数据库的链接及数据CRUD操作 publicclassA...

yytrobot的博客 723

sift、surf、orb 特征提取——三维重建

参考文章:[sift、surf、orb 特征提取及最优特征点匹配] 最近刚刚入门三维重建,在SFM算法的代码中注意到了feature_type( feature extraction method)这个参数,想细致了解一下这几种特征提取算法,在这里做一下笔记。 SIFT 简介 SIFT(Scale-Invariant Feature Transform)——尺度不变特征变换,是一种计算机视觉的特征提取算法,用来侦测与描述图像中的局部特征。 实质上,它是在不同的尺度空间上查找关键点(特征点),并计算出关键点的

bb_sy_w的博客 4362

九:MVC主从表数据加载

九:MVC主从表数据加载 EF对关联表数据加载的三种方式: 延迟加载:只有在需要的时候加载数据。EF默认的加载方式。 贪婪加载:一次性组织好数据,全部加载到内存中。 显式加载:需要通过代码手动加载关联表。 延迟加载 virtual Configuration.LazyLoadingEnabled = true; ...

小半的博客 381

QT的温湿度显示系统

大家好,这里是石侃侃的博客,欢迎前来讨论这篇文章介绍的是DHT11在2440上的基于Qt5.6的应用基于单片机系统的温湿度监测系统构成框图如图2-1所示。图2-1 系统构成框图该系统采用单片机s3c2440作为了本设计的核心元件。利用LCD作为了显示器件,利用触摸屏作为用户界面输入设备,第一行显示当前实时的温度,湿度,第二行依次显示历史时刻最高的温度值,最高的湿度值。第三行是一个文本框,记录了程...

zxpcus的博客 1万+

告别点不亮!STM32F103驱动HT1621段码屏的常见坑点与调试心得

本文详细解析了STM32F103驱动HT1621段码屏的五大常见问题及解决方案,包括硬件连接、时序控制、RAM地址映射等关键难点。通过实测数据和代码示例,帮助开发者快速排查显示异常问题,提升驱动开发效率。特别针对HT1621与STM32F103的兼容性问题提供了专业调试建议。

weixin_30925435的博客 379

MVC设计思想

1.MVC思想的说明 经典MVC模式中,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。其中,View的定义比较清晰,就是用户界面。 M:model业务模型 V:view用户界面 C:control 控制层 历史说明: JSP动态页面 :html代码+java代码 写到一起 xxx.jsp 一大推 代码 不方便后期维护,页面和业务执行紧...

WRSR52的博客 3422

【七】Hadoop3.3.4基于ubuntu24的分布式集群安装

本次安装实验基于苹果m2芯片的mac系统,使用vmware fusion搭建三台ubuntu24分布式虚拟机,确保在三台机器上安装了Java jdk8,并配置了免密码登录,网络互通,防火墙关闭,授时服务器已经同步。访问apche官网源,下载3.3.4版本,我们用二进制通用版即可,因为hadoop运行在java环境,跨平台性使得无需编译arm架构版本。至此,Hadoop的安装完成,包括hdfs文件存储系统,mapreduce计算框架,yarn资源管理系统均能正常、稳定使用。

qq_31412425的博客 2161

MVC架构设计浅析

关键词:MVC;SpringMVC;分层;视图;控制器;模型 0 引言 Web应用的根本都是从数据存储和检索数据并将其显示给用户。在用户更改数据之后,系统再将更新内容存储到数据存储中。因为关键的信息流发生在数据存储和用户界面之间,所以很多Web应用将数据和用户界面这两部分绑在一起,以减少编码量并提高应用程序性能。但是,这种看起来自然而然的方法有一些大问题。一是,用户界面的更改往往比数据存储系统的更改频繁得多。二是,这种情况下耦合往往会合并其他的业务逻辑。那么如何让 Web 应用程序的用户界面功能实现模块

m0_67261762的博客 1792

VECTOR硬件VN1600系列对比:VN1610、VN1611、VN1630A、VN1640A、VN1630log、VN1670

VN16系列说不清道不明的区别和关系

AmorRun的博客 2万+

CentOS 7下kkFileView 4.4.0离线部署全攻略(含LibreOffice 7.5配置避坑指南)

本文详细介绍了在CentOS 7环境下离线部署kkFileView 4.4.0的全流程,包括LibreOffice 7.5的配置避坑指南、中文字体解决方案以及企业级运维实践。通过本指南,用户可以在内网环境中快速搭建稳定可靠的文档在线预览服务,提升办公效率。

weixin_28481133的博客 290

MVC不是一种设计模式,而是一种设计思想

MVC不是一种设计模式,而是一种设计思想.     设计模式:是一种固定的方法,不灵活,有特定的适用场景.     设计思想:是一种思想,比较灵活,由多种设计模式组合实现.  MVC设计思想:  V(view):主要功能是展示数据.(主要有数据即可,不关心数据来源.)(a想喝水,只要有水即可,不关心水的来源)  M(Model):主要功能提供数据,.(主要用来提供数据,并不关心数据让谁显

我们年轻,阳光免费 1716

Python 爬取新浪财经 7x24(1): 下载数据

前言 最近在做一个需要很多财经数据的项目。于是想到可不可以通过爬虫来解决(尝试白嫖)。 提供财经数据的网站有很多个,其中比较靠谱和更新比较及时的应该是新浪7x24 live数据。 http://finance.sina.com.cn/7x24/?tag=0 这个问题有一定的难度,因为这个网页是动态加载的。每一次只会加载部分数据,而只有拉到底部才可以加载新的数据。 于是乎,我们要做的事情是: 下载数据 保存到数据库 本篇介绍如何下载数据。 代码 闲言少叙书归正文,代码的实现如下: import reque

ZJ_11701的博客 2905

mvvm模式和mvc的区别_揭开MVC与MVVM的设计思想的面纱?

MVC和MVVM在程序员面试中是经常碰到的问题了,关于MVC和MVVM为何这般设计,请听我慢慢向你分析。-----------------------------------------------------------------------------------------------1.让我们先了解一下MVC几乎所有的App都只干这么一件事:将数据展示给用户看,并处理一些用户对界面的操作...

weixin_39674978的博客 165

AI时代的软件质量保证新方法论

3.2.1 质量保证的方法论 质量保证(Quality Assurance, QA)是一种系统化的方法,用于确保产品或服务符合预定的质量标准。在AI时代,软件质量保证的方法论需要适应不断变化的AI技术和应用场景。 3.2.1.1 质量管理体系的构建 首先,构建一个完善

AI天才研究院 1353

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

MVC和MVVM 架构模式/设计思想

MVC Model、View、Controller   1)最上面的一层,是直接面向最终用户的"视图层"(View)。它是提供给用户的操作界面,是程序的外壳。   2)最底下的一层,是核心的"数据层"(Model),也就是程序需要操作的数据或信息。   3)中间的一层,就是"控制层"(Controller),它负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作...

weixin_30512785的博客 124

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

MVC开发模式

MVC开发模式     MVC模式是"Model-View-Controller"的缩写,中文翻译为"模式-视图-控制器"。MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变Model或View,或者同时改变两者。只要Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。类似的,只要Controller改变了View

sushun_的专栏 475

【Java设计模式 面向对象设计思想】六 再谈MVC贫血模式与DDD领域驱动开发

DDD从代码上的区别很小,就是对Service层进行重新设计并将BO升级为Domain,但是从设计和思维模式上区别很大,它是一套自底向上的面向对象思维方式和开发流程,能让我们从业务建模的视角去看问题。 从可读性上来说:它可以把原来最重的service逻辑拆分并且转移一部分逻辑,可以使得代码可读性略微提高,另外,模型充血以后基于模型的业务抽象在不断的迭代之后会越来越明确,业务的细节会越来越精准,通过阅读模型的充血行为代码,能够极快的了解系统的业务,对于开发来说能说明显的提升开发效率。 ......

MaoLin Tian's Blog 1371

MVC模式基本理解

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34008784的博客 627

mvc模式和软件三层架构

MVC: 1. M:Model,模型。JavaBean dao service * 完成具体的: 数据的封装(javabean), 业务操作(service),操作数据库(Dao), 2. V:View,视图。JSP * 展示数据 3. C:Controller,控制器。Servlet * 获取用户的输入数据(request) * 调用模型–> serviece --> da...

weixin_39708283的博客 310
上一篇: SQL优化(转载)
下一篇: MVC模式解决方案
hwctl
博客等级 码龄20年 13粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值