SpringMVC + mybatis结合

SpringMVC设计模型替换struts测试

首先转载

第一、MVC框架的出现是为了将URL从HTTP的世界中映射到Java世界中,这是MVC框架的核心功能。而在URL这一点SpringMVC无疑更加优雅。

第二、从设计实现角度来说,我觉得SpringMVC更加清晰。即使我们去对比Struts2的原理图和SpringMVC的类图,它依然很让人困惑,远没有SpringMVC更加直观。


SpringMVC设计思路:将整个处理流程规范化,并把每一个处理步骤分派到不同的组件中进行处理。

这个方案实际上涉及到两个方面:

处理流程规范化 —— 将处理流程划分为若干个步骤(任务),并使用一条明确的逻辑主线将所有的步骤串联起来

处理流程组件化 —— 将处理流程中的每一个步骤(任务)都定义为接口,并为每个接口赋予不同的实现模式

处理流程规范化是目的,对于处理过程的步骤划分和流程定义则是手段。因而处理流程规范化的首要内容就是考虑一个通用的Servlet响应程序大致应该包含的逻辑步骤:

步骤1—— 对Http请求进行初步处理,查找与之对应的Controller处理类(方法)   ——HandlerMapping

步骤2—— 调用相应的Controller处理类(方法)完成业务逻辑                    ——HandlerAdapter

步骤3—— 对Controller处理类(方法)调用时可能发生的异常进行处理            ——HandlerExceptionResolver

步骤4—— 根据Controller处理类(方法)的调用结果,进行Http响应处理       ——ViewResolver

第三、设计原则更加明朗。

    【Open for extension /closed for modification】

这条重要的设计原则被写在了spring官方的reference中SpringMVC章节的起始段: A key design principle in SpringWeb MVC and in Spring in general is the “Open for extension, closed for modification” principle.

并且重点很好地体现在SpringMVC的实现当中,可以扩展,但却不能改变。我曾经扩展过Spring的IOC、AOP功能,这一点SpringMVC应该和Spring一脉相承。

第四、组件化的设计方案和特定的设计原则让SpringMVC形散神聚。

  •  —— SpringMVC总是沿着一条固定的逻辑主线运行
  •  —— SpringMVC却拥有多种不同的行为模式

SpringMVC是一个基于组件的开发框架,组件的不同实现体系构成了“形”;组件的逻辑串联构成了“神”。因此,“形散神不散”: SpringMVC的逻辑主线始终不变,而行为模式却可以多种多样。

第五、更加贴合Web发展的趋势,这个更加虚了,不再展开说这个 问题了。

 

第六、技术上的放缓导致了程序员对Struts2失去了热情,导致SpringMVC依靠自身的努力和Spring的口碑,逐渐显露了自身的优势和特点。

 

为什么SpringMVC会赢得最后的胜利呢?最后,我们不妨想一想Struts2是怎样流行起来的!

我自己是从Struts1用过来的,后来Struts1的问题很明显了,开源社区出现了很多的MVC框架,最为突出的是Webwork2。

Webwork2探索了一条与传统Servlet模型不同的解决方案,逐渐被大家熟识和理解,不断发展并得到了广大程序员的认可。它以优秀的设计思想和灵活的实现,吸引了大批的Web层开发人员投入它的 怀抱。

Apache社区与Opensymphony宣布未来的Struts项目将与Webwork2项目合并,并联合推出Struts2。

Struts2能够在一个相当长的时间段内占据开发市场主导地位的重要原因在于其技术上的领先优势。而这一技术上的领先优势,突出表现为对Controller的彻底改造:

public class UserController {

    private User user

    public String execute() {

        // 这里加入业务逻辑代码

       return "success";

    }

}

 

从上面的代码中,我们可以看到Webwork2 /Struts2对于Controller最大的改造有两点:

  • 在Controller中彻底杜绝引入HttpServletRequest或者HttpServletResponse这样的原生Servlet对象。
  • 将请求参数和响应数据都从响应方法中剥离到了Controller中的属性变量。

这两大改造被看作是框架的神来之笔。因为通过这一改造,整个Controller类彻底与Web容器解耦,可以方便地进行单元测试。而摆脱了Servlet束缚的Controller,也为整个编程模型赋予了全新的定义。从引入新的编程元素的角度来说,Webwork2 / Struts2无疑也是成功的。因为在传统Servlet模式中的禁地Controller中的属性变量被合理利用了起来作为请求处理过程中的数据部分。这样的改造不仅使得表达式引擎能够得到最大限度的发挥,同时使得整个Controller看起来更像是一个POJO。因而,这种表现形态被笔者冠以的名称 是:POJO实现模式。POJO实现模式是一种具有革命性意义的模式,因为它能够把解耦合这样一个观点发挥到极致。从面向对象的角度来看,POJO模式无疑也是所有程序员所追求的一个目标。这也就是Webwork2 /Struts2那么多年来经久不衰的一个重要原因。

下面是测试代码部分

applicationContext.xml配置

