SSM框架(Springmv+Spring+mybatis)

Springmv+Spring+mybatis

    • 导包
    • 创建配置文件
        • db.properties数据库配置文件
        • mybatis-cfg配置
        • application-context.xml配置
        • springmvc配置
        • web.xml配置
        • springmvc对静态资源处理
    • Springmvc转换日期格式或者字符串样式
    • 高阶参数绑定
        • 数组
        • list
    • springmvc的注解
    • 异常处理器(HandlerExceptionResolver)
    • 上传文件
    • json数据交互
    • RestFu的开发风格
    • 拦截器
        • 访问顺序
        • 拦截器的使用
        • 拦截器的执行流程
        • 实际操作
    • 分页
    • 拓展(JDBCTemplate)

导包

  1. Spring的IOC核心依赖4个包
  2. Springmvc的两个web包
  3. Spring的AOP的4个包
  4. Spring-JDBC包
  5. mysql数据库的依赖
  6. c3p0数据库连接池的2个依赖
  7. mybatis的包和Spring支持mybatis的包
  8. 前端可能会使用的jstl和jstl-api以及standard
		
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-beansartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-coreartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-expressionartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>

         
        <dependency>
            <groupId>org.aopalliancegroupId>
            <artifactId>com.springsource.org.aopallianceartifactId>
            <version>1.0.0version>
        dependency>
        
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.2version>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aopartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aspectsartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-txartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>6.0.6version>
        dependency>

        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>

        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.4.6version>
        dependency>
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>1.3.2version>
        dependency>

        
        <dependency>
            <groupId>com.mchangegroupId>
            <artifactId>c3p0artifactId>
            <version>0.9.5.2version>
        dependency>
        
        <dependency>
            <groupId>com.mchangegroupId>
            <artifactId>mchange-commons-javaartifactId>
            <version>0.2.11version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.1.5.RELEASEversion>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.16.20version>
        dependency>

        
        <dependency>
            <groupId>javax.servlet.jsp.jstlgroupId>
            <artifactId>jstlartifactId>
            <version>1.2version>
        dependency>
        
        <dependency>
            <groupId>javax.servlet.jsp.jstlgroupId>
            <artifactId>jstl-apiartifactId>
            <version>1.2version>
        dependency>
        
        <dependency>
            <groupId>taglibsgroupId>
            <artifactId>standardartifactId>
            <version>1.1.2version>
        dependency>

创建配置文件

db.properties数据库配置文件

  1. 数据库驱动
  2. 数据库访问url
  3. 数据库用户名
  4. 数据库密码
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test8?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=cqrjxk39

注意:

在xml中写数据库访问url时,“&”会变成"&",这可能是由xml的编码规则决定的,在xml文件中有以下几类字符要进行转义替换:
< < 小于号
> > 大于号
& &
' 单引号
" " 双引号

mybatis-cfg配置

  1. 打印sql语句
  2. 实例类别名配置


<configuration>
    
    <settings>
        
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    settings>
    <typeAliases>
        
        <package name="com.spring.pojo">package>
    typeAliases>
configuration>

application-context.xml配置

  1. 配置组件扫描,完成bean管理
  2. 加载配置文件db.properties
  3. 配置c3p0数据库连接池
  4. 配置mybatis
  5. 配置事务管理器
  6. 开启事务注解


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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-4.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    		 http://www.springframework.org/schema/aop
     		http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
           ">
    <context:component-scan base-package="com.spring">context:component-scan>

    <context:property-placeholder location="classpath:db.properties">context:property-placeholder>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}">property>
        <property name="jdbcUrl" value="${jdbc.url}">property>
        <property name="user" value="${jdbc.username}">property>
        <property name="password" value="${jdbc.password}">property>
    bean>

    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource">property>
        <property name="mapperLocations" value="classpath:com/spring/dao/*.xml">property>
        <property name="configLocation" value="classpath:mybatis-cfg.xml">property>
    bean>
    
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.spring.dao">property>
        <property name="sqlSessionFactoryBeanName" value="sessionFactory">property>
    bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource">property>
    bean>

    <tx:annotation-driven transaction-manager="transactionManager">tx:annotation-driven>

beans>

注意: 使用eclipse编译器编写此段代码很容易会出现Cannot find the declaration of element 'beans’这个错误,在这种情况下可以使用本地对象,如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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
           classpath:/org/springframework/beans/factory/xml/spring-beans.xsd
           http://www.springframework.org/schema/context
           classpath:/org/springframework/context/config/spring-context.xsd
            http://www.springframework.org/schema/tx
            classpath:/org/springframework/transaction/config/spring-tx.xsd
    		 http://www.springframework.org/schema/aop
     		classpath:/org/springframework/aop/config/spring-aop.xsd">

使用classpath:+路径,路径去本地导入的jar包中去找

springmvc配置

  1. 配置注解驱动
  2. 视图解析器


<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"
       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 ">
    
    
    <mvc:annotation-driven>mvc:annotation-driven>
    
    <context:component-scan base-package="com.spring.controller">context:component-scan>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="prefix" value="/WEB-INF/jsp/">property>
        
        <property name="suffix" value=".jsp">property>
    bean>
beans>

web.xml配置

  1. 配置Spring的监听器(用来读取配置文件application-context.xml)
  2. 配置前端控制器
  3. 配置POST提交编码格式(防止乱码)
	<listener>
        
    	<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
	listener>
    <context-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:application-context.xmlparam-value>
    context-param>
    
    
    <servlet>
        <servlet-name>springmvcservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:springmvc.xmlparam-value>
        init-param>
    servlet>
    
    <servlet-mapping>
        <servlet-name>springmvcservlet-name>
        <url-pattern>*.actionurl-pattern>
    servlet-mapping>
	
	<filter>
        <filter-name>encodingfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>encodingfilter-name>
        <url-pattern>*.actionurl-pattern>
    filter-mapping>

springmvc对静态资源处理

当web.xml的拦截为“/”或者“/*”拦截所有的时候,前端的CSS和js等页面同样会被拦截,所以我们需要在springmvc.xml配置中对静态资源做一定的处理

<mvc:resources location="/CSS/" mapping="/CSS/**">mvc:resources>
<mvc:resources location="/js/" mapping="/js/**">mvc:resources>

Springmvc转换日期格式或者字符串样式

在Springmvc中配置转换工厂,转换器主要由springmvc的适配器来完成
springmvc配置文件配置

	
    <mvc:annotation-driven conversion-service="ConversionServiceFactoryBean">mvc:annotation-driven>

    
    <bean id="ConversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        
        <property name="converters">
            <list>
                
                <bean class="com.spring.converter.DateConverter">bean>
            list>
        property>
    bean>

自定义转换器,实现Converter接口

import org.springframework.core.convert.converter.Converter;
//String为需要转换的目标的类型,Timestamp是被转换的目标类型
public class DateConverter implements Converter<String, Timestamp> {
    @Override
    public Timestamp convert(String s) {
        try {
            if( s != null){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy:MM-dd HH_mm-ss");
                Timestamp parse = (Timestamp) simpleDateFormat.parse(s);
                return parse;
            }
        }catch (Exception e){

        }
        return null;
    }
}

高阶参数绑定

数组

数组大多应用于多选删除的场合
例如:
前端

<form action="${pageContext.request.contextPath}/deletes.action" method="post">
	商品列表:
	<table width="100%" border=1>
		<tr>
			<td>商品名称td>
			<td>商品价格td>
			<td>生产日期td>
			<td>商品描述td>
			<td>操作td>
		tr>
		<c:forEach items="${itemList }" var="item">
			<tr>
				<td><input type="checkbox" name="ids" value="${item.id}">td>
				<td>${item.name }td>
				<td>${item.price }td>
				<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>td>
				<td>${item.detail }td>
				
				<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改a>td>
			
			tr>
		c:forEach>
	
	table>
	<input type="submit" value="删除">
form>

后端:

	//produces参数是为了防止后端传递给前端数据中有中文时会出现乱码
	@RequestMapping(value = "/deletes.action",method = RequestMethod.POST,produces="text/html;charset=UTF-8")
    public String deletes(Integer[] ids){
        for (Integer id:ids){
            itemService.delete(id);
        }
        return "redirect:/itemList.action";
    }

list

list集合一般用于批量修改
例如:
1. 后端实体类中必须要有list集合,且泛型为该实体类
2. 前端代码:

<form action="${pageContext.request.contextPath}/updates.action" method="post">
商品列表:
<table width="100%" border=1>
	<tr>
		<td>商品名称td>
		<td>商品价格td>
		<td>生产日期td>
		<td>商品描述td>
		<td>操作td>
	tr>
	<c:forEach items="${itemList }" var="item" varStatus="s">
		<tr>
			<td><input type="hidden" name="items[${s.index}].id" value="${item.id}">td>
			<td><input type="text" name="items[${s.index}].name" value="${item.name }">td>
			<td><input type="text" name="items[${s.index}].price" value="${item.price }">td>
			<td><input type="text" name="items[${s.index}].detail" value="${item.detail }">td>
			<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改a>td>
		tr>
	c:forEach>
table>
<input type="submit" value="修改">
form>
  1. 后端
	@RequestMapping(value = "/updates.action",method = RequestMethod.POST,produces="text/html;charset=UTF-8")
    public String updates(Item item){
        List<Item> items = item.getItems();
        for (int i= 0; i < items.size(); i++){
            itemService.update(items.get(i));
        }
        return "redirect:/itemList.action";
    }

springmvc的注解

@RequestMapping:表示方法返回的是页面或者是重定向,可以放在方法上,也可以放在类上

  • value:访问路径,是数组,可以实现多请求,多个url可以使用大括号括起来,值之间以“,”隔开
  • method:提交方式,常用的两个值为RequestMethod.POST和RequestMethod.GET,默认值为get,也是数组,支持多种提交方式也是用大括号括起来,值之间以“,”隔开
  • produces:后端传递前端的参数格式,防止参数中含有中文会出现乱码问题

@ResponseBody:一般与@RequestMapping配套使用,返回json数据
@RestController:放在类上,相当于@ResponseBody+@Controller,表示该类下所有的方法都返回的是json数据
@CrossOrigin(origins = “*”, maxAge = 3600):Spring4.2及以上版本支持,放在类上,用于解决跨域问题。4.2以下版本可以使用拦截器来解决跨域问题,文章下面讲述拦截器时有提到

异常处理器(HandlerExceptionResolver)

springmvc在处理请求过程中会负责捕获dao,service,controller层的异常信息,并交由自定义异常处理器处理,异常分为预期异常(自己可以预测到的)和运行时异常(未知的)

  1. 创建预期异常类,并继承Exception类

    @Data
    public class MessageException extends Exception {
    
        private String msg;
    
        public MessageException(String msg){
            this.msg = msg;
        }
    }
    
  2. 在dao,service,controller你能预测到可能会发生此异常的地方抛出此异常

    		if(items == null){
                throw new MessageException("商品信息不能为空");
            }
    
  3. 创建自定义异常类,并实现org.springframework.web.servlet.HandlerExceptionResolver接口,并使用注解将其纳入spring的bean管理

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class ExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        //判断异常类型
        if(e instanceof MessageException){
            //预期异常
            MessageException messageException = (MessageException)e;
            modelAndView.addObject("error",(messageException.getMsg()));
        }else{
            //运行时异常
            modelAndView.addObject("error","未知异常");
            System.out.println(o);
            System.out.println(e);
        }
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

上传文件

  • 在D创建文件夹upload(名字随便取)

  • 配置tomcat
    SSM框架(Springmv+Spring+mybatis)_第1张图片

  • 添加文件上传依赖

    		
            <dependency>
                <groupId>commons-fileuploadgroupId>
                <artifactId>commons-fileuploadartifactId>
                <version>1.3.1version>
            dependency>
            
            <dependency>
                <groupId>commons-iogroupId>
                <artifactId>commons-ioartifactId>
                <version>2.4version>
            dependency>
    
  • 前端

    • 不管你是上传图片还是上传文件,form表单的属性里面必须要有enctype=“multipart/form-data”
    • 设置回显时,必须要先判断,否则图片可能没有,显示不出来
<form id="itemForm"	action="${pageContext.request.contextPath }/updateitem.action" method="post" enctype="multipart/form-data">
		<input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
		<table width="100%" border=1>
			<tr>
				<td>商品名称td>
				<td><input type="text" name="name" value="${item.name }" />td>
			tr>
			<tr>
				<td>商品价格td>
				<td><input type="text" name="price" value="${item.price }" />td>
			tr>

			<tr>
				<td>商品生产日期td>
				<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" />td>
			tr>
			<tr>
				<td>商品图片td>
				<td>
					<c:if test="${item.pid !=null}">
						
						<img src="/pid/${item.pid}" width=100 height=100/>
						<br/>
					c:if>
					<input type="file"  name="pictureFile"/>
				td>
			tr>
			<tr>
				<td>商品简介td>
				<td><textarea rows="3" cols="30" name="detail">${item.detail }textarea>
				td>
			tr>
			<tr>
				<td colspan="2" align="center"><input type="submit" value="提交" />
				td>
			tr>
		table>

	form>
  • 后端
    • 设置图片的名字
    • 获取文件后缀名
    • 保存到磁盘
    • 保存到数据库(只需保存图片名即可,因为前端有配置完整的路径)
	@RequestMapping(value = "/updateitem.action",method = RequestMethod.GET,produces="text/html;charset=UTF-8")
    public String updateitem(Item item, MultipartFile pictureFile) throws IOException {
        //        设置图片名字,防止名字重复
        String s = UUID.randomUUID().toString().replaceAll("-", "");
        //获取文件扩展名
        String extension = FilenameUtils.getExtension(pictureFile.getOriginalFilename());
        //        保存图片到D盘
        pictureFile.transferTo(new File("D:\\upload\\"+s+"."+extension));
        //保存到数据库
        item.setPid(s+"."+extension);

        itemService.update(item);
        return "redirect:/itemEdit.action?id="+item.getId();
    }

json数据交互

  • 导入解析json数据的三个包

    		
            <dependency>
                <groupId>com.fasterxml.jackson.coregroupId>
                <artifactId>jackson-databindartifactId>
                <version>2.9.8version>
            dependency>
            
            <dependency>
                <groupId>com.fasterxml.jackson.coregroupId>
                <artifactId>jackson-coreartifactId>
                <version>2.9.8version>
            dependency>
            
            <dependency>
                <groupId>com.fasterxml.jackson.coregroupId>
                <artifactId>jackson-annotationsartifactId>
                <version>2.9.8version>
            dependency>
    
  • 导入jquery

  • 前端ajax编写

    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    	<title>修改商品信息title>
    	<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.4.4.min.js">script>
    	<script type="text/javascript">
    		$(function () {
    			// alert(1);
    			var params = '{"id":10,"name":"测试商品","price":99.9,"detail":"测试商品描述","pid":"123456.jpg"}';
    			$.ajax({
    				url:"${pageContext.request.contextPath}/json.action",
    				data:params,
    				contentType:"application/json;charset=UTF-8",//发送的数据格式
    				type:"post",
    				dataType:"json",//回调的数据也是json数据
    				success:function (data) {
    					alert(data.name);
    				}
    			})
    		})
    	script>
    head>
    
  • 创建一个类封装json数据

  • 接收json数据,并返回json数据到前端

    	@ResponseBody
        @RequestMapping(value = "/json.action",method = RequestMethod.POST,produces="text/html;charset=UTF-8")
        public Item json(@RequestBody Item item){
            System.out.println("json来了");
            System.out.println(item);
            return item;
        }
    

RestFu的开发风格

如果前端的请求url的方式如下所示,请求参数直接放在url中,并没有使用?+键值对的形式,那么后端的代码为
前端:

<td><a href="${pageContext.request.contextPath }/itemEdit/${item.id}.action">修改a>td>

后端:

	@RequestMapping(value = "/itemEdit/{id}.action",method = RequestMethod.GET,produces="text/html;charset=UTF-8")
    public String toEditItem(@PathVariable int id,Model model){
        Item item = new Item();
        item.setId(id);
        List<Item> items = itemService.find(item);
        if(items.size() != 0){
            model.addAttribute("item",items.get(0));
        }
        return "editItem";
    }

拦截器

访问顺序

用户访问——>拦截器方法前——>执行controller层方法——>拦截器方法后——>拦截器页面渲染——>用户

拦截器的使用

  • 创建拦截器类,并实现org.springframework.web.servlet.HandlerInterceptor接口,可以创建多个

    import org.springframework.lang.Nullable;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Interceptor1 implements HandlerInterceptor {
        //方法前,true表示放行,false表示拦截
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        	//Spring4.2以下版本解决跨域问题
           String originHeader = request.getHeader("Origin");
           response.setHeader("Access-Control-Allow-Origin", originHeader);
           response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
           response.setHeader("Access-Control-Max-Age", "0");  
           response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");  
           response.setHeader("Access-Control-Allow-Credentials", "true");  
           response.setHeader("XDomainRequestAllowed","1");   
           response.setHeader("XDomainRequestAllowed","1");
            return true;
        }
    
        //方法后
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    
        }
    
        //页面渲染
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    
        }
    }
    
  • 在springmvc配置文件中配置拦截器

    <mvc:interceptors>
            
            <mvc:interceptor>
                
                <mvc:mapping path="/**"/>
                <bean class="com.spring.interceptor.Interceptor1">bean>
            mvc:interceptor>
            <mvc:interceptor>
                
                <mvc:mapping path="/**"/>
                <bean class="com.spring.interceptor.Interceptor2">bean>
            mvc:interceptor>
        mvc:interceptors>
    

拦截器的执行流程

  • 方法前preHandle按照拦截器定义的顺序调用
  • 方法后postHandle按照拦截器定义的逆序调用,并且只有当方法前preHandle全部返回true才会调用
  • 页面渲染afterCompletion按照拦截器定义的逆序调用,只要其所在的拦截器的方法前preHandle返回true就会调用

实际操作

前端登录页面:

<form action="${pageContext.request.contextPath}/login.action" method="post">
    <input type="text" name="username"><br />
    <input type="submit" value="登录">
form>

后端:

  1. 前往登录页面

  2. 登录后保存用户名到session,并跳转到其他页面

     	//前往登录页面
        @RequestMapping(value = "/login.action",method = RequestMethod.GET,produces="text/html;charset=UTF-8")
        public String tologin(){
            return "login";
        }
        
        //登录后保存跳转
        @RequestMapping(value = "/login.action",method = RequestMethod.POST,produces="text/html;charset=UTF-8")
        public String login(String username, HttpSession session){
            //将用户名保存到session
            session.setAttribute("username",username);
            return "redirect:/itemList.action";
        }
    

拦截器方法1:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        if(!requestURI.equals("/Demo32/login.action")){
            //表示如果不是访问登录页面的请求,那么就要判断他有没有登录
            String username = (String) request.getSession().getAttribute("username");
            if(username == null){
                //表示如果没有登录,将其拦截并打回登录页面
                response.sendRedirect(request.getContextPath()+"/login.action");
                return false;
            }
        }
        //以上条件都符合后会返回true,放行
        return true;
    }

分页

分页两个比较重要的类,其中一个是PageHelper,另外一个是PageInfo

  1. 导入分页包

    		
            <dependency>
                <groupId>com.github.miemiedevgroupId>
                <artifactId>mybatis-paginatorartifactId>
                <version>1.2.15version>
            dependency>
            
            <dependency>
                <groupId>com.github.pagehelpergroupId>
                <artifactId>pagehelperartifactId>
                <version>5.1.2version>
            dependency>
    
  2. 配置application-context.xml配置文件

    	<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource">property>
            <property name="mapperLocations" value="classpath*:com/hospital/dao/*.xml">property>
            <property name="configLocation" value="classpath:mybatis-cfg.xml">property>
            <property name="plugins">
                <array>
                    <bean class="com.github.pagehelper.PageInterceptor">
                        <property name="properties">
                            <value>
                                
                                helperDialect=mysql
                                reasonable=true
                            value>
                        property>
                    bean>
                array>
            property>
        bean>
    
  3. dao层service层编写(略)

  4. 分析PageInfo类的属性

    	//当前页
    	private int pageNum;
    	//每页显示的记录数
        private int pageSize;
        //当前页面的记录数
        private int size;
        //起始页
        private int startRow;
        //尾页
        private int endRow;
        //总记录数
        private long total;
        //总页数
        private int pages;
        //结果集
        private List<T> list;
        //前一页
        private int prePage;
        //下一页
        private int nextPage;
        //是否为第一页
        private boolean isFirstPage;
        //是否为最后一页
        private boolean isLastPage;
        //是否有前一页
        private boolean hasPreviousPage;
        //是否有下一页
        private boolean hasNextPage;
        //导航页码数
        private int navigatePages;
        //所有导航页号
        private int[] navigatepageNums;
        //导航起始页
        private int navigateFirstPage;
        //导航最后一页
        private int navigateLastPage;
    
  5. 前端(参考)

    <table>
       <thead>
        <tr>
            <th>医生编号th>
            <th>医生姓名th>
            <th>入院时间th>
            <th>所属科室th>
            <th>操作th>
        tr>
        thead>
        	
    	     <c:forEach items="${doctorList.list }" var="d" varStatus="status">
    			<tr>
    				<td style="vertical-align: middle;"><input type="checkbox"
    					name="check" value="1">td>
    				<td>${d.id }td>
    				<td>${d.name }td>
    				<td><fmt:formatDate value="${d.time }" pattern="yyyy年MM月dd日"/>  td>
    				<td>${d.seccoXuan.seccoName }td>
    				<td><a href="doctor/toEditPage?id=${d.id }&pageNum=${doctorList.pageNum}">更改a>   
    				<a href="doctor/detail?id=${d.id }&pageNum=${doctorList.pageNum}"	>详情a>td>
    			tr>
    		c:forEach>
      table>
      
     <table>
    		<tr>
    			<th colspan="5">
    				<div class="inline pull-right page">
    					共${doctorList.total }条记录 ${doctorList.pageNum }/${doctorList.pages } 页
    					<c:if test="${doctorList.isFirstPage }">
    						<a href="javascript:void()" aria-label="Previous"> <span
    							aria-hidden="true">«span>
    						a>
    					c:if>
    					
    					<c:if test="${!doctorList.isFirstPage }">
    						<a href='${pageContext.request.contextPath}/doctor/forward.action?pageNum=${doctorList.pageNum - 1 }'>«a>
    					c:if>
    					<c:forEach items="${doctorList.navigatepageNums }" var="n">
    						
    						<c:if test="${n==doctorList.pageNum }">
    							<a class="product-ym_bg" href="${pageContext.request.contextPath}/doctor/forward.action?pageNum=${n }">${n }a>
    						c:if>
    						
    						<c:if test="${n!=doctorList.pageNum}">
    							<a class="product-ym_bg" href="${pageContext.request.contextPath}/doctor/forward.action?pageNum=${n }">${n }a>
    						c:if>
    					c:forEach>
    					
    					<c:if test="${doctorList.isLastPage }">
    
    						<a href="javascript:void()" aria-label="Next"> <span
    							aria-hidden="true">»span>
    						a>
    
    					c:if>
    					
    					<c:if test="${!doctorList.isLastPage }">
    
    						<a class="product-ym_xyy"
    							href="${pageContext.request.contextPath}/doctor/forward.action?pageNum=${doctorList.pageNum + 1 }"
    							aria-label="Next"> <span aria-hidden="true">»span>
    						a>
    
    					c:if>
    				div>
    
    				<div>
    					<button type="button" class="btn btn-success" onclick="addDoctor()">添加医生button>
    					   
    					<button type="button" class="btn btn-success" id="delPro"
    						onClick="delAll();">删除选中button>
    				div>
    			th>
    		tr>
    	table>
    
  6. 后端

    @RequestMapping(value = "/forward.action",method = RequestMethod.GET,produces="text/html;charset=UTF-8")
        public String forward(Model model, @RequestParam(defaultValue = "1")int pageNum,@RequestParam(defaultValue = "2")int pageSize){
            PageHelper.startPage(pageNum,pageSize);//该语句后面紧挨着的查询语句就会分页
            List<Doctor> doctors = doctorService.find();
            PageInfo<Doctor> doctorList = new PageInfo<Doctor>(doctors);
            model.addAttribute("doctorList",doctorList);
            return "/doctor/index";
        }
    

拓展(JDBCTemplate)

在一些公司还会使用Spring自带的JDBCTemplate代替mybatis,这里我引用一篇较好的博客来理解JDBCTemplate的用法
JDBCTemplate的用法

你可能感兴趣的:(框架)