一、数据库环境用mysql,数据库建表语句如下:
/* SQLyog v10.2 MySQL - 5.1.72-community : Database - mybatis ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*Table structure for table `items` */ DROP DATABASE IF EXISTS `mybatis`; CREATE DATABASE `mybatis` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `mybatis`; SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS `items`; CREATE TABLE `items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL COMMENT '商品名称', `price` float(10,1) NOT NULL COMMENT '商品定价', `detail` text COMMENT '商品描述', `pic` varchar(64) DEFAULT NULL COMMENT '商品图片', `createtime` datetime NOT NULL COMMENT '生产日期', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; insert into `items`(`id`,`name`,`price`,`detail`,`pic`,`createtime`) values (1,'台式机',3000.0,'该电脑质量非常好!!!!',NULL,'2015-02-03 13:22:53'),(2,'笔记本',6000.0,'笔记本性能好,质量好!!!!!',NULL,'2015-02-09 13:22:57'),(3,'背包',200.0,'名牌背包,容量大质量好!!!!',NULL,'2015-02-06 13:23:02'); /*Table structure for table `orderdetail` */ DROP TABLE IF EXISTS `orderdetail`; CREATE TABLE `orderdetail` ( `id` int(11) NOT NULL AUTO_INCREMENT, `orders_id` int(11) NOT NULL COMMENT '订单id', `items_id` int(11) NOT NULL COMMENT '商品id', `items_num` int(11) DEFAULT NULL COMMENT '商品购买数量', PRIMARY KEY (`id`), KEY `FK_orderdetail_1` (`orders_id`), KEY `FK_orderdetail_2` (`items_id`), CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; insert into `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) values (1,3,1,1),(2,3,2,3),(3,4,3,4),(4,4,2,3); /*Table structure for table `orders` */ DROP TABLE IF EXISTS `orders`; CREATE TABLE `orders` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '下单用户id', `number` varchar(32) NOT NULL COMMENT '订单号', `createtime` datetime NOT NULL COMMENT '创建订单时间', `note` varchar(100) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`), KEY `FK_orders_1` (`user_id`), CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; insert into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL),(4,1,'1000011','2015-02-03 13:22:41',NULL),(5,10,'1000012','2015-02-12 16:13:23',NULL); /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` date DEFAULT NULL COMMENT '生日', `sex` char(1) DEFAULT NULL COMMENT '性别', `address` varchar(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8; insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河南郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
建表成功之后数据库如图所示:
java的环境是jdk1.7,eclipse使用mars2,spring使用3.2的版本。spring3.2所需要的jar包如图所示:
至此,所需要的软件和环境都准备完毕。
----------------------------------------------------------------我是华丽的分割线-----------------------------
开始正式开发第一个springmvc的程序。在eclipse搭建项目如下所示:
配置前端控制器,前端控制器的本质是一个servlet,所以前端控制器的配置要在web.xml文件里面。
<!-- 配置SpringMVC前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 在这里contextConfiguration配置springmvc的配置文件 (配置处理器适配器、映射器、视图解析器等) 如果不配置contextConfiguration默认加载WEB-INF/servlet名称-servlet.xml 即springmvc-servlet.xml文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 配置url-partern有三种方式 1. *.action 保证所有以.action结尾的请求都有DispatcherServlet进行解析 2. / 所有的请求都由DispatcherServlet进行解析 但是要通过Restful风格的配置 让DispatcherServlet不解析html等静态文件 3. /* 这种配置方式不对 会报错 目前先采用第一种方式 --> <url-pattern>*.action</url-pattern> </servlet-mapping>
我们把关于springmvc的配置全部集中在springmvc.xml文件中,这样便于统一管理springmvc的东西。
配置非注解的处理器适配器:
非注解的处理器适配器本质上就是一个bean。只要在springmvc.xml中添加下面的配置语句:
<!-- 处理器适配器 这个适配器可以执行所有实现Controller接口的handler --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
通过查看这个类的源代码可以发现,这个适配器可以执行所有实现了Controller接口的类。
配置非注解的处理器映射器:
<!-- 处理器映射器 会把bean的name作为url进行查找 因此在配置Handler的时候需要指定name属性 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
配置视图解析器:
<!-- 视图解析器 解析jsp,默认使用jstl的标签和语法,因此必须要有jstl的包 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> </bean>
配置完成之后来开发第一个controller,这controller实现了Controller接口。这种非注解的方式在实际的开发过程中使用的很少,因为一个类只能处理一件事情,这样会有很多个类,不适合做大型的开发。
package com.whw.ssm.controller; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import com.whw.ssm.po.Items; /** * 编写第一个Controller * 这个Controller实现了Controller接口 * @author Emitofo * */ public class ItemsController1 implements Controller{ @Override public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { // TODO Auto-generated method stub List<Items> itemsList = new ArrayList<Items>(); //向list中填充静态数据 Items items_1 = new Items(); items_1.setName("联想笔记本"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); itemsList.add(items_1); itemsList.add(items_2); ModelAndView modelAndView = new ModelAndView(); // 这个方法底层调用的是request.setAttribute(); modelAndView.addObject("itemsList", itemsList); modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp"); return modelAndView; } }
在springmvc.xml中配置url和这个controller的映射关系。这么配置以后,只要用queryItem.action这个url来访问,就可以执行我们写的这个controller了。
<bean id="itemsController1" name="/queryItems.action" class="com.whw.ssm.controller.ItemsController1"/>
接着,我们继承HttpRequestHandler这个接口来开发一个新的Controller。
package com.whw.ssm.controller; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.Request; import org.springframework.web.HttpRequestHandler; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import com.whw.ssm.po.Items; /** * 编写第二个Controller * 这个Controller实现了HttpRequestHandler接口 * 这种方式和原生的servlet方式很相似,可以直接操作request和response对象 * 最常见的一种应用就是设置reponse的类型,然后给用户返回一个json格式的数据 * @author Emitofo * */ public class ItemsController2 implements HttpRequestHandler{ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub List<Items> itemsList = new ArrayList<Items>(); //向list中填充静态数据 Items items_1 = new Items(); items_1.setName("联想笔记本"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!这是高端系列的笔记本"); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!装逼专用的手机"); itemsList.add(items_1); itemsList.add(items_2); request.setAttribute("itemsList", itemsList); request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response); } }
同时我们再springmv.xml中引入新的非注解映射器和非注解适配器,非注解映射器和非注解适配器可以交叉使用。
第二种形式的非注解处理器映射器
<!-- 处理器映射器 会把bean的name作为url进行查找 因此在配置Handler的时候需要指定name属性 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <!--简单url映射 这也是一个映射器 多个映射器可以并存--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- 对itemsController1进行url映射,url是/queryItems1.action itemsController1是某个controller的id --> <prop key="/queryItems1.action">itemsController1</prop> <prop key="/queryItems2.action">itemsController1</prop> </props> </property> </bean>
第二种形式的非注解处理器适配器
<!-- 另一个非注解的适配器 适配器也可以配置多个 每一个适配器都实现了HandlerMapping这个接口--> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
使用queryItems1.action或者是queryItems2.action都可以访问页面。
开发使用注解形式的controller,注意,这是在实际开发过程中使用最多的方式,因为注解简单方便,易于使用,所以需要重点掌握。在使用注解的方式开发之前,必须先对springmvc.xml文件进行配置。注意,使用注解的方式进行开发,必须配置注解映射器和注解适配器,注意注解映射器只能和注解适配器搭配使用。
<!-- 注解映射器和注解适配器必须一起使用 要么都不用 要么都得用 --> <!--注解映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> <!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置 mvc:annotation-driven默认加载很多的参数绑定方法, 比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter 实际开发时使用mvc:annotation-driven --> <!-- <mvc:annotation-driven></mvc:annotation-driven> -->
使用注解的形式来开发controller。
package com.whw.ssm.controller; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.Request; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.whw.ssm.po.Items; /** * 编写第三个Controller * 使用注解的方式来实现Controller * @author Emitofo * */ @Controller public class ItemsController3 { @RequestMapping("/queryItems4.action") public ModelAndView queryItems() throws Exception { List<Items> itemsList = new ArrayList<Items>(); //向list中填充静态数据 Items items_1 = new Items(); items_1.setName("联想笔记本"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!这是高端系列的笔记本"); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!装逼专用的手机"); itemsList.add(items_1); itemsList.add(items_2); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("itemsList", itemsList); modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp"); return modelAndView; } }
对于注解形式开发的controller可以在springmvc.xml中进行单个配置,也可以使用spring的组件扫描,建议使用组件扫描,这样就直接扫描那个package下面的所有类。
在springmvc.xml中单独进行配置。
<bean class="com.whw.ssm.controller.ItemsController3"/>
或者是用spring的组件进行扫描。
<!-- 对于注解的Handler可以单个配置 实际开发中建议使用组件扫描 --> <!-- <bean class="cn.itcast.ssm.controller.ItemsController3" /> --> <!-- 可以扫描controller、service、... 这里让扫描controller,指定controller的包 --> <context:component-scan base-package="com.whw.ssm.controller"></context:component-scan>
使用queryItems4.action就能访问这个controller。
到现在为止,springmvc.xml的内容如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> <!-- 下面的是Handler --> <bean id="itemsController1" name="/queryItems.action" class="com.whw.ssm.controller.ItemsController1"/> <bean id="itemsController2" name="/queryItems3.action" class="com.whw.ssm.controller.ItemsController2"/> <!-- <bean class="com.whw.ssm.controller.ItemsController3"/> --> <!-- 处理器映射器 处理器适配器 视图解析器等其实可以不用在这个配置文件里面配置 因为 DispatcherServlet.properties里面已经配置了这三个东西的默认值 --> <!-- 处理器映射器 会把bean的name作为url进行查找 因此在配置Handler的时候需要指定name属性 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <!--简单url映射 这也是一个映射器 多个映射器可以并存--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- 对itemsController1进行url映射,url是/queryItems1.action itemsController1是某个controller的id --> <prop key="/queryItems1.action">itemsController1</prop> <prop key="/queryItems2.action">itemsController1</prop> </props> </property> </bean> <!-- 对于注解的Handler可以单个配置 实际开发中建议使用组件扫描 --> <!-- <bean class="cn.itcast.ssm.controller.ItemsController3" /> --> <!-- 可以扫描controller、service、... 这里让扫描controller,指定controller的包 --> <context:component-scan base-package="com.whw.ssm.controller"></context:component-scan> <!-- 处理器适配器 这个适配器可以执行所有实现Controller接口的handler --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> <!-- 另一个非注解的适配器 适配器也可以配置多个 每一个适配器都实现了HandlerMapping这个接口--> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/> <!-- 视图解析器 解析jsp,默认使用jstl的标签和语法,因此必须要有jstl的包 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> </bean> <!-- 注解映射器和注解适配器必须一起使用 要么都不用 要么都得用 --> <!--注解映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> <!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置 mvc:annotation-driven默认加载很多的参数绑定方法, 比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter 实际开发时使用mvc:annotation-driven --> <!-- <mvc:annotation-driven></mvc:annotation-driven> --> </beans>