<span style="font-size:18px;"><!-- 扫描包内的注解 -->
	<context:component-scan base-package="com.hellojava"></context:component-scan>
	<!-- 注册驱动类 -->
	<mvc:annotation-driven/>
	<!-- 视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/view/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<!-- 配置数据源 -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/mytest3"></property>
		<property name="username" value="root"></property>
		<property name="password" value="1111"></property>
	</bean>

	<!-- 集成myBaits框架,配置sqlSessionFatory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="typeAliasesPackage" value="com.hellojava.entity"></property>
		<property name="mapperLocations" value="classpath:com/hellojava/mapper/*.xml"></property>
	</bean>
	<!-- mybatis自动扫描包下的mapper -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.hellojava.dao"></property>
		<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
	</bean></span>
web.xml配置文件
<span style="font-size:18px;"><!-- The front controller of this Spring Web application, responsible for handling all application requests -->
	<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param><!-- spring 容器 spring配置文件的路径 -->
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:applicationContext.xml</param-value>
		</init-param><!-- 修改servlet初始化时机 -->
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Map all requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern><!-- 过滤全部请求 -->
	</servlet-mapping>
	
	<filter><!-- 处理文字请求 -->
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping></span>

项目测试各个包及其文件如下 




业务层

package com.hellojava.business;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hellojava.dao.BookDao;
import com.hellojava.entity.Book;

@Service("bookService")
public class BookService {
	@Autowired
	private BookDao bookDao;
	
	public List<Book> loadAll(){
		return bookDao.loadAll();
	}
	
	public boolean save(Book book){
		int i=bookDao.save(book);
		return i>0?true:false;
	}
	
	public boolean delete(int bookId){
		int i=bookDao.delete(bookId);
		return i>0?true:false;
	}
	
	public Book loadById(int bookId){
		return bookDao.loadById(bookId);
	}
	
	public boolean update(Book book){
		int i=bookDao.update(book);
		return i>0?true:false;
	}
}


控制器
package com.hellojava.contorller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.hellojava.business.BookService;
import com.hellojava.entity.Book;

@Controller
public class BookContorller {
	@Autowired
	private BookService bookService;
	
	@RequestMapping("/loadAll")
	public String loadAll(ModelMap model){
		List<Book> books=bookService.loadAll();
		model.addAttribute("books",books);
		return "index";
	}
	
	@RequestMapping("/save.html")
	public String save(){
		return "save";
	}
	
	@RequestMapping("/saveHander")
	public String saveHander(Book book){
		boolean bool=bookService.save(book);
		return bool?"redirect:/loadAll":"error";
	}
	
	@RequestMapping("/deleteHander")
	public String deleteHander(int bookId){
		boolean bool=bookService.delete(bookId);
		return bool?"redirect:/loadAll":"error";
	}
	@ModelAttribute
	public void loadBook(@RequestParam(name="bookId",required=false) Integer bookId,ModelMap model){
		if(bookId!=null){
			Book book= bookService.loadById(bookId);
			model.addAttribute("book", book);
		}
	}
	@RequestMapping("/loadUpdate")
	public String loadById(int bookId,ModelMap model){
		Book b=bookService.loadById(bookId);
		model.addAttribute("loadUpdate", b);
		return "update";
	}
	
	@RequestMapping("/updateHander")
	public String update(@RequestParam("book")Book book){
		return "redirect:/loadAll";
	}
}

映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hellojava.dao.BookDao">
	<select id="loadAll" resultType="Book">
		select * from Book
	</select>
	<insert id="save" parameterType="Book">
		insert into book(bookName,bookAuthor,bookPrice,bookInfo)
			values(#{bookName},#{bookAuthor},#{bookPrice},#{bookInfo})
	</insert>
	<delete id="delete" parameterType="int">
		delete from book where bookId=#{bookId}
	</delete>
	<select id="loadById" parameterType="int" resultType="Book">
		select * from book where bookId=#{bookId}
	</select>
	<update id="update" parameterType="Book">
		update book set bookName=#{bookName},bookAuthor=#{bookAuthor},bookPrice=#{bookPrice},bookInfo=#{bookInfo} where bookId=#{bookId}
	</update>
</mapper>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用 JavaScript 编写的杀死幽灵游戏(附源代码) 杀死鬼魂游戏是使用 Vanilla JavaScript、CSS 和 HTML 画布开发的简单项目。这款游戏很有趣。玩家必须触摸/杀死游荡的鬼魂才能得分。您必须将鼠标悬停在鬼魂上 - 尽量得分。鬼魂在眨眼间不断从一个地方移动到另一个地方。您必须在 1 分钟内尽可能多地杀死鬼魂。 游戏制作 这个游戏项目只是用 HTML 画布、CSS 和 JavaScript 编写的。说到这个游戏的特点,用户必须触摸/杀死游荡的幽灵才能得分。游戏会根据你杀死的幽灵数量来记录你的总分。你必须将鼠标悬停在幽灵上——尽量得分。你必须在 1 分钟内尽可能多地杀死幽灵。游戏还会显示最高排名分数,如果你成功击败它,该分数会在游戏结束屏幕上更新。 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox。要玩游戏,首先,单击 index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值