传统SSM框架👻笔记  现在再看传统的SSM开发…真是太艹了…还是SpringBoot爽啊……
 
Spring框架 介绍 
 
Spring优势 
Spring体系结构  
 
Spring开发步骤 
一. 坐标 导入基本包
<dependencies >      	 	<dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-context</artifactId >          <version > 5.3.18</version >      </dependency >       </dependencies > 
 
二. 编写Dao和实现类对象
public  interface  UserDao  {	public  void  save () ; } public  class  UserDaoImpl  implements  UserDao  {	@Override  	public  void  save ()  { 	System.out.println("UserDao save method running...." ); 	} } 
 
三. 核心配置文件 applicationContext.xml
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation ="http://www.springframework.org/schema/beans                             http://www.springframework.org/schema/beans/spring-beans.xsd" ></beans > 
 
四. 在 Spring 配置文件中配置 UserDaoImpl
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation ="http://www.springframework.org/schema/beans                             http://www.springframework.org/schema/beans/spring-beans.xsd" >	<bean  id ="userDao"  class ="com.itheima.dao.impl.UserDaoImpl" > </bean >       </beans > 
 
五. 使用Spring的API获得Bean实例
@Test public  void  test1 () {     	ApplicationContext  applicationContext  =  new          ClassPathXmlApplicationContext ("applicationContext.xml" ); 	UserDao  userDao  =  (UserDao) applicationContext.getBean("userDao" ); 	userDao.save();      } 
 
Spring配置文件  Bean标签 
Bean标签基本配置
Scope范围配置 
当scope的取值为**singleton**时
Bean的实例化个数:**1个 ** 
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例 
Bean的生命周期:
对象创建:当应用加载,创建容器时 ,对象就被创建了 
对象运行:只要容器在,对象一直活着 
对象销毁:当应用卸载,销毁容器时,对象就被销毁了  
 
 
 
 
当scope的取值为**prototype**时
Bean的实例化个数:多个  
Bean的实例化时机:当调用getBean()方法时实例化Bean
对象创建:当使用对象时,创建新的对象实例  
对象运行:只要对象在使用中,就一直活着 
对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了  
 
 
 
 
 
 
Bean生命周期配置 init-method:指定类中的初始化方法名称 
destroy-method:指定类中销毁方法名称 
Bean实例化三种方式
    **1 无参构造方法实例化 ** 
    **2 工厂静态方法实例化 ** 
    3 工厂实例方法实例化  
无参构造方法实例化  
 
<bean  id ="userDao"  class ="com.itheima.factory.StaticFactoryBean" /> 
 
工厂静态方法实例化  
 
factory-method 寻找该id的静态方法 从返回值中获取对象 
public  class  StaticFactoryBean  {	public  static  UserDao createUserDao () { 		return  new  UserDaoImpl (); 	} } 
 
<bean  id ="userDao"  class ="com.itheima.factory.StaticFactoryBean"   factory-method ="createUserDao" />
 
工厂实例方法实例化  
 
factory-bean 寻找此id的bean对象  
factory-method 寻找到的bean对象的id 
public  class  DynamicFactoryBean  {	public  UserDao createUserDao () { 		return  new  UserDaoImpl (); 	} } 
 
<bean  id ="factoryBean"  class ="com.itheima.factory.DynamicFactoryBean" /> <bean  id ="userDao"  factory-bean ="factoryBean"  factory-method ="createUserDao" /> 
 
 
依赖注入 注入方式
Bean的依赖注入概念: 
依赖注入(Dependency Injection ):它是 Spring 框架核心 IOC 的具体实现。 
**在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。 IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。 **
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。 简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。 
Set方式: 
public  class  SetServiceImpl  implements  SetService  {     	private  SetDao setDao;          public  void  setUserDao (SetDao setDao)  { 		this .setDao = setDao; 	}      	@Override  	public  void  save ()  { 		setDao.save(); 	}      } 
 
<bean  id ="setDao"  class ="com.ganga.dao.impl.SetDaoImpl" > </bean > <bean  id ="setService"  class ="com.ganga.service.impl.SetServiceImpl" > 	<property  name ="setDao"  ref ="setDao" />  </bean > 
 
另外还可以引入p  标签
p:setDao-ref="setDao"
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xmlns:p ="http://www.springframework.org/schema/p"         xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >          <bean  id ="setDao"  class ="com.ganga.dao.impl.SetDaoImpl" > </bean >      <bean  id ="setService"  class ="com.ganga.service.impl.SetServiceImpl"  p:setDao-ref ="setDao" > </bean >       </beans > 
 
 
构造方法注入 
public  class  ConstructorServiceImpl  implements  ConstructorService  {         private  ConstructorDao constructorDao;          public  ConstructorServiceImpl () {     }          public  ConstructorServiceImpl (ConstructorDao constructorDao) {                  this .constructorDao = constructorDao;     }     @Override      public  void  method ()  {                  constructorDao.method();     } } 
 
<bean  id ="constructorDao"  class ="com.ganga.dao.impl.ConstructorDaoImpl" > </bean > <bean  id ="constructorService"  class ="com.ganga.service.impl.ConstructorServiceImpl" > 	<constructor-arg  name ="constructorDao"  ref ="constructorDao" />  </bean >      
 
 
Bean依赖注入的数据类型
上面的操作,都是注入的引用Bean,处了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。
注入数据的三种数据类型
普通数据类型 
引用数据类型 
集合数据类型  
其中引用数据类型,此处就不再赘述了,之前的操作都是对UserDao对象的引用进行注入的,下面将以set方法注入为 例,演示普通数据类型和集合数据类型的注入。
普通数据类型 
<bean  id ="x01SetDao"  class ="com.ganga.dao.impl.X01SetDaoImpl" >     <property  name ="username"  value ="尴尬酱" />      <property  name ="age"  value ="9" />  </bean > <bean  id ="x01ConstructorDao"  class ="com.ganga.dao.impl.X01ConstructorDaoImpl" >     <constructor-arg  name ="username"  value ="这就尴尬了" />      <constructor-arg  name ="age"  value ="20" />  </bean > 
 
引用数据类型 
集合数据类型  
public  class  X03DaoImpl  implements  X03Dao  {         private  List<String> stringList;     private  List<User> userList;          private  Map<String, User> stringUserMap;          private  Properties properties;          public  void  setStringList (List<String> stringList)  {         this .stringList = stringList;     }     public  void  setUserList (List<User> userList)  {         this .userList = userList;     }          public  void  setStringUserMap (Map<String, User> stringUserMap)  {         this .stringUserMap = stringUserMap;     }          public  void  setProperties (Properties properties)  {         this .properties = properties;     }     @Override      public  void  method ()  {         System.out.println("====== List ======" );         System.out.println(stringList);         for  (User user : userList) {             System.out.println(user);         }         System.out.println("\n====== Map ======" );         System.out.println(stringUserMap);         System.out.println("\n====== Properties ======" );         System.out.println(properties);         System.out.println("\nrun X03DaoImpl method..." );     } } 
 
applicationContext.xml
<bean  id ="x03Dao"  class ="com.ganga.dao.impl.X03DaoImpl" >                  <property  name ="stringList" >              <list >                  <value > 亚索哥哥</value >                  <value > 永恩弟弟</value >                  <value > 卡特妹妹</value >              </list >          </property >          <property  name ="userList" >              <list >                  <ref  bean ="user1" />                  <ref  bean ="user2" />                  <ref  bean ="user3" />                  <bean  class ="com.ganga.pojo.User" >                      <constructor-arg  name ="username"  value ="盖伦哥哥" />                      <constructor-arg  name ="age"  value ="10" />                      <constructor-arg  name ="adds"  value ="德玛西亚" />                  </bean >              </list >          </property >                   <property  name ="stringUserMap" >              <map >                  <entry  key ="u1"  value-ref ="user1" />                  <entry  key ="u2"  value-ref ="user2" />                  <entry  key ="u3"  value-ref ="user3" />              </map >          </property >                   <property  name ="properties" >              <props >                  <prop  key ="p1" > 亚索哥哥</prop >                  <prop  key ="p2" > 永恩哥哥</prop >                  <prop  key ="p3" > 卡特妹妹</prop >              </props >          </property >      </bean >           <bean  id ="user1"  class ="com.ganga.pojo.User" >          <constructor-arg  name ="username"  value ="亚索哥哥" />          <constructor-arg  name ="age"  value ="18" />          <constructor-arg  name ="adds"  value ="艾欧尼亚" />      </bean >      <bean  id ="user2"  class ="com.ganga.pojo.User" >          <constructor-arg  name ="username"  value ="永恩哥哥" />          <constructor-arg  name ="age"  value ="16" />          <constructor-arg  name ="adds"  value ="艾欧尼亚" />      </bean >      <bean  id ="user3"  class ="com.ganga.pojo.User" >          <constructor-arg  name ="username"  value ="卡特妹妹" />          <constructor-arg  name ="age"  value ="9" />          <constructor-arg  name ="adds"  value ="诺克萨斯" />      </bean >  
 
引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他 配置文件中,而在Spring主配置文件通过import标签进行加载
<import  resource ="applicationContext-xxx.xml" /> 
 
 
Spring相关API ApplicationContext的继承体系 applicationContext:  接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象
 
ApplicationContext的实现类 
ClassPathXmlApplicationContext 
    它是从类的根路径下加载配置文件 推荐使用这种
 
FileSystemXmlApplicationContext 
    它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
 
AnnotationConfigApplicationContext 
    当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
 
 
 
getBean()方法使用 常用的有两个
通过bean的 字符id来找 getBean("userDao")
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
 
 
通过类的calss自动匹配  getBean(UserDao.class)
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时, 则此方法会报错。
 
 
 
Spring配置数据源 数据源(连接池)的作用 
数据源(连接池)是提高程序性能如出现的 
事先实例化数据源,初始化部分连接资源 
使用连接资源时从数据源中获取 
使用完毕后将连接资源归还给数据源 
 
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid  等
数据源的开发步骤 
导入数据源的坐标和数据库驱动坐标 
创建数据源对象 
设置数据源的基本连接数据 
使用数据源获取连接资源和归还连接资源 
 
Spring配置数据源 
可以将DataSource的创建权交由Spring容器去完成
    DataSource有无参构造方法,而Spring默认就是通过无参构造方法实例化对象的
    DataSource要想使用需要通过set方法设置数据库连接信息,而Spring可以通过set方法进行字符串注入
抽取jdbc配置文件 
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:context ="http://www.springframework.org/schema/context"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation =                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" >              <context:property-placeholder  location ="classpath:jdbc.properties" />      <bean  id ="c3p0DataSource"  class ="com.mchange.v2.c3p0.ComboPooledDataSource" >          <property  name ="driverClass"  value ="${jdbc.driverClass}" />          <property  name ="jdbcUrl"  value ="${jdbc.url}" />          <property  name ="user"  value ="${jdbc.user}" />          <property  name ="password"  value ="${jdbc.password}" />      </bean >       </beans > 
 
jdbc.driverClass =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql:///webcase?useSSL=false&useServerPrepStmts=true jdbc.user =root jdbc.password =ganga 
 
重点: Spring容器加载properties文件 
<context:property-placeholder  location ="xx.properties" />   <property  name =""  value ="${key}" /> 
 
 
Spring注解开发 Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置 文件可以简化配置,提高开发效率。
Spring原始注解 Spring原始注解主要是替代的配置 
**注意: ** 
        使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean 需要进行扫描以便识别使用注解配置的类、字段和方法。
<context:component-scan  base-package ="com.ganga" > </context:component-scan > 
 
使用@Component或@Service标识UserServiceImpl需要Spring进行实例化
使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入
使用@Value进行字符串的注入  一般配合el表达式来体现解耦合
@Service("annoFirstService") public  class  AnnoFirstServiceImpl  implements  AnnoFirstService  {                        @Resource(name = "annoFirstDao")           private  AnnoFirstDao annoFirstDao;          @Value("${jdbc.driverClass}")      private  String driver;               @Override      public  void  method ()  {         System.out.println("-------------------------------" );         System.out.println("driver: "  + driver);         System.out.println("-------------------------------" );         annoFirstDao.method();     } } 
 
使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法
@PostConstruct public  void  init () {	System.out.println("初始化方法...." ); } @PreDestroy public  void  destroy () {	System.out.println("销毁方法....." ); } 
 
Spring新注解     使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下: 
非自定义的Bean的配置: <bean> 
加载properties文件的配置: <context:property-placeholder> 
组件扫描的配置: <context:component-scan> 
引入其他文件: <import> 
 
引入Spring新注解 
要想使用注解开发 首先有一个核心配置类 
SpringApplicationContext.java
package  com.ganga.config;import  org.springframework.context.annotation.ComponentScan;import  org.springframework.context.annotation.Configuration;import  org.springframework.context.annotation.Import;@Configuration @ComponentScan("com.ganga") @Import({SpringDataSourceApplicationContext.class}) public  class  SpringApplicationContext  {} 
 
解决 非自定义的Bean的配置 创建DataSource对象
SpringDataSourceApplicationContext.java
package  com.ganga.config;import  com.mchange.v2.c3p0.ComboPooledDataSource;import  org.springframework.beans.factory.annotation.Value;import  org.springframework.context.annotation.Bean;import  org.springframework.context.annotation.PropertySource;import  javax.sql.DataSource;@PropertySource("classpath:jdbc.properties") public  class  SpringDataSourceApplicationContext  {              @Value("${jdbc.driverClass}")      private  String driver;     @Value("${jdbc.url}")      private  String url;     @Value("${jdbc.user}")      private  String user;     @Value("${jdbc.password}")      private  String password;          @Bean("dataSourceNew")      public  DataSource getDataSource ()  throws  Exception {         ComboPooledDataSource  dataSource  =  new  ComboPooledDataSource ();         dataSource.setDriverClass(driver);         dataSource.setJdbcUrl(url);         dataSource.setUser(user);         dataSource.setPassword(password);         return  dataSource;     } } 
 
 
Spring整合Junit 原始Junit测试Spring的问题 在测试类中,每个测试方法都有以下两行代码:
ApplicationContext  ac  =  new  ClassPathXmlApplicationContext ("bean.xml" );IAccountService  as  =  ac.getBean("accountService" ,IAccountService.class);
 
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
上述问题解决思路 
1. 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
1. 将需要进行测试Bean直接在测试类中进行注入
 
Spring集成Junit步骤 
导入spring集成Junit的坐标  
使用@Runwith注解替换原来的运行期  
使用@ContextConfiguration指定配置文件或配置类  
使用@Autowired注入需要测试的对象  
创建测试方法进行测试  
 
① 导入spring集成Junit的坐标 
<dependency > 	<groupId > org.springframework</groupId >  	<artifactId > spring-test</artifactId >  	<version > 5.3.18</version >  </dependency > <dependency > 	<groupId > junit</groupId >  	<artifactId > junit</artifactId >  	<version > 4.13.1</version >  	 </dependency > 
 
② 使用@Runwith注解替换原来的运行期 
③ 使用@ContextConfiguration指定配置文件或配置类 
④ 使用@Autowired注入需要测试的对象 
⑤ 创建测试方法进行测试 
SpringJunitRunTest.java
package  com.ganga.test;import  com.ganga.config.SpringApplicationContext;import  com.ganga.service.UserService;import  org.junit.Test;import  org.junit.runner.RunWith;import  org.springframework.beans.factory.annotation.Autowired;import  org.springframework.beans.factory.annotation.Qualifier;import  org.springframework.test.context.ContextConfiguration;import  org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import  javax.sql.DataSource;import  java.sql.Connection;import  java.sql.SQLException;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {SpringApplicationContext.class} ) public  class  SpringJunitRunTest  {         @Autowired      private  UserService userService;          @Test      public  void  userServiceTest () {         userService.SelectAll();     }     @Autowired           private  DataSource dataSource;     @Test      public  void  dataSourceTest ()  throws  SQLException {         Connection  connection  =  dataSource.getConnection();         System.out.println(connection);         connection.close();     } } 
 
 
Spring集成Web环境 ApplicationContext应用上下文获取问题
ApplicationContext应用上下文获取方式 
Spring提供了获取应用上下文的工具 
Spring集成Web环境步骤 
导入Spring集成Web的坐标
<dependency > 	<groupId > org.springframework</groupId >  	<artifactId > spring-web</artifactId >  	<version > 5.3.18</version >  </dependency > 
 
在web.xml中配置ContextLoaderListener监听器
<context-param >     <param-name > contextConfigLocation</param-name >      <param-value > classpath:applicationContext.xml</param-value >  </context-param > <listener >          <listener-class > org.springframework.web.context.ContextLoaderListener</listener-class >  </listener > 
 
使用Spirng-web 提供的工具获取Spring核心容器
ApplicationContext  app  =  WebApplicationContextUtils.getWebApplicationContext(servletContext);
 
 
 
SpringMVC框架 SpringMVC概述 SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架 ,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。
SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解 ,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时 它还支持 RESTful 编程风格的请求 。
SpringMVC快速入门 需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。
开发步骤:
导入SpringMVC相关坐标  
配置SpringMVC核心控制器DispathcerServlet  
创建Controller类和视图页面  
使用注解配置Controller类中业务方法的映射地址  
配置SpringMVC核心文件 spring-mvc.xml  
客户端发起请求测试  
 
① 导入Spring和SpringMVC的坐标 
① 导入Servlet和Jsp的坐标 
<dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-webmvc</artifactId >      <version > 5.3.18</version >  </dependency > <dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-context</artifactId >      <version > 5.3.18</version >  </dependency > <dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-web</artifactId >      <version > 5.3.18</version >  </dependency > <dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-test</artifactId >      <version > 5.3.18</version >  </dependency > <dependency > 	<groupId > javax.servlet</groupId >  	<artifactId > javax.servlet-api</artifactId >  	<version > 4.0.1</version >  	<scope > provided</scope >  </dependency > <dependency > 	<groupId > javax.servlet.jsp</groupId >  	<artifactId > javax.servlet.jsp-api</artifactId >  	<version > 2.3.3</version >  </dependency > <dependency >     <groupId > javax.servlet.jsp</groupId >  	<artifactId > jsp-api</artifactId >  	<version > 2.2</version >  	<scope > provided</scope >  </dependency > 
 
② 在web.xml配置SpringMVC的核心控制器 
<servlet >     <servlet-name > DispatcherServlet</servlet-name >      <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class >           <init-param >          <param-name > contextConfigLocation</param-name >          <param-value > classpath:spring-mvc.xml</param-value >      </init-param >           <load-on-startup > 1</load-on-startup >  </servlet > <servlet-mapping >     <servlet-name > DispatcherServlet</servlet-name >      <url-pattern > /</url-pattern >  </servlet-mapping > 
 
③ 创建Controller和业务方法 
③ 创建视图页面index.jsp 
④ 配置注解 
package  com.ganga.controller;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;@Controller public  class  UserController  {         @RequestMapping("/method")      public  String method () {         System.out.println("UserController method run ..." );         return  "index.jsp" ;     } } 
 
⑤ 创建spring-mvc.xml 
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:context ="http://www.springframework.org/schema/context"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation =                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd                " >              <context:component-scan  base-package ="com.ganga.controller" />           </beans > 
 
⑥ 访问测试地址 
SpringMVC流程视图 
SpringMVC的执行流程 
① 用户发送请求至**前端控制器DispatcherServlet。 **
② DispatcherServlet收到请求调用HandlerMapping处理器映射器。
③ 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果 有则生成)一并返回给DispatcherServlet。
④ DispatcherServlet调用HandlerAdapter处理器适配器。
⑤ HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
⑥ Controller执行完成返回ModelAndView。
⑦ HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
⑧ DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
⑨ ViewReslover解析后返回具体View。
⑩ DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。
SpringMVC 组件解析 
前端控制器:DispatcherServlet 
    用户请求到达前端控制器,它就相当于 MVC 模式中的 C ,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。 
 
处理器映射器:HandlerMapping 
    HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
 
处理器适配器:HandlerAdapter 
    通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理 器进行执行。
 
处理器:Handler处理器:Handler 
    它就是我们开发中要编写的具体业务控制器 。由 DispatcherServlet 把用户请求转发到 Handler。由 Handler 对具体的用户请求进行处理。
 
视图解析器:ViewResolver 
    View Resolver 负责将处理结果生成 View 视图,ViewResolver 首先根据逻辑视图名解析成物理视图名,即 具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
 
视图:View 
    SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp 。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程 序员根据业务需求开发具体的页面
 
 
 
SpringMVC注解解析 @RequestMapping 
另外:RequestMapping标签里面设置属性: produces = “text/html;charset=UTF-8”
    设置文件格式 和 字符集编码
    相当于 response.setContentType(“text/html;charset=utf-8”);
 
@Controller @RequestMapping("/web/x1") public  class  UserControllerDame02  {         @RequestMapping("/dame02")      public  String method () {         System.out.println("run UserControllerDame02 dame02 ..." );         return  "/jsp/dame02.jsp" ;              } } 
 
 
package  com.ganga.controller.X1_RequestMapping注解;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestMethod;@Controller() @RequestMapping("web/x1") public  class  UserControllerDame03  {                   @RequestMapping(value = "/dame03-1",method = RequestMethod.GET)      public  String dame01 ()  {         System.out.println("run UserControllerDame03 dame03 ..." );         return  "/jsp/dame03.jsp" ;     }          @RequestMapping(value = "/dame03-2",method = RequestMethod.POST)      public  String dame02 ()  {         System.out.println("run UserControllerDame03 dame031 ..." );         return  "/jsp/dame03.jsp" ;     } } 
 
 
package  com.ganga.controller.X1_RequestMapping注解;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestMethod;@Controller @RequestMapping("/web/x1") public  class  UserControllerDame04  {         @RequestMapping(value = "/dame04-1",params = {"username","id"},method = RequestMethod.GET)      public  String method1 () {         System.out.println("run UserControllerDame04-1 dame04-1 ..." );         return  "/jsp/dame04-1.jsp" ;     }               @RequestMapping(value = "/dame04-2",params = {"user!100"},method = RequestMethod.GET)      public  String method2 () {         System.out.println("run UserControllerDame04-2 dame04-2 ..." );         return  "/jsp/dame04-2.jsp" ;     } } 
 
 
 组件扫描 
配置处理器适配器
<bean  class ="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" > 	<property  name ="messageConverters" >  		<list >  			<bean  class ="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />  			</list >  	</property >  </bean > <mvc:annotation-driven /> 
 
视图解析器 
<bean  id ="viewResolver"  class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > 	 	<property  name ="prefix"  value ="/jsp/" />  	 	<property  name ="suffix"  value =".jsp" />  </bean > 
 
SpringMVC的数据响应 SpringMVC的数据响应方式
页面跳转
forward: 转发
redirect: 重定向
直接返回字符串 
package  com.ganga.controller.X3_SpringMVC数据响应.A页面跳转;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;@Controller @RequestMapping("/web/x3") public  class  ReturnStringSkip  {    @RequestMapping("/dame05-1")      public  String method01 () {         System.out.println("run dame05 method01" );         return  "dame05" ;     }                    @RequestMapping("/dame05-2")      public  String method02 () {         System.out.println("run dame05 method02" );         return  "redirect:http://localhost:8080/B5_SpringMVC_war/jsp/dame05.jsp" ;     }           } 
 
通过ModerAndView 
package  com.ganga.controller.X3_SpringMVC数据响应.A页面跳转;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.servlet.ModelAndView;@Controller @RequestMapping("/web/x3") public  class  ReturnModelAndViewSkip  {    @RequestMapping("/dame06-1")      public  ModelAndView method01 () {                  ModelAndView  modelAndView  =  new  ModelAndView ();                  modelAndView.addObject("modelKey" ,"123" );                  modelAndView.setViewName("dame06" );                  return  modelAndView;     }               @RequestMapping("/dame06-2")      public  ModelAndView method02 (ModelAndView modelAndView) {                           modelAndView.addObject("modelKey" ,"321" );                  modelAndView.setViewName("dame06" );                  return  modelAndView;     } } 
 
上面两个进行拆分 
package  com.ganga.controller.X3_SpringMVC数据响应.A页面跳转;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;@Controller @RequestMapping("/web/x3") public  class  ReturnZStringModelSkip  {    @RequestMapping("/dame06-m")      public  String method (Model model) {                  model.addAttribute("modelKey" ,"model..." );                  return  "dame06" ;     } } 
 
回写数据
Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为响应体返回的话,只需要使用 response.getWriter().print(“hello world”) 即可,那么在Controller中想直接回写字符串该怎样呢?
① 通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数 据,此时不需要视图跳转,业务方法返回值为void。
@RequestMapping("/quick4") public  void  quickMethod4 (HttpServletResponse response)  throws  IOException {	response.getWriter().print("hello world" ); } 
 
② 将    的字符串直接返回,但此时需要通过**@ResponseBody**注解告知SpringMVC框架,方法 返回的字符串不是跳转是直接在http响应体中返回。
@RequestMapping("/quick5") @ResponseBody public  String quickMethod5 ()  throws  IOException {return  "hello springMVC!!!" ;} 
 
直接返回字符串 
在异步项目中,客户端与服务器端往往要进行json格式字符串交互,此时我们可以手动拼接json字符串返回。
上述方式手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串, 我们可以使用web阶段学习过的json转换工具jackson进行转换,导入jackson坐标。
<dependency > 	<groupId > com.fasterxml.jackson.core</groupId >  	<artifactId > jackson-core</artifactId >  	<version > 2.9.0</version >   </dependency > <dependency >     <groupId > com.fasterxml.jackson.core</groupId >      <artifactId > jackson-databind</artifactId >      <version > 2.9.0</version >  </dependency > <dependency >     <groupId > com.fasterxml.jackson.core</groupId >      <artifactId > jackson-annotations</artifactId >      <version > 2.9.0</version >  </dependency > 
 
代码演示
package  com.ganga.controller.X3_SpringMVC数据响应.B回写数据;import  com.alibaba.fastjson.JSON;import  com.ganga.pojo.User;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;import  javax.servlet.http.HttpServletResponse;import  java.io.IOException;@Controller @RequestMapping("/web/x3") public  class  WriterBackAttribute  {              @RequestMapping("/dame08-1")      public  void  me01 (HttpServletResponse response)  throws  IOException {         response.getWriter().print("response! me01" );     }                    @RequestMapping("/dame08-2")      @ResponseBody      public  String me02 () {                  return  "response! me02" ;     }          @RequestMapping("/dame08-3")      @ResponseBody      public  String me03 () {                  return  "{\"username\":\"ganga\",\"age\":18}" ;     }          @RequestMapping("/dame08-4")      @ResponseBody      public  String me04 () {                  User  user  =  new  User ("gangajiang" , 9 );                  String  json  =  JSON.toJSONString(user);         return  json;     }                @RequestMapping("/dame08-5")      @ResponseBody      public  User me05 () {         System.out.println("run dame08-5 me05..." );                  User  user  =  new  User ("obg" , 99 );         return  user;     } } 
 
返回对象或集合 
通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数, 指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行配置
在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多, 因此,我们可以使用mvc的注解驱动代替上述配置。
<bean  class ="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" >     <property  name ="messageConverters" >          <list >              <bean  class ="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />          </list >      </property >  </bean > <mvc:annotation-driven /> 
 
代码演示
package  com.ganga.controller.X3_SpringMVC数据响应.B回写数据;import  com.ganga.pojo.User;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;import  java.util.ArrayList;import  java.util.List;@Controller @RequestMapping("/web/x3") public  class  WriterBackAttributeObjAndList  {         @RequestMapping("/dame09-1")      @ResponseBody      public  User me01 ()  {                  User  user  =  new  User ("obg-me01" , 99 );         return  user;     }          @RequestMapping("/dame09-2")      @ResponseBody      public  List<User> me02 ()  {                  List<User> users = new  ArrayList <User>();         users.add(new  User ("lisa" , 17 ));         users.add(new  User ("zs" , 99 ));         users.add(new  User ("ls" , 66 ));         return  users;     } } 
 
SpringMVC获取请求数据 获取的数据类型 
基本数据类型 
 
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。
package  com.ganga.controller.X4_SpringMVC获取请求数据.A普通数据类型;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("/web/x4") public  class  UserRequestParameterController01  {    @RequestMapping("/user01")      @ResponseBody      public  String user01 (String username, int  age)  {         System.out.println(username + " : "  + age);         String  write  =  "<h1 align=\"center\">getParameter: username="  + username +                 "  &  age="  + age + "</h1>" ;         return  write;     }      } 
 
获取POJO类型参数 
 
Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。
package  com.ganga.controller.X4_SpringMVC获取请求数据.BPOJO数据类型;import  com.ganga.pojo.User;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("/web/x4") public  class  UserRequestParameterController02  {    @RequestMapping("/user02")      @ResponseBody      public  String user02 (User user) {         System.out.println(user);         String  write  =  "<h1 align=\"center\">getParameter: "  +user.toString() + "</h1>" ;         return  write;     }      } 
 
获取数组数据类型 
 
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。
package  com.ganga.controller.X4_SpringMVC获取请求数据.C数组数据类型;import  com.ganga.pojo.User;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;import  java.util.Arrays;import  java.util.List;@Controller @RequestMapping("/web/x4") public  class  UserRequestParameterController03  {    @RequestMapping("/user03")      @ResponseBody      public  String user03 (String[] pramName) {         List<String> strings = Arrays.asList(pramName);         System.out.println(strings);         return  strings.toString();     }           } 
 
4.获取集合数据类型
package  com.ganga.controller.X4_SpringMVC获取请求数据.D集合数据类型;import  com.ganga.pojo.VO;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("/web/x4") public  class  UserRequestParameterController04  {    @RequestMapping("/user04")      @ResponseBody      public  String user04 (VO vo) {         System.out.println(vo.toString());         return  vo.toString();     } } 
 
解决请求乱码问题 当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤。
<filter > 	<filter-name > CharacterEncodingFilter</filter-name >  	<filter-class > org.springframework.web.filter.CharacterEncodingFilter</filter-class >  	<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 > 
 
资源拦截问题 解决方案
参数绑定注解 @requestParam 
代码演示:
package  com.ganga.controller.X4_SpringMVC获取请求数据.F注解RequestParam;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestParam;import  org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("/web/x4") public  class  TestRequestParamAnnotation  {    @RequestMapping("/param00")      @ResponseBody      public  String param00 (String username) {                           System.out.println(username);         if  (username == null ){             return  "null" ;         }         return  username;     }                    @RequestMapping("/param01")      @ResponseBody      public  String param01 (@RequestParam("name")  String username) {                           System.out.println(username);         return  username;     }     @RequestMapping("/param02-1")      @ResponseBody      public  String param02_1 (@RequestParam(value = "name",required = true)  String username) {                           System.out.println(username);         return  username;     }     @RequestMapping("/param02-2")      @ResponseBody      public  String param02_2 (@RequestParam(value = "name",required = false)  String username) {                           System.out.println(username);         return  username;     }     @RequestMapping("/param03")      @ResponseBody      public  String param03 (@RequestParam(value = "name",defaultValue = "default")  String username) {                           System.out.println(username);         return  username;     } } 
 
 
获取restful参数风格 
代码演示: 
package  com.ganga.controller.X4_SpringMVC获取请求数据.G获取Restful风格参数;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.PathVariable;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestMethod;import  org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("/web/x4") public  class  TestPathVariable  {    @RequestMapping("/restful/{user}")      @ResponseBody      public  String pathVariable (@PathVariable(value = "user",required = false)  String username) {                  System.out.println(username);         return  username;     }          @RequestMapping(value = "/userAdd/{user}",method = RequestMethod.POST)      @ResponseBody      public  String pathVariablePost (@PathVariable("user")  String username) {         System.out.println(username);         return  username;     } } 
 
 
自定义转换器 
SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。 
但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自 定义转换器。 
 
开发步骤: 
**① 定义转换器类实现Converter接口 ** 
② 在配置文件中声明转换器 
③ 在中引用转换器 
**① 定义转换器类实现Converter接口 ** 
package  com.ganga.converter;import  org.springframework.core.convert.converter.Converter;import  java.text.ParseException;import  java.text.SimpleDateFormat;import  java.util.Date;public  class  DataConverter  implements  Converter <String, Date> {    @Override      public  Date convert (String source)  {         SimpleDateFormat  simple  =  new  SimpleDateFormat ("yyyy-MM-dd:HH-mm-ss" );         Date  date  =  null ;         try  {             date = simple.parse(source);         } catch  (ParseException e) {             e.printStackTrace();         }         return  date;     } } 
 
② 在配置文件中声明转换器 
spring-mvc.xml
<bean  id ="conversionService"  class ="org.springframework.context.support.ConversionServiceFactoryBean" >     <property  name ="converters" >          <list >                           <bean  class ="com.ganga.converter.DataConverter" > </bean >         </list >      </property >  </bean > <mvc:annotation-driven  conversion-service ="conversionService" /> 
 
③ 在中引用转换器 
package  com.ganga.controller.X4_SpringMVC获取请求数据.H自定义转换器;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestParam;import  org.springframework.web.bind.annotation.ResponseBody;import  java.util.Date;@Controller @RequestMapping("/web/x4/") public  class  ConverterConversionServiceFactionBean  {    @RequestMapping("/converter")      @ResponseBody      public  String converterTest (@RequestParam("date")  Date date) {                  System.out.println(date);         String  dateStr  =  date.toString();         return  dateStr;     } } 
 
 
获取Servlet相关API SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:
方法参数类型是Servlet相关API SpringMVC回自动注入 
- **HttpServletResponse**
 
HttpServletResponse  
HttpSession  
 
@Controller @RequestMapping("/web/x4") public  class  SpringMvcGetServletAPI  {         @RequestMapping("/getAPI")      @ResponseBody      public  String getServletAPI (HttpServletRequest request, HttpServletResponse response, HttpSession session)  {         return  request + "<br>"  + response + "<br>"  + session;     } } 
 
 
获得请求头  
@RequestHeader 
    使用@RequestHeader可以获得请求头信息,
    相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
value:  请求头的名称
 
required:  是否必须携带此请求头
 
 
 
@CookieValue 
    使用@CookieValue可以获得指定Cookie的值
@CookieValue注解的属性如下:
value:  指定cookie的名称
 
required:  是否必须携带此cookie
 
 
 
package  com.ganga.controller.X4_SpringMVC获取请求数据.J获取请求头;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.CookieValue;import  org.springframework.web.bind.annotation.RequestHeader;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("/web/x4") public  class  SpringMvcGetHeader  {         @RequestMapping("/getHeader")      @ResponseBody      public  String getHeader (@RequestHeader("User-Agent")  String user_agent) {                  System.out.println(user_agent);         return  user_agent;     }          @RequestMapping("/getCookie")      @ResponseBody      public  String getCookie (@CookieValue("JSESSIONID")  String JSESSIONID) {                  System.out.println(JSESSIONID);         return  JSESSIONID;     } } 
 
 
文件上传 文件上传三要素 
文件上传原理 
当form表单修改为多部分表单时,request.getParameter()将失效。
 
enctype=“application/x-www-form-urlencoded”时,form表单的正文内容格式是:
**key=value&key=value&key=value **  
 
 
当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:
 
 
 
**文件上传步骤 ** 
**① 导入fileupload和io坐标 ** 
 
**② 配置文件上传解析器 ** 
 
③ 编写文件上传代码 
 
 
**① 导入fileupload和io坐标 ** 
pom.xml
<dependency >     <groupId > commons-io</groupId >      <artifactId > commons-io</artifactId >      <version > 2.6</version >  </dependency > <dependency >     <groupId > commons-fileupload</groupId >      <artifactId > commons-fileupload</artifactId >      <version > 1.4</version >  </dependency > 
 
**② 配置文件上传解析器 ** 
spring-mvc.xml
<bean  id ="multipartResolver"  class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" >          <property  name ="maxUploadSize"  value ="40960000" />           <property  name ="maxUploadSizePerFile"  value ="20480000" />           <property  name ="defaultEncoding"  value ="utf-8" />  </bean > 
 
③ 编写文件上传代码 
java代码
package  com.ganga.controller.X4_SpringMVC获取请求数据.K文件上传;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.ResponseBody;import  org.springframework.web.multipart.MultipartFile;import  java.io.File;import  java.io.IOException;@Controller @RequestMapping("/web/x4") public  class  SendFile  {         @RequestMapping("/upload01")      @ResponseBody      public  String upload01 (String filename, MultipartFile upload) {                  System.out.println(filename);                  String  originalFilename  =  upload.getOriginalFilename();         try  {                          upload.transferTo(new  File ("D:\\MySSM\\A2_Spring_MVC\\B5_SpringMVC\\src\\main\\webapp\\file\\" +originalFilename));         } catch  (IOException e) {             e.printStackTrace();         }         return  "......" ;     }          @RequestMapping("/upload02-1")      @ResponseBody      public  String upload02 (String fileName,MultipartFile upload1,MultipartFile upload2,MultipartFile upload3) {                  System.out.println(fileName);         String  name1  =  upload1.getOriginalFilename();         String  name2  =  upload2.getOriginalFilename();         String  name3  =  upload3.getOriginalFilename();         try  {             upload1.transferTo(new  File ("D:\\MySSM\\A2_Spring_MVC\\B5_SpringMVC\\src\\main\\webapp\\file\\"  + name1));             upload2.transferTo(new  File ("D:\\MySSM\\A2_Spring_MVC\\B5_SpringMVC\\src\\main\\webapp\\file\\"  + name2));             upload3.transferTo(new  File ("D:\\MySSM\\A2_Spring_MVC\\B5_SpringMVC\\src\\main\\webapp\\file\\"  + name3));         } catch  (IOException e) {             e.printStackTrace();         }         return  "......" ;     }          @RequestMapping("/upload02-2")      @ResponseBody      public  String upload03 (String fileName,MultipartFile[] upload) {                  System.out.println(fileName);         for  (MultipartFile multipartFile : upload) {             String  originalFilename  =  multipartFile.getOriginalFilename();             try  {                 multipartFile.transferTo(new  File ("D:\\MySSM\\A2_Spring_MVC\\B5_SpringMVC\\src\\main\\webapp\\file\\" +originalFilename));             } catch  (IOException e) {                 e.printStackTrace();             }         }         return  "......" ;     } } 
 
表单:
<%@ page contentType="text/html;charset=UTF-8"  language="java"  %> <%@ page isELIgnored="false"  %> <html> <head>     <title>Title</title> </head> <body style="background: bisque" > <br><br><br> <div align="center" >     <h1>文件上传 - 单文件上传</h1>     <form method="post"  enctype="multipart/form-data"  action="${pageContext.request.contextPath}/web/x4/upload01" >         文件名称:<input type="text"  name="filename" ><br>         上传文件:<input type="file"  name="upload" ><br>         <input type="submit"  value="提交上传" >     </form> </div> <br><br><br> <div align="center" >     <h1>文件上传 - 多文件上传 - 02 </h1>     <form method="post"  enctype="multipart/form-data"  action="${pageContext.request.contextPath}/web/x4/upload02-1" >         文件名称:<input type="text"  name="filename" ><br>         上传文件:<input type="file"  name="upload1" ><br>         上传文件:<input type="file"  name="upload2" ><br>         上传文件:<input type="file"  name="upload3" ><br>         <input type="submit"  value="提交上传" >     </form> </div> <br><br><br> <div align="center" >     <h1>文件上传 - 多文件上传 - 01 </h1>     <form method="post"  enctype="multipart/form-data"  action="${pageContext.request.contextPath}/web/x4/upload02-2" >         文件名称:<input type="text"  name="filename" ><br>         上传文件:<input type="file"  name="upload" ><br>         上传文件:<input type="file"  name="upload" ><br>         上传文件:<input type="file"  name="upload" ><br>         <input type="submit"  value="提交上传" >     </form> </div> </body> </html> 
 
SpringMVC拦截过滤器 自定义拦截器很简单,只有如下三步:
① 创建拦截器类实现HandlerInterceptor接口
② 配置拦截器
③ 测试拦截器的拦截效果
 
 
① 创建拦截器类实现HandlerInterceptor接口 package  com.ganga.interceptor;import  org.springframework.web.servlet.HandlerInterceptor;import  org.springframework.web.servlet.ModelAndView;import  javax.servlet.http.HttpServletRequest;import  javax.servlet.http.HttpServletResponse;public  class  MyInterceptor  implements  HandlerInterceptor  {         @Override      public  boolean  preHandle (HttpServletRequest request,                               HttpServletResponse response,                              Object handler)         throws  Exception {                  System.out.println("\n run preHandle ..." );         String  user  =  request.getParameter("user" );         if  ("ganga" .equals(user)){             return  true ;         }else  {             request.getRequestDispatcher("/error.jsp" )                 .forward(request,response);             return  false ;         }              }          @Override      public  void  postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  throws  Exception {         System.out.println("\n run postHandle ..." );     }          @Override      public  void  afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  throws  Exception {         System.out.println("\n run afterCompletion ..." );     } } 
 
② 配置拦截器 <mvc:interceptors >          <mvc:interceptor >          <mvc:mapping  path ="/web/dame01/**" />          <bean  class ="com.ganga.interceptor.MyInterceptor" />      </mvc:interceptor >            </mvc:interceptors > 
 
③ 测试拦截器的拦截效果 package  com.ganga.controller;import  org.springframework.stereotype.Controller;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestParam;import  org.springframework.web.servlet.ModelAndView;@Controller @RequestMapping("/web/dame02") public  class  DameController02  {    @RequestMapping("/me02")      public  ModelAndView method02 (ModelAndView modelAndView,@RequestParam("user")  String username) {                                    modelAndView.addObject("params" ,username);         modelAndView.setViewName("/index.jsp" );         System.out.println("\n访问执行..." );         return  modelAndView;     } } 
 
 
拦截器方法 
注意: 它是一个chain 与servlet的拦截器filter一样 是一个chain [链]
<mvc:interceptors >          	     <mvc:interceptor >          <mvc:mapping  path ="/web/dame03/**" />          <bean  class ="com.ganga.interceptor.DameChain01" />      </mvc:interceptor >           <mvc:interceptor >          <mvc:mapping  path ="/web/dame03/**" />          <bean  class ="com.ganga.interceptor.DameChain02" />      </mvc:interceptor >            </mvc:interceptors > 
 
 
SpringMVC异常处理机制 异常处理的思路 
 
异常处理两种方式 
方式一:
简单的异常处理器 SimpleMappingExceptionResolver 
SpringMVC已经定义好了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置
<bean  class ="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" >          <property  name ="defaultErrorView"  value ="/index.jsp" />           <property  name ="exceptionMappings" >          <map >                           <entry  key ="java.lang.ClassCastException"                       value ="/error.jsp" />                          <entry  key ="java.lang.ArithmeticException"                       value ="/error.jsp" />                          <entry  key ="java.io.FileNotFoundException"                       value ="/error.jsp" />                          <entry  key ="java.lang.NullPointerException"                       value ="/error.jsp" />                          <entry  key ="com.ganga.exception.MyException"                       value ="/error.jsp" />         </map >      </property >  </bean > 
 
 
方式二:
自定义异常 HandlerExceptionResolver 
① 创建异常处理器类实现HandlerExceptionResolver
② 配置异常处理器
③ 编写异常页面
④ 测试异常跳转
 
① 创建异常处理器类实现HandlerExceptionResolver
package  com.ganga.exception;import  org.springframework.web.servlet.HandlerExceptionResolver;import  org.springframework.web.servlet.ModelAndView;import  javax.servlet.http.HttpServletRequest;import  javax.servlet.http.HttpServletResponse;import  java.io.FileNotFoundException;public  class  MyHandlerExceptionResolver  implements  HandlerExceptionResolver  {    @Override      public  ModelAndView resolveException (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  {         ModelAndView  mav  =  new  ModelAndView ();                  if  (ex instanceof  ClassCastException){             mav.addObject("errors" ,"类转换异常" );         }else  if  (ex instanceof  ArithmeticException){             mav.addObject("errors" ,"除0异常" );         }else  if  (ex instanceof  FileNotFoundException){             mav.addObject("errors" ,"空文件路径异常" );         }else  if  (ex instanceof  NullPointerException){             mav.addObject("errors" ,"空指针异常" );         }else  if  (ex instanceof  MyException){             mav.addObject("errors" ,"自定义异常" );         }         mav.setViewName("/errors.jsp" );         return  mav;     } } 
 
② 配置异常处理器
<bean  class ="com.ganga.exception.MyHandlerExceptionResolver" /> 
 
③ 编写异常页面
<%@ page contentType="text/html;charset=UTF-8"  language="java"  %> <html> <head> <title>Title</title> </head> <body> 这是一个最终异常的显示页面 </body> </html> 
 
④ 测试异常跳转
 
知识要点
 
SpringJdbcTemplate JdbcTemplate概述 它是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装 。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nosql数据库的RedisTemplate,操 作消息队列的JmsTemplate等等。
JdbcTemplate开发步骤 ① 导入spring-jdbc和spring-tx坐标 
② 创建数据库表和实体 
③ 创建JdbcTemplate对象注入DataSource放入容器 
④ 执行数据库操作 
 
演示操作: ① 导入spring-jdbc和spring-tx坐标 
pom.xml
<dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-jdbc</artifactId >      <version > 5.3.18</version >  </dependency > <dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-tx</artifactId >      <version > 5.3.18</version >  </dependency > 
 
 
② 创建数据库表和实体 
 
③ 创建JdbcTemplate对象注入DataSource放入容器 
jdbc.properties
jdbc.driverClass =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql:///webcase?useSSL=false&useServerPrepStmts=true jdbc.user =root jdbc.password =ganga 
 
applicationContext.xml
<context:property-placeholder  location ="classpath:jdbc.properties" /> <bean  id ="dataSource"  class ="com.mchange.v2.c3p0.ComboPooledDataSource" >     <property  name ="driverClass"  value ="${jdbc.driverClass}" />      <property  name ="jdbcUrl"  value ="${jdbc.url}" />      <property  name ="user"  value ="${jdbc.user}" />      <property  name ="password"  value ="${jdbc.password}" />  </bean > <bean  id ="jdbcTemplate"  class ="org.springframework.jdbc.core.JdbcTemplate" >     <property  name ="dataSource"  ref ="dataSource" />  </bean > 
 
 
④ 执行数据库操作 
package  com.ganga.test;import  com.mchange.v2.c3p0.ComboPooledDataSource;import  org.springframework.context.ApplicationContext;import  org.springframework.context.support.ClassPathXmlApplicationContext;import  org.springframework.jdbc.core.JdbcTemplate;import  org.testng.annotations.Test;import  javax.sql.DataSource;import  javax.xml.crypto.Data;import  java.beans.PropertyVetoException;public  class  JdbcTemplateTest  {    @Test      public  void  entryTest01 ()  throws  PropertyVetoException {         JdbcTemplate  jdbcTemplate  =  new  JdbcTemplate ();                  ComboPooledDataSource  dataSource  =  new  ComboPooledDataSource ();         dataSource.setDriverClass("com.mysql.jdbc.Driver" );         dataSource.setJdbcUrl("jdbc:mysql:///webcase?useSSL=false" );         dataSource.setUser("root" );         dataSource.setPassword("ganga" );                  jdbcTemplate.setDataSource(dataSource);                  int  row  =  jdbcTemplate.update("insert into account values(?,?)" , "ganga" , 100000000 );         System.out.println(row);              }          @Test      public  void  entryTest02 () {                  ApplicationContext  app  =  new  ClassPathXmlApplicationContext ("applicationContext.xml" );         JdbcTemplate  jdbcTemplate  =  app.getBean(JdbcTemplate.class);                  int  row  =  jdbcTemplate.update("insert into account values(?,?)" ,"gangajiang" ,"1230000" );         System.out.println(row);     } } 
 
 
JdbcTemplate的常用操作 增删改查 
JdbcTemplateCRUDTest.java
package  com.ganga.test;import  com.ganga.pojo.Account;import  org.junit.Test;import  org.junit.runner.RunWith;import  org.springframework.beans.factory.annotation.Autowired;import  org.springframework.jdbc.core.BeanPropertyRowMapper;import  org.springframework.jdbc.core.JdbcTemplate;import  org.springframework.test.context.ContextConfiguration;import  org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import  java.util.List;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public  class  JdbcTemplateCRUDTest  {         @Autowired      private  JdbcTemplate jdbcTemplate;          @Test      public  void  updateAddTest () {         String  sql  =  "insert into account values(?,?)" ;         int  row  =  jdbcTemplate.update(sql, "gangale" , "1" );         System.out.println(row);     }          @Test      public  void  updateDeleteTest () {         String  sql  =  "delete from account where user = ?" ;         int  row  =  jdbcTemplate.update(sql, "gangale" );         System.out.println(row);     }          @Test      public  void  updateUpdateTest () {         String  sql  =  "update account set money=? where user=?" ;         int  row  =  jdbcTemplate.update(sql,"2" ,"gangale" );         System.out.println(row);     }          @Test      public  void  querySelectTest01 () {         String  sql  =  "select * from account" ;         List<Account> query = jdbcTemplate.query(sql, new  BeanPropertyRowMapper <Account>(Account.class));         System.out.println(query);     }          @Test      public  void  querySelectTest02 () {         String  sql  =  "select * from account where user=?" ;         Account  ganga  =  jdbcTemplate.queryForObject(sql, new  BeanPropertyRowMapper <Account>(Account.class), "ganga" );         System.out.println(ganga);     }          @Test      public  void  querySelectTest03 () {         String  sql  =  "select count(*) from account" ;         List<Long> longs = jdbcTemplate.queryForList(sql, Long.class);         System.out.println(longs);     } } 
 
 
SpringAOP 学习SpringAOP之前,先学习一下JDK动态代理 和Cglib动态代理 的实现方式
JDK 动态代理 步骤:
定义目标类接口 
实现目标类接口 重写目标类方法 
创建一个代理工厂类 实现 InvocationHandler 实现invoke()方法 
在invoke()方法中实现 :1. 增强方法   2. 调用目标方法 
通过Proxy.newProxyInstance()方法获取动态代理对象 
 
UserDao
package  com.ganga.servlet;public  interface  UserDao  {    int  getAge (String name, int  age) ; } 
 
UserDaoImpl
package  com.ganga.servlet.impl;import  com.ganga.servlet.UserDao;public  class  UserDaoImpl  implements  UserDao  {    @Override      public  int  getAge (String name, int  age)  {         System.out.println("目标方法执行......" );         System.out.println("代理前的目标结果是:"  + age);         return  age;     } } 
 
UserInvocationHandler [重点]
package  com.ganga.handler;import  com.ganga.aspect.MyAspect;import  java.lang.reflect.InvocationHandler;import  java.lang.reflect.Method;import  java.lang.reflect.Proxy;public  class  UserInvocationHandler  implements  InvocationHandler  {         Object target;          public  Object getInstance (Object target)  {         this .target = target;         return  Proxy.newProxyInstance(                 target.getClass().getClassLoader(),                 target.getClass().getInterfaces(),                 this );              }     @Override      public  Object invoke (Object proxy, Method method, Object[] args)  throws  Throwable {         Object ageObj;                  MyAspect  myAspect  =  new  MyAspect ();         myAspect.check_permission();                  ageObj = method.invoke(target, args);                  if  (ageObj != null ){             int  age  =  (int ) ageObj;             age = age + 1 ;             ageObj = age;         }         myAspect.log();                  return  ageObj;     } } 
 
MyAspect
package  com.ganga.aspect;public  class  MyAspect  {    public  void  check_permission () {         System.out.println("检查权限..." );     }     public  void  log () {         System.out.println("日志记录..." );     } } 
 
DameUser
package  com.ganga;import  com.ganga.handler.UserInvocationHandler;import  com.ganga.servlet.UserDao;import  com.ganga.servlet.impl.UserDaoImpl;public  class  DameUser  {    public  static  void  main (String[] args)  {                           UserDao  userDao  =  new  UserDaoImpl ();                           UserDao  proxy  =  (UserDao) new  UserInvocationHandler ().getInstance(userDao);                  int  age  =  proxy.getAge("尴尬酱" , 9 );                  System.out.println("增强方法后的 代理后的 返回结果:" +age);     } } 
 
 
Cglib动态代理 UserTarget
package  com.ganga.service;public  class  UserTarget  {         public  int  getAge (String name,int  age) {         System.out.println("目标方法执行......" );         System.out.println("目标方法执行age参数值为: "  + age);         return  age;     } } 
 
CglibProxy [重点]
package  com.ganga.proxy;import  com.ganga.aspect.MyAspect;import  org.springframework.cglib.proxy.Enhancer;import  org.springframework.cglib.proxy.MethodInterceptor;import  org.springframework.cglib.proxy.MethodProxy;import  java.lang.reflect.Method;public  class  CglibProxy  implements  MethodInterceptor  {         Object target;               public  Object createProxy (Object target) {                  this .target = target;                  Enhancer  enhancer  =  new  Enhancer ();                  enhancer.setSuperclass(target.getClass());                  enhancer.setCallback(this );                  Object  proxy  =  enhancer.create();         return  proxy;     }          @Override      public  Object intercept (Object proxy, Method method, Object[] args, MethodProxy methodProxy)  throws  Throwable {                  MyAspect  myAspect  =  new  MyAspect ();         myAspect.check_permission();                           Object  ageObj  =  null ;         ageObj = method.invoke(target, args);                                    if  (ageObj != null ){             int  age  =  (int ) ageObj;             age = age + 1 ;             ageObj = age;         }         myAspect.log();                  return  ageObj;     } } 
 
MyAspect
package  com.ganga.aspect;public  class  MyAspect  {    public  void  check_permission () {         System.out.println("检查权限..." );     }     public  void  log () {         System.out.println("日志记录..." );     } } 
 
CglibProxyTest
package  com.ganga.test;import  com.ganga.proxy.CglibProxy;import  com.ganga.service.UserTarget;import  net.sf.cglib.proxy.MethodInterceptor;public  class  CglibProxyTest  {    public  static  void  main (String[] args)  {                  UserTarget  userTarget  =  new  UserTarget ();                  CglibProxy  im  =  new  CglibProxy ();                  UserTarget  proxy  =  (UserTarget) im.createProxy(userTarget);                  int  age  =  proxy.getAge("尴尬酱" , 9 );         System.out.println("代理后age的值是: "  + age);     } } 
 
 
AOP面向切面编程 一:什么是面向切面编程 
AOP  为 A  spect O  riented P  rogramming 的缩写,意思为面向切面编程 ,是通过预编译方式 和运行期 动态代理   实现程序功能的统一维护的一种技术。
动态代理 
AOP 是 OOP 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型 。利用AOP可以对业务逻辑的各个部分进行隔离 ,从而使得业务逻辑各部分之间的耦合度降低 ,提高程序 的可重用性,同时提高了开发的效率。
二:AOP 的作用及其优势 
三:AOP 的底层实现 
        实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现的 。在运行期间 ,Spring通过动态代理技术动态 的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。
四:AOP 的动态代理技术 
常用的动态代理技术
JDK 代理 : 基于接口的动态代理技术
 
cglib 代理:基于父类的动态代理技术
 
 
五:JDK的动态代理 
首先要有一个目标接口:
package  com.ganga.proxy.jdk;public  interface  TargetInterface  {    void  sell () ; } 
 
有一个目标类 实现 这个目标接口
package  com.ganga.proxy.jdk;public  class  Target  implements  TargetInterface {    @Override      public  void  sell ()  {         System.out.println("目标方法执行。。。" );     } } 
 
要增强的代码
package  com.ganga.proxy.jdk;public  class  MyAdvice  {    public  void  before () {         System.out.println("前置增强..." );     }     public  void  after () {         System.out.println("后置增强..." );     } } 
 
动态代理 并 测试
package  com.ganga.proxy.jdk;import  java.lang.reflect.InvocationHandler;import  java.lang.reflect.Method;import  java.lang.reflect.Proxy;public  class  RunMain  {    public  static  void  main (String[] args)  {                  Target  target  =  new  Target ();                  MyAdvice  myAdvice  =  new  MyAdvice ();                  TargetInterface  proxy  =  (TargetInterface)              Proxy.newProxyInstance(             	                 target.getClass().getClassLoader(),             	                 target.getClass().getInterfaces(),             	                 new  InvocationHandler () {                     @Override                      public  Object invoke (Object proxy, Method method, Object[] args)  throws  Throwable {                         myAdvice.before();                          Object  invoke  =  method.invoke(target, args);                         myAdvice.after();                          return  invoke;                     }                 }                      );                  proxy.sell();     } } 
 
 
六:Cglib的动态代理 
需要一个目标类  不需要接口
package  com.ganga.proxy.cglib;public  class  Target {    public  void  sell ()  {         System.out.println("目标方法执行。。。" );     } } 
 
要增强的代码
package  com.ganga.proxy.cglib;public  class  MyAdvice  {    public  void  before () {         System.out.println("前置增强..." );     }     public  void  after () {         System.out.println("后置增强..." );     } } 
 
创建动态代理 并 测试
package  com.ganga.proxy.cglib;import  org.springframework.cglib.proxy.Enhancer;import  org.springframework.cglib.proxy.MethodInterceptor;import  org.springframework.cglib.proxy.MethodProxy;import  java.lang.reflect.Method;public  class  RunMain  {    public  static  void  main (String[] args)  {                  Target  target  =  new  Target ();                  MyAdvice  myAdvice  =  new  MyAdvice ();                  Enhancer  enhancer  =  new  Enhancer ();                  enhancer.setSuperclass(target.getClass());                           enhancer.setCallback(new  MethodInterceptor () {             @Override              public  Object intercept                  (Object o,                   Method method,                  Object[] objects,                  MethodProxy methodProxy)  throws  Throwable {                                                                   myAdvice.before();                                  Object  invoke  =  method.invoke(target, args);                                  myAdvice.after();                 return  invoke;             }         });                  Target  proxy  =  (Target) enhancer.create();                  proxy.sell();     } } 
 
AOP 相关概念 Spring 的 AOP 实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。
在正式讲解 AOP 的操作之前,我们必须理解 AOP 的相关术语,常用的术语如下:
Target(目标对象)  :代理的目标对象
 
Proxy (代理)  :一个类被 AOP 织入增强后,就产生一个结果代理类
 
Joinpoint(连接点)  :所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方 法类型的连接点
 
Pointcut(切入点)  :所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义
 
Advice(通知/ 增强)  :所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知
 
Aspect(切面)  :是切入点和通知(引介)的结合
 
Weaving(织入)  :是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而 AspectJ采用编译期织入和类装载期织入
 
 
AOP 开发明确的事项 
**需要编写的内容 **
 
 
AOP 技术实现的内容 Spring 框架监控切入点方法的执行。 
一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
 
 
AOP 底层使用哪种代理方式 
在 spring 中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。
 
 
 
基于XML的AOP开发 快速入门 ① 导入 AOP 相关坐标
② 创建目标接口和目标类(内部有切点)
③ 创建切面类(内部有增强方法)
④ 将目标类和切面类的对象创建权交给 spring
⑤ 在 applicationContext.xml 中配置织入关系
⑥ 测试代码
 
① 导入 AOP 相关坐标
<dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-context</artifactId >      <version > 5.3.18</version >  </dependency >   <dependency >     <groupId > org.aspectj</groupId >      <artifactId > aspectjweaver</artifactId >      <version > 1.9.9.1</version >  </dependency > 
 
② 创建目标接口和目标类(内部有切点)
目标接口
package  com.ganga.aop;public  interface  TargetInterface  {    void  sell1 () ;     int  sell2 (String name,int  age) ;     int  sell3 (String name,int  age) ; } 
 
目标类
package  com.ganga.aop;public  class  Target  implements  TargetInterface  {    @Override      public  void  sell1 ()  {         System.out.println("目标方法执行。。。" );     }     @Override      public  int  sell2 (String name,int  age)  {         System.out.println("姓名: "  + name);         System.out.println("年龄: "  + age);         return  age;     }     @Override      public  int  sell3 (String name, int  age) {         System.out.println("姓名: "  + name);         System.out.println("年龄: "  + age);         int  i  =  1 /0 ;          return  age;     } } 
 
③ 创建切面类(内部有增强方法)
package  com.ganga.aop;import  org.aspectj.lang.ProceedingJoinPoint;public  class  MyAdvice  {    public  void  before () {         System.out.println("前置增强..." );     }     public  void  afterReturning () {         System.out.println("后置增强..." );     }     public  Object around (ProceedingJoinPoint pjp)  throws  Throwable {         System.out.println("环绕前增强...." );         Object  proceed  =  pjp.proceed();         System.out.println("环绕后增强...." );         return  proceed;     }     public  void  throwing () {         System.out.println("异常抛出后增强..." );     }     public  void  after () {         System.out.println("最终增强...." );     } } 
 
④ 将目标类和切面类的对象创建权交给 spring
⑤ 在 applicationContext.xml 中配置织入关系
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:aop ="http://www.springframework.org/schema/aop"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation =                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd                " >         <bean  id ="target"  class ="com.ganga.aop.Target" />           <bean  id ="myAdvice"  class ="com.ganga.aop.MyAdvice" />           <aop:config >                   <aop:aspect  ref ="myAdvice" >                           <aop:before  method ="before"  pointcut ="execution(public void com.ganga.aop.Target.sell1())" />              <aop:after-returning  method ="afterReturning"  pointcut ="execution(public void com.ganga.aop.Target.sell1())" />                           <aop:before  method ="before"  pointcut ="execution(* com.ganga.aop.Target.sell2(String,int))" />                           <aop:before  method ="before"  pointcut ="execution(* com.ganga.aop..*.sell3(..))" />                           <aop:pointcut  id ="pointcutSell3"  expression ="execution(* com.ganga.aop..*.sell3(..))" />                           <aop:around  method ="around"  pointcut-ref ="pointcutSell3" />                           <aop:after-throwing  method ="throwing"  pointcut-ref ="pointcutSell3" />                           <aop:after  method ="after"  pointcut-ref ="pointcutSell3" />          </aop:aspect >      </aop:config >       </beans > 
 
⑥ 测试代码
package  com.ganga.aop;import  org.junit.Test;import  org.junit.runner.RunWith;import  org.springframework.beans.factory.annotation.Autowired;import  org.springframework.test.context.ContextConfiguration;import  org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public  class  TestAOP  {         @Autowired      private  TargetInterface target;     @Test      public  void  testTarget () {         System.out.println("=============" );         target.sell1();         System.out.println("=============" );     }     @Test      public  void  testPointcut1 () {         int  age  =  target.sell2("尴尬" , 9 );         System.out.println(age);     }     @Test      public  void  testPointcut2 ()  throws  InterruptedException {         int  age  =  target.sell3("尴尬酱" ,9 );         System.out.println(age);              } } 
 
 
切点表达式 
通知的类型 
其中 环绕通知比较特殊:
需要参数: ProceedingJoninPoint
调用proceed()方法 并返回一个对象 也是目标对象的返回
public  Object around (ProceedingJoinPoint pjp)  throws  Throwable {    System.out.println("环绕前增强...." );     Object  proceed  =  pjp.proceed();     System.out.println("环绕后增强...." );     return  proceed; } 
 
切点表达式的抽取 
知识要点
 
Spring的事务控制 编程式事务控制 编程式事务控制相关对象
编程式事务控制三大对象
**PlatformTransactionManager   [接口]  平台事务管理器 ** 
视频 
PlatformTransactionManager 接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法。
TransactionDefinition   事务的定义信息对象 
视频 
TransactionDefinition 是事务的定义信息对象,里面有如下方法:
事务隔离级别: 
设置隔离级别,可以解决事务并发产生的问题,如脏读 、不可重复读 和虚读 。
 
事务传播行为: 
**REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值) ** 
 
**SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务) ** 
 
MANDATORY :使用当前的事务,如果当前没有事务,就抛出异常
 
REQUERS_NEW :新建事务,如果当前在事务中,把当前事务挂起。
 
NOT_SUPPORTED :以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
 
NEVER :以非事务方式运行,如果当前存在事务,抛出异常
 
NESTED :如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作
 
超时时间  :默认值是-1,没有超时限制。如果有,以秒为单位进行设置
 
是否只读 :建议查询时设置为只读
 
 
 
TransactionStatus    [接口] 事务的运行状态 
TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。
三者之间的关系 
1. PlatformTransactionManager 
    接口  定义行为  接口的实现根据不同的dao层技术不同的api进行实现的
2. TransactionDefinition 
封装事务的参数的
3. TransactionStatus 
被动的封装事务的状态信息的
1和2是是要具体设置的 如果用Spring的 声明式事务控制 是需要配置的
而3是 1和2配置后,事务运行状态发生被动的封装事务的状态信息的,是不需要配置的
 
声明式事务控制 什么是声明式事务控制: 
Spring 的声明式事务顾名思义就是采用声明的方式来处理事务 。这里所说的声明,就是指在配置文件中声明 ,用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。
声明式事务处理的作用: 
事务管理不侵入开发的组件。具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如 此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话, 也只需要在定义文件中重新配置即可 
在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译 ,这样维护起来极其方便 
 
织入:         切面:  业务方法  –> 切点     +   事务控制 –>通知/增强
注意: Spring 声明式事务控制底层就是AOP。
 
基于XML的声明式事务控制 先看一下代码: 
Dao层
package  com.ganga.dao;public  interface  TransferDao  {    void  out (String user,double  money) ;     void  in (String user,double  money) ; } 
 
package  com.ganga.dao.impl;import  com.ganga.dao.TransferDao;import  org.springframework.jdbc.core.JdbcTemplate;public  class  TransferDaoImpl  implements  TransferDao  {    private  JdbcTemplate jdbcTemplate;     public  void  setJdbcTemplate (JdbcTemplate jdbcTemplate)  {         this .jdbcTemplate = jdbcTemplate;     }     @Override      public  void  out (String user, double  money)  {         jdbcTemplate.update("update account set money = money-? where user = ?;" ,money,user);     }     @Override      public  void  in (String user, double  money)  {         jdbcTemplate.update("update account set money = money+? where user = ?;" ,money,user);     } } 
 
service层
package  com.ganga.service;public  interface  TransferService  {    public  void  transfer (String outMan,String inMan,double  money) ; } 
 
package  com.ganga.service.impl;import  com.ganga.dao.TransferDao;import  com.ganga.service.TransferService;public  class  TransferServiceImpl  implements  TransferService  {    private  TransferDao transferDao;     public  void  setTransferDao (TransferDao transferDao)  {         this .transferDao = transferDao;     }          @Override      public  void  transfer (String outMan, String inMan, double  money)  {         transferDao.out(outMan,money);         System.out.println("======" );         int  i  =  1 /0 ;          transferDao.in(inMan,money);     } } 
 
模拟controller层/服务层
package  com.ganga.controller;import  com.ganga.service.TransferService;import  org.springframework.context.ApplicationContext;import  org.springframework.context.support.ClassPathXmlApplicationContext;public  class  TransferController  {    public  static  void  main (String[] args)  {         ApplicationContext  app  =  new  ClassPathXmlApplicationContext ("applicationContext.xml" );         TransferService  transfer  =  app.getBean(TransferService.class);         transfer.transfer("ganga" ,"gangajiang" ,1 );     } } 
 
基于XML声明式事务控制的实现分析: 
声明式事务控制明确事项:
切点是谁?        —— 业务方法 
谁是通知?        —— 事务增强 
配置切面?        —— 事务增强+业务方法 
 
spring-tx坐标导入
<dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-jdbc</artifactId >      <version > 5.3.18</version >  </dependency > <dependency >     <groupId > org.springframework</groupId >      <artifactId > spring-tx</artifactId >      <version > 5.3.18</version >  </dependency > 
 
applicationContext.xml的配置
<?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:context ="http://www.springframework.org/schema/context"         xmlns:aop ="http://www.springframework.org/schema/aop"         xmlns:tx ="http://www.springframework.org/schema/tx"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation =                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd                " >         <context:property-placeholder  location ="classpath:jdbc.properties" />                <bean  id ="dataSource"  class ="com.mchange.v2.c3p0.ComboPooledDataSource" >          <property  name ="driverClass"  value ="${jdbc.driverClass}" />          <property  name ="jdbcUrl"  value ="${jdbc.url}" />          <property  name ="user"  value ="${jdbc.user}" />          <property  name ="password"  value ="${jdbc.password}" />      </bean >           <bean  id ="jdbcTemplate"  class ="org.springframework.jdbc.core.JdbcTemplate" >          <property  name ="dataSource"  ref ="dataSource" />      </bean >           <bean  id ="transferDao"  class ="com.ganga.dao.impl.TransferDaoImpl" >          <property  name ="jdbcTemplate"  ref ="jdbcTemplate" />      </bean >           <bean  id ="transferServlet"  class ="com.ganga.service.impl.TransferServiceImpl" >          <property  name ="transferDao"  ref ="transferDao" />      </bean >           <bean  id ="transactionManager"  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >          <property  name ="dataSource"  ref ="dataSource" />      </bean >                     <tx:advice  id ="txAdvice"  transaction-manager ="transactionManager" >                   <tx:attributes >                           <tx:method  name ="transfer"  isolation ="REPEATABLE_READ"  propagation ="REQUIRED"  timeout ="-1"  read-only ="false" />              <tx:method  name ="sell"  isolation ="REPEATABLE_READ"  propagation ="REQUIRED"  timeout ="-1"  read-only ="false" />              <tx:method  name ="update*"  isolation ="REPEATABLE_READ"  propagation ="REQUIRED"  timeout ="-1"  read-only ="false" />                       </tx:attributes >      </tx:advice >                     <aop:config >                   <aop:advisor  advice-ref ="txAdvice"  pointcut ="execution(* com.ganga.service.impl..*.*(..))" />               </aop:config >  </beans > 
 
<tx:method>的相关属性 
 
基于XML实现要点: 
① 引入tx 和 aop命名空间
② 配置平台事务管理器
<bean  id ="transactionManager"  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >     	         <property  name ="dataSource"  ref ="dataSource" />       </bean > 
 
③ 配置事务增强
<tx:advice  id ="txAdvice"              transaction-manager ="transactionManager" >               <tx:attributes >                                     <tx:method  name ="transfer"                       isolation ="REPEATABLE_READ"                      propagation ="REQUIRED"                      timeout ="-1"  read-only ="false" />                  <tx:method  name ="sell"                       isolation ="REPEATABLE_READ"                      propagation ="REQUIRED"                      timeout ="-1"  read-only ="false" />              </tx:attributes >  </tx:advice > 
 
④ 配置事务 AOP 织入
<aop:config >          <aop:advisor  advice-ref ="txAdvice"                     pointcut ="execution(切点表达式)" /> </aop:config > 
 
 
基于注解的声明式事务控制 ① 使用 **@Transactional **在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离 级别、传播行为等。
② 注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。
③ 使用在方法上,不同的方法可以采用不同的事务参数配置。
④ Xml配置文件中要开启事务的注解驱动**<tx:annotation-driven />**
 
注解: @Transationall 
Service
package  com.ganga.service.impl;import  com.ganga.dao.TransferDao;import  com.ganga.service.TransferService;import  org.springframework.beans.factory.annotation.Autowired;import  org.springframework.stereotype.Service;import  org.springframework.transaction.annotation.Isolation;import  org.springframework.transaction.annotation.Propagation;import  org.springframework.transaction.annotation.Transactional;@Service @Transactional(isolation=Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, timeout = -1, readOnly = false) public  class  TransferServiceImpl  implements  TransferService  {         @Autowired      private  TransferDao transferDao;          @Override           @Transactional(isolation=Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, timeout = -1, readOnly = false)      public  void  transfer (String outMan, String inMan, double  money)  {         transferDao.out(outMan,money);         System.out.println("======" );         int  i  =  1 /0 ;         transferDao.in(inMan,money);     } } 
 
 
事务注解驱动 
applicationContext.xml
<bean  id ="transactionManager"  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >     <property  name ="dataSource"  ref ="dataSource" />  </bean > <tx:annotation-driven  transaction-manager ="transactionManager" /> 
 
 
MyBatis框架 – 复习 MyBatis初始化配置  
MyBatis官网文档地址: https://mybatis.org/mybatis-3/zh/getting-started.html 
目录结构: 
注意: 这个是没有使用Mapper代理开发的目录格式
Mapper代理开发目录格式 // 优化格式 将资源配置文件放在 resources当中 但是打包后又刚好和java class文件在同一目录下
pom.xml Maven -> pom.xml核心配置文件 
<?xml version="1.0"  encoding="UTF-8" ?> <project  xmlns ="http://maven.apache.org/POM/4.0.0"           xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >     <modelVersion > 4.0.0</modelVersion >      <groupId > org.example</groupId >      <artifactId > B5_MyBatis</artifactId >      <version > 1.0-SNAPSHOT</version >      <properties >          <maven.compiler.source > 16</maven.compiler.source >          <maven.compiler.target > 16</maven.compiler.target >      </properties >           <dependencies >                   <dependency >              <groupId > org.mybatis</groupId >              <artifactId > mybatis</artifactId >              <version > 3.4.6</version >          </dependency >                   <dependency >              <groupId > mysql</groupId >              <artifactId > mysql-connector-java</artifactId >              <version > 5.1.46</version >          </dependency >                   <dependency >              <groupId > junit</groupId >              <artifactId > junit</artifactId >              <version > 4.13.1</version >              <scope > test</scope >          </dependency >                   <dependency >              <groupId > org.slf4j</groupId >              <artifactId > slf4j-api</artifactId >              <version > 1.7.20</version >          </dependency >                   <dependency >              <groupId > ch.qos.logback</groupId >              <artifactId > logback-classic</artifactId >              <version > 1.2.3</version >          </dependency >                   <dependency >              <groupId > ch.qos.logback</groupId >              <artifactId > logback-core</artifactId >              <version > 1.2.3</version >          </dependency >      </dependencies >           <build >          <resources >              <resource >                  <directory > src/main/resources</directory >                  <includes >                      <include > **/*.properties</include >                      <include > **/*.xml</include >                  </includes >                  <filtering > false</filtering >              </resource >              <resource >                  <directory > src/main/java</directory >                  <includes >                      <include > **/*.properties</include >                      <include > **/*.xml</include >                  </includes >                  <filtering > false</filtering >              </resource >          </resources >      </build >  </project > 
 
mybatis-config.xml MyBatis -> mybatis-config.xml核心配置文件 
<?xml version="1.0"  encoding="UTF8"  ?> <!DOCTYPE configuration          PUBLIC  "-//mybatis.org//DTD Config 3.0//EN"          "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration >     <environments  default ="development" >          <environment  id ="development" >              <transactionManager  type ="JDBC" />                           <dataSource  type ="POOLED" >                                   <property  name ="driver"  value ="com.mysql.jdbc.Driver" />                                   <property  name ="url"  value ="jdbc:mysql:///数据库名?useSSL=false& useUnicode=true& characterUnicode=utf-8C" />                                   <property  name ="username"  value ="" />                                   <property  name ="password"  value ="" />              </dataSource >          </environment >      </environments >  	          <mappers >                                              <package  name ="com.ganga.mapper" />      </mappers >  </configuration > 
 
XxxMapper.xml模板一 <?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." >          <select  id =""  resultType ="" >          select * from user;     </select >       </mapper > 
 
XxxMapper.xml模板二 <?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.ganga.mapper.BrandMapper" >               <resultMap  id ="brandResultMap"  type ="com" >                    <result  column ="数据库"  property ="java类变量" />               </resultMap >           <select  id =""  resultMap ="brandResultMap" >          select * from tb_brand;     </select >                     <select  id =""  resultMap ="resultMapId" >          select * from tb_brand where id = #{id};     </select >       </mapper > 
 
封装获取SqlSessionFactory对象 package  com.ganga.util;import  org.apache.ibatis.io.Resources;import  org.apache.ibatis.session.SqlSession;import  org.apache.ibatis.session.SqlSessionFactory;import  org.apache.ibatis.session.SqlSessionFactoryBuilder;import  java.io.IOException;import  java.io.InputStream;public  class  MyBatisUtils  {    private  static  SqlSessionFactory sqlSessionFactory;     static  {         try  {                          String  resource  =  "mybatis-config.xml" ;             InputStream  inputStream  =  Resources.getResourceAsStream(resource);             sqlSessionFactory = new  SqlSessionFactoryBuilder ().build(inputStream);         } catch  (IOException e) {             e.printStackTrace();         }     }          public  static  SqlSessionFactory getSqlSessionFactory () {         return  sqlSessionFactory;     } } 
 
相关API 执行方式 
全限定名 
三个核心类 
Mapper代理 
resultMap 映射 <resultMap  id ="brandResultMap"  type ="com.ganga.pojo.Brand" >     <result  column ="brand_name"  property ="brandName" />      <result  column ="company_name"  property ="companyName" />       </resultMap > <select  id ="selectAll"  resultMap ="brandResultMap" >     select *     from tb_brand; </select > 
 
参数封装 Mybatis 接口方法中可以接收各种各样的参数,如下:
多个参数 
单个参数:单个参数又可以是如下类型
POJO 类型 
Map 集合类型 
Collection 集合类型 
List 集合类型 
Array 类型 
其他类型 
 
 
 
常用的三种: 参数接收方式
散装参数: 如果方法中有多个参数, 需要使用( @Param(“SQL参数占位符名称”)数据类型 参数名称一般和占位符名称相同 ) 
对象参数: 对象的属性名称要和参数占位符名称一致 
map集合参数: Map map = new HashMap(); map.put(“占位符名称”,参数); 
 
散装参数: List<Brand> selectByCondition1 (@Param("status")  int  status, @Param("companyName")  String companyName, @Param("brandName")  String brandName) ; 	     int  status  =  1 ;     String  companyName  =  "华为" ;     String  brandName  =  "华为" ;          companyName = "%"  + companyName + "%" ;     brandName = "%"  + brandName + "%" ;          SqlSession  sqlSession  =  MyBatisUtils.getSqlSessionFactory().openSession();          BrandMapper  brandMapper  =  sqlSession.getMapper(BrandMapper.class);          List<Brand> brands = brandMapper.selectByCondition1(status, companyName, brandName);          sqlSession.close(); 
 
对象参数: List<Brand> selectByCondition2 (Brand brand) ;          int  status  =  1 ;     String  companyName  =  "华为" ;     String  brandName  =  "华为" ;          companyName = "%"  + companyName + "%" ;     brandName = "%"  + brandName + "%" ;          Brand  brand  =  new  Brand ();     brand.setStatus(status);     brand.setCompanyName(companyName);     brand.setBrandName(brandName);          SqlSession  sqlSession  =  MyBatisUtils.getSqlSessionFactory().openSession();          BrandMapper  brandMapper  =  sqlSession.getMapper(BrandMapper.class);          List<Brand> brands = brandMapper.selectByCondition2(brand);          sqlSession.close(); 
 
map集合参数: List<Brand> selectByCondition3 (Map map) ;          int  status  =  1 ;     String  companyName  =  "华为" ;     String  brandName  =  "华为" ;          companyName = "%"  + companyName + "%" ;     brandName = "%"  + brandName + "%" ;          Map  map  =  new  HashMap ();     map.put("status" ,status);     map.put("companyName" ,companyName);     map.put("brandName" ,brandName);          SqlSession  sqlSession  =  MyBatisUtils.getSqlSessionFactory().openSession();          BrandMapper  brandMapper  =  sqlSession.getMapper(BrandMapper.class);          List<Brand> brands = brandMapper.selectByCondition3(map);          sqlSession.close(); 
 
提取Sql片段 
动态SQL 动态查询 
<select  id ="selectDynamicSQL03"  resultMap ="brandResultMap" >     select *     from tb_brand     <where >          <if  test ="status != null" >              status = #{status}         </if >          <if  test ="companyName != null and companyName != ''" >              and company_name like #{companyName}         </if >          <if  test ="brandName != null and brandName != ''" >              and brand_name like #{brandName};         </if >      </where >  </select > <select  id ="selectDynamicSQL001"  resultMap ="brandResultMap" >     select *     from tb_brand     where     <choose >           <when  test ="status != null" >               status = #{status}         </when >          <when  test ="companyName != null and companyName != ''" >              company_name like #{companyName}         </when >          <when  test ="brandName != null and brandName != ''" >              brand_name like #{brandName};         </when >          <otherwise >               1 = 1         </otherwise >      </choose >  </select > <select  id ="selectDynamicSQL002"  resultMap ="brandResultMap" >     select *     from tb_brand     <where >          <choose >               <when  test ="status != null" >                   status = #{status}             </when >              <when  test ="companyName != null and companyName != ''" >                  company_name like #{companyName}             </when >              <when  test ="brandName != null and brandName != ''" >                  brand_name like #{brandName};             </when >          </choose >      </where >  </select > 
 
动态修改 
<update  id ="updateBrandDynamic" >     update     tb_brand     <set >          <if  test ="brandName != null and brandName != ''" >              brand_name = #{brandName},         </if >          <if  test ="companyName != null and companyName != ''" >              company_name = #{companyName},         </if >          <if  test ="ordered != null" >              ordered = #{ordered},         </if >          <if  test ="description != null and description != ''" >              description = #{description},         </if >          <if  test ="status != null" >              status = #{status}         </if >      </set >      where     id = #{id}; </update > 
 
动态删除 
<delete  id ="deleteByIdAll" >     delete from tb_brand     where id     in  <foreach  collection ="ids"  item ="id"  separator =","  open ="("  close =")" >      #{id}     </foreach >  </delete > 
 
 
注解开发 Mybatis 针对 CURD 操作都提供了对应的注解,已经做到见名知意。如下:
查询 :@Select 
添加 :@Insert 
修改 :@Update 
删除 :@Delete 
 
MyBatis核心配置文件深入 
environments标签 
<environments  default ="development" >               <environment  id ="development" >                   <transactionManager  type ="JDBC" />                   <dataSource  type ="POOLED" >                           <property  name ="driver"  value ="" />                           <property  name ="url"  value ="" />                           <property  name ="username"  value ="" />                           <property  name ="password"  value ="" />          </dataSource >      </environment >       </environments > 
 
 
mapper标签 该标签的作用是加载映射的,加载方式有如下几种:
使用相对于类路径的资源引用 ,例如:
 <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
使用完全限定资源定位符(URL) ,例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
使用映射器接口实现类的完全限定类名 ,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
将包内的映射器接口实现全部注册为映射器 ,例如:
<package name="org.mybatis.builder"/>
 
Properties标签 实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件   — 使用el表达式
<properties  resource ="jdbc.properties" > </properties > <environments  default ="development" >     <environment  id ="development" >          <transactionManager  type ="JDBC" />                   <dataSource  type ="POOLED" >                                        <property  name ="driver"                          value ="${jdbc.driverClass}" />                          <property  name ="url"                          value ="${jdbc.url}" />                          <property  name ="username"                          value ="${jdbc.user}" />                          <property  name ="password"                          value ="${jdbc.password}" />                      </dataSource >      </environment >  </environments > 
 
jdbc.driverClass =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql:///webcase?useSSL=false&useServerPrepStmts=true jdbc.user =root jdbc.password =ganga 
 
 
 
typeAliases标签 
 
 
综合演示 mybatis-config.xml <?xml version="1.0"  encoding="UTF8"  ?> <!DOCTYPE configuration          PUBLIC  "-//mybatis.org//DTD Config 3.0//EN"          "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration >     <environments  default ="development" >          <environment  id ="development" >              <transactionManager  type ="JDBC" />                           <dataSource  type ="POOLED" >                                   <property  name ="driver"  value ="com.mysql.jdbc.Driver" />                                   <property  name ="url"  value ="jdbc:mysql:///webcase?useSSL=false& useUnicode=true& characterUnicode=utf-8C" />                                   <property  name ="username"  value ="root" />                                   <property  name ="password"  value ="ganga" />              </dataSource >          </environment >      </environments >           <mappers >                                              <package  name ="com.ganga.mapper" />      </mappers >  </configuration > 
 
 
MyBatisUtils.java package  com.ganga.util;import  org.apache.ibatis.io.Resources;import  org.apache.ibatis.session.SqlSessionFactory;import  org.apache.ibatis.session.SqlSessionFactoryBuilder;import  java.io.IOException;import  java.io.InputStream;public  class  MyBatisUtils  {    private  static  SqlSessionFactory sqlSessionFactory;     static {         try  {                          String  resource  =  "mybatis-config.xml" ;             InputStream  inputStream  =  Resources.getResourceAsStream(resource);             sqlSessionFactory = new  SqlSessionFactoryBuilder ().build(inputStream);         } catch  (IOException e) {             e.printStackTrace();         }     }          public  static  SqlSessionFactory getSqlSessionFactory () {         return  sqlSessionFactory;     } } 
 
 
UserMapper.xml <?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.ganga.mapper.BrandMapper" >          <resultMap  id ="brandResultMap"  type ="com.ganga.pojo.Brand" >          <result  column ="brand_name"  property ="brandName" />          <result  column ="company_name"  property ="companyName" />               </resultMap >           <select  id ="selectAll"  resultMap ="brandResultMap" >          select *         from tb_brand;     </select >           <select  id ="selectById"  resultMap ="brandResultMap" >          select *         from tb_brand         where id = #{id};     </select >           <select  id ="selectByOrdered"  resultMap ="brandResultMap" >          select *         from tb_brand         where ordered > = 50;     </select >                <select  id ="selectByCondition1"  resultMap ="brandResultMap" >          select *         from tb_brand         where status = #{status}           and company_name like #{companyName}           and brand_name like #{brandName};     </select >           <select  id ="selectByCondition2"  resultMap ="brandResultMap" >          select *         from tb_brand         where status = #{status}           and company_name like #{companyName}           and brand_name like #{brandName};     </select >           <select  id ="selectByCondition3"  resultMap ="brandResultMap" >          select *         from tb_brand         where status = #{status}           and company_name like #{companyName}           and brand_name like #{brandName};     </select >                <select  id ="selectDynamicSQL01"  resultMap ="brandResultMap" >          select *         from tb_brand         where status = #{status}           and company_name like #{companyName}           and brand_name like #{brandName};     </select >           <select  id ="selectDynamicSQL02"  resultMap ="brandResultMap" >          select *         from tb_brand         where         <if  test ="status != null" >              status = #{status}         </if >          <if  test ="companyName != null and companyName != ''" >              and company_name like #{companyName}         </if >          <if  test ="brandName != null and brandName != ''" >              and brand_name like #{brandName};         </if >      </select >           <select  id ="selectDynamicSQL03"  resultMap ="brandResultMap" >          select *         from tb_brand         <where >              <if  test ="status != null" >                  status = #{status}             </if >              <if  test ="companyName != null and companyName != ''" >                  and company_name like #{companyName}             </if >              <if  test ="brandName != null and brandName != ''" >                  and brand_name like #{brandName};             </if >          </where >      </select >                <select  id ="selectDynamicSQL001"  resultMap ="brandResultMap" >          select *         from tb_brand         where         <choose >               <when  test ="status != null" >                   status = #{status}             </when >              <when  test ="companyName != null and companyName != ''" >                  company_name like #{companyName}             </when >              <when  test ="brandName != null and brandName != ''" >                  brand_name like #{brandName};             </when >              <otherwise >                   1 = 1             </otherwise >          </choose >      </select >           <select  id ="selectDynamicSQL002"  resultMap ="brandResultMap" >          select *         from tb_brand         <where >              <choose >                   <when  test ="status != null" >                       status = #{status}                 </when >                  <when  test ="companyName != null and companyName != ''" >                      company_name like #{companyName}                 </when >                  <when  test ="brandName != null and brandName != ''" >                      brand_name like #{brandName};                 </when >              </choose >          </where >      </select >           <insert  id ="addAll"  useGeneratedKeys ="true"  keyProperty ="id" >          insert into tb_brand (brand_name, company_name, ordered, description, status)         values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});     </insert >           <update  id ="updateBrand" >          update             tb_brand         set brand_name   = #{brandName},             company_name = #{companyName},             ordered      = #{ordered},             description  = #{description},             status       = #{status}         where id = #{id};     </update >           <update  id ="updateBrandDynamic" >          update         tb_brand         <set >              <if  test ="brandName != null and brandName != ''" >                  brand_name = #{brandName},             </if >              <if  test ="companyName != null and companyName != ''" >                  company_name = #{companyName},             </if >              <if  test ="ordered != null" >                  ordered = #{ordered},             </if >              <if  test ="description != null and description != ''" >                  description = #{description},             </if >              <if  test ="status != null" >                  status = #{status}             </if >          </set >          where             id = #{id};     </update >           <delete  id ="deleteById" >          delete         from tb_brand         where id = #{id};     </delete >           <delete  id ="deleteByIdAll" >          delete from tb_brand         where id         in  <foreach  collection ="ids"  item ="id"  separator =","  open ="("  close =")" >                  #{id}             </foreach >      </delete >  </mapper > 
 
 
pojo - User.java package  com.ganga.pojo;public  class  Brand  {    private  Integer id;     private  String brandName;     private  String companyName;     private  Integer ordered;     private  String description;     private  Integer status;     public  Brand ()  {     }     public  Brand (Integer id, String brandName, String companyName, Integer ordered, String description, Integer status)  {         this .id = id;         this .brandName = brandName;         this .companyName = companyName;         this .ordered = ordered;         this .description = description;         this .status = status;     }     public  Integer getId ()  {         return  id;     }     public  void  setId (Integer id)  {         this .id = id;     }     public  String getBrandName ()  {         return  brandName;     }     public  void  setBrandName (String brandName)  {         this .brandName = brandName;     }     public  String getCompanyName ()  {         return  companyName;     }     public  void  setCompanyName (String companyName)  {         this .companyName = companyName;     }     public  Integer getOrdered ()  {         return  ordered;     }     public  void  setOrdered (Integer ordered)  {         this .ordered = ordered;     }     public  String getDescription ()  {         return  description;     }     public  void  setDescription (String description)  {         this .description = description;     }     public  Integer getStatus ()  {         return  status;     }     public  void  setStatus (Integer status)  {         this .status = status;     }     @Override      public  String toString ()  {         return  "Brand{"  +                 "id="  + id +                 ", brandName='"  + brandName + '\''  +                 ", companyName='"  + companyName + '\''  +                 ", ordered="  + ordered +                 ", description='"  + description + '\''  +                 ", status="  + status +                 '}' ;     } } 
 
 
Dao层 接口:
package  com.ganga.mapper;import  com.ganga.pojo.Brand;import  org.apache.ibatis.annotations.Param;import  org.apache.ibatis.annotations.Select;import  java.util.List;import  java.util.Map;public  interface  BrandMapper  {         List<Brand> selectAll () ;          Brand selectById (int  id) ;          List<Brand> selectByOrdered () ;               List<Brand> selectByCondition1 (@Param("status")  int  status, @Param("companyName")  String companyName, @Param("brandName")  String brandName) ;     List<Brand> selectByCondition2 (Brand brand) ;     List<Brand> selectByCondition3 (Map map) ;               List<Brand> selectDynamicSQL01 (Map map) ;          List<Brand> selectDynamicSQL02 (Map map) ;          List<Brand> selectDynamicSQL03 (Map map) ;               List<Brand> selectDynamicSQL001 (Brand brand) ;     List<Brand> selectDynamicSQL002 (Brand brand) ;          int  addAll (Brand brand) ;          int  updateBrand (Brand brand) ;          int  updateBrandDynamic (Brand brand) ;               int  deleteById (int  id) ;          int  deleteByIdAll (@Param("ids") int [] ids) ;          @Select("select * from tb_brand where id = #{id}")      List<Brand> selectByIdAnnotation (int  id) ; } 
 
 
Service层 package  com.ganga.service;import  com.ganga.mapper.UserMapper;import  com.ganga.pojo.User;import  com.ganga.util.MyBatisUtils;import  org.apache.ibatis.session.SqlSession;import  org.apache.ibatis.session.SqlSessionFactory;import  java.util.List;public  class  UserService  {         private  SqlSessionFactory  factory  =          MyBatisUtils.getSqlSessionFactory();          public  User selectAll (User user) {                  SqlSession  sqlSession  =  factory.openSession();                  UserMapper  mapper  =              sqlSession.getMapper(UserMapper.class);                  User  us  =  mapper.selectAll(user);                  sqlSession.close();                  return  us;     }               public  boolean  selectByName (String name) {         SqlSession  sqlSession  =  factory.openSession();         UserMapper  mapper  =               sqlSession.getMapper(UserMapper.class);         User  user  =  mapper.selectByName(name);                  sqlSession.close();         if  (user == null ){                          return  true ;         }else {                          return  false ;         }     }          public  int  addUser (String username, String password) {         SqlSession  sqlSession  =  factory.openSession();         UserMapper  mapper  =               sqlSession.getMapper(UserMapper.class);         int  i  =  mapper.addUser(username, password);                  sqlSession.commit();                  sqlSession.close();         return  i;     } } 
 
 
Web层 package  com.ganga.web.register;import  com.ganga.service.UserService;import  javax.servlet.*;import  javax.servlet.http.*;import  javax.servlet.annotation.*;import  java.io.IOException;@WebServlet("/register") public  class  RegisterServlet  extends  HttpServlet  {	          private  UserService  userService  =  new  UserService ();     @Override      protected  void  doGet (HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {                           String  username  =  request.getParameter("username" );         String  password  =  request.getParameter("password" );         String  checkCode  =  request.getParameter("checkCode" );         System.out.println(username);         System.out.println(password);         System.out.println("p5sv" .equalsIgnoreCase(checkCode));         System.out.println(userService.selectByName(username));                  if  ("p5sv" .equalsIgnoreCase(checkCode)){                          if  (userService.selectByName(username)){                                  userService.addUser(username, password);                 request.setAttribute("register_msg" ,"注册成功, 请登录!" );                 request.getRequestDispatcher("/login.jsp" ).forward(request,response);             }else  {                                  request.setAttribute("register_msg" ,"用户名已经存在!" );                 request.getRequestDispatcher("/register.jsp" ).forward(request,response);             }         } else  {             request.setAttribute("register_msg" , "验证码错误" );             request.getRequestDispatcher("/register.jsp" ).forward(request,response);         }     }     @Override      protected  void  doPost (HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {         this .doGet(request, response);     } } 
 
 
我的踩坑必坑指南 
单词复习 
单词 
解释 
 
 
=================== 
=================== 
 
environment 
环境 
 
resource 
资源 
 
 
 
 
mapper 
映射 
 
pojo 
实体类 
 
utils 
工具 
 
 
 
 
@SqlSessionFactoryBuilder  
SQL会话工厂创建者 
 
 
 
 
@SqlSessionFactory  
SQL会话工厂 
 
@. openSession(t/f) 
获取SqlSession对象 
 
 
 
 
@SqlSession  
SQL会话 
 
@ .getMapper(#.class) 
获取Mapper代理对象 
 
 
 
 
Mapper  
 
 
namespace 
名称空间 
 
 
 
 
resultMap 
结果Map / 数据库与类的映射 
 
id=”” 
resultMap的唯一标识 
 
type=”” 
要映射的实体类 全限定名 
 
<result <id 
前者完成普通列的映射 后者时主键 
 
column=”” 
数据库列名 
 
property=”” 
映射类的属性名 
 
 
 
 
@@Param  
(@Param(“status”) int 映射参数名) 
 
 
 
 
dynamic  
动态 
 
 
 
 
<choose 
选择 -> switch 
 
<<when 
何时 -> case 
 
<<otherwise 
否则 -> default 
 
 
 
 
<foreach 
循环 
 
collection=”” 
集合 -> 要遍历的集合 
 
item=”” 
项目 -> 每个结果 
 
separator=”” 
分离 -> 每个后面要用什么分离 
 
open=”” 
打开 -> 开始时,前面要加的东西 
 
close=”” 
关闭 -> 结束时,后面要加的东西 
 
 
 
 
 
Spring整合MyBatis pom.xml <packaging > war</packaging > <dependencies >          <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-context</artifactId >          <version > 5.3.18</version >      </dependency >      <dependency >          <groupId > org.aspectj</groupId >          <artifactId > aspectjweaver</artifactId >          <version > 1.9.9.1</version >      </dependency >      <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-web</artifactId >          <version > 5.3.18</version >      </dependency >      <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-test</artifactId >          <version > 5.3.18</version >      </dependency >      <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-jdbc</artifactId >          <version > 5.3.18</version >      </dependency >           <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-webmvc</artifactId >          <version > 5.3.18</version >      </dependency >      <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-tx</artifactId >          <version > 5.3.18</version >      </dependency >           <dependency >          <groupId > org.mybatis</groupId >          <artifactId > mybatis</artifactId >          <version > 3.4.6</version >      </dependency >           <dependency >          <groupId > org.mybatis</groupId >          <artifactId > mybatis-spring</artifactId >          <version > 1.3.2</version >      </dependency >           <dependency >          <groupId > mysql</groupId >          <artifactId > mysql-connector-java</artifactId >          <version > 5.1.49</version >      </dependency >           <dependency >          <groupId > com.alibaba</groupId >          <artifactId > druid</artifactId >          <version > 1.2.8</version >      </dependency >      <dependency >          <groupId > c3p0</groupId >          <artifactId > c3p0</artifactId >          <version > 0.9.1.2</version >      </dependency >           <dependency >          <groupId > javax.servlet</groupId >          <artifactId > servlet-api</artifactId >          <version > 2.5</version >          <scope > provided</scope >      </dependency >      <dependency >          <groupId > javax.servlet.jsp</groupId >          <artifactId > javax.servlet.jsp-api</artifactId >          <version > 2.3.3</version >      </dependency >           <dependency >          <groupId > junit</groupId >          <artifactId > junit</artifactId >          <version > 4.13.1</version >      </dependency >           <dependency >          <groupId > com.fasterxml.jackson.core</groupId >          <artifactId > jackson-databind</artifactId >          <version > 2.13.2.2</version >      </dependency >      <dependency >          <groupId > com.fasterxml.jackson.core</groupId >          <artifactId > jackson-annotations</artifactId >          <version > 2.13.2</version >      </dependency >           <dependency >          <groupId > com.alibaba</groupId >          <artifactId > fastjson</artifactId >          <version > 1.2.76</version >      </dependency >           <dependency >          <groupId > commons-io</groupId >          <artifactId > commons-io</artifactId >          <version > 2.6</version >      </dependency >      <dependency >          <groupId > commons-fileupload</groupId >          <artifactId > commons-fileupload</artifactId >          <version > 1.4</version >      </dependency >           <dependency >          <groupId > org.slf4j</groupId >          <artifactId > slf4j-api</artifactId >          <version > 1.7.20</version >      </dependency >           <dependency >          <groupId > ch.qos.logback</groupId >          <artifactId > logback-classic</artifactId >          <version > 1.2.3</version >      </dependency >           <dependency >          <groupId > ch.qos.logback</groupId >          <artifactId > logback-core</artifactId >          <version > 1.2.3</version >      </dependency >  </dependencies > <build >     <resources >          <resource >              <directory > src/main/resources</directory >              <includes >                  <include > **/*.properties</include >                  <include > **/*.xml</include >              </includes >              <filtering > false</filtering >          </resource >          <resource >              <directory > src/main/java</directory >              <includes >                  <include > **/*.properties</include >                  <include > **/*.xml</include >              </includes >              <filtering > false</filtering >          </resource >      </resources >  </build > 
 
jdbc.properties jdbc.driverClass =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql:///webcase?useSSL=false&useServerPrepStmts=true jdbc.user =root jdbc.password =ganga 
 
logback.xml <?xml version="1.0"  encoding="UTF-8" ?> <configuration >          <appender  name ="Console"  class ="ch.qos.logback.core.ConsoleAppender" >          <encoder >              <pattern > [%level]  %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern >          </encoder >      </appender >      <logger  name ="com.ganga"  level ="DEBUG"  additivity ="false" >          <appender-ref  ref ="Console" />      </logger >           <root  level ="INFO" >          <appender-ref  ref ="Console" />      </root >  </configuration > 
 
mybatis-config.xml <?xml version="1.0"  encoding="UTF-8"  ?> <!DOCTYPE configuration          PUBLIC  "-//mybatis.org//DTD Config 3.0//EN"          "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration >                     	           	<typeAliases >                   <typeAlias  alias ="user"  type ="com.ganga.pojo.User" />                   <package  name ="com.ganga.pojo" />               </typeAliases >  </configuration > 
 
applicationContext.xml <?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:context ="http://www.springframework.org/schema/context"         xmlns:aop ="http://www.springframework.org/schema/aop"         xmlns:tx ="http://www.springframework.org/schema/tx"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation =                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd                " >                                                                          <context:component-scan  base-package ="com.ganga" >                   <context:exclude-filter  type ="annotation"  expression ="org.springframework.stereotype.Controller" />      </context:component-scan >           <context:annotation-config > </context:annotation-config >           <context:property-placeholder  location ="classpath:jdbc.properties" />                               <bean  id ="dataSource"  class ="com.alibaba.druid.pool.DruidDataSource" >          <property  name ="driverClassName"  value ="${jdbc.driverClass}" />          <property  name ="url"  value ="${jdbc.url}" />          <property  name ="username"  value ="${jdbc.user}" />          <property  name ="password"  value ="${jdbc.password}" />      </bean >                     <bean  id ="sqlSessionFactory"  class ="org.mybatis.spring.SqlSessionFactoryBean" >                   <property  name ="dataSource"  ref ="dataSource" > </property >                   <property  name ="configLocation"  value ="classpath:mybatis-config.xml" > </property >                   <property  name ="mapperLocations"  value ="classpath:com/ganga/mapper/*.xml" />      </bean >                     <bean  id ="userMapper"  class ="org.mybatis.spring.mapper.MapperFactoryBean" >                   <property  name ="mapperInterface"  value ="com.ganga.mapper.UserMapper"  />                   <property  name ="sqlSessionFactory"  ref ="sqlSessionFactory"  />      </bean >           <bean  id ="accountMapper"  class ="org.mybatis.spring.mapper.MapperFactoryBean" >          <property  name ="mapperInterface"  value ="com.ganga.mapper.AccountMapper" />          <property  name ="sqlSessionFactory"  ref ="sqlSessionFactory" />      </bean >                     <bean  class ="org.mybatis.spring.mapper.MapperScannerConfigurer" >          <property  name ="basePackage"  value ="com.ganga.mapper" />      </bean >                               <bean  id ="transactionManager"  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >          <property  name ="dataSource"  ref ="dataSource" />      </bean >           <tx:advice  id ="txAdvice" >          <tx:attributes >              <tx:method  name ="*" />          </tx:attributes >      </tx:advice >           <aop:config >                   <aop:advisor  advice-ref ="txAdvice"  pointcut ="execution(* com.ganga.service.impl..*.*(..))" />      </aop:config >  </beans > 
 
spring-mvc.xml <?xml version="1.0"  encoding="UTF-8" ?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:context ="http://www.springframework.org/schema/context"         xmlns:mvc ="http://www.springframework.org/schema/mvc"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation =                "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd                 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd                " >                                            <context:component-scan  base-package ="com.ganga.controller" />           <mvc:annotation-driven  conversion-service ="conversionService" />           <bean  id ="internalResourceViewResolver"  class ="org.springframework.web.servlet.view.InternalResourceViewResolver" >          <property  name ="prefix"  value ="/jsp/" />          <property  name ="suffix"  value =".jsp" />      </bean >           <mvc:default-servlet-handler />           <bean  id ="conversionService"  class ="org.springframework.context.support.ConversionServiceFactoryBean" >          <property  name ="converters" >              <list >                                   <bean  class ="com.ganga.util.DataConverter" > </bean >              </list >          </property >      </bean >                <bean  id ="multipartResolver"  class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" >                   <property  name ="maxUploadSize"  value ="40960000" />                   <property  name ="maxUploadSizePerFile"  value ="20480000" />                   <property  name ="defaultEncoding"  value ="utf-8" />      </bean >           <mvc:interceptors >          <mvc:interceptor >              <mvc:mapping  path ="/bean/*" />              <bean  class ="com.ganga.interceptor.MyInterceptor" />          </mvc:interceptor >      </mvc:interceptors >                               <bean  class ="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" >                   <property  name ="defaultErrorView"  value ="/index.jsp" />                   <property  name ="exceptionMappings" >              <map >                                   <entry  key ="java.lang.ClassCastException"  value ="/error.jsp" />                                   <entry  key ="java.lang.ArithmeticException"  value ="/error.jsp" />                                   <entry  key ="java.io.FileNotFoundException"  value ="/error.jsp" />                                   <entry  key ="java.lang.NullPointerException"  value ="/error.jsp" />                                   <entry  key ="com.ganga.exception.MyException"  value ="/error.jsp" />              </map >          </property >      </bean >           <bean  class ="com.ganga.exception.MyHandlerExceptionResolver" />  </beans > 
 
web.xml <?xml version="1.0"  encoding="UTF-8" ?> <web-app  xmlns ="http://xmlns.jcp.org/xml/ns/javaee"           xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation ="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"           version ="4.0" >                         <context-param >          <param-name > contextConfigLocation</param-name >          <param-value > classpath:applicationContext.xml</param-value >      </context-param >      <listener >          <listener-class > org.springframework.web.context.ContextLoaderListener</listener-class >      </listener >           <servlet >          <servlet-name > DispatcherServlet</servlet-name >          <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class >          <init-param >              <param-name > contextConfigLocation</param-name >              <param-value > classpath:spring-mvc.xml</param-value >          </init-param >          <load-on-startup > 1</load-on-startup >      </servlet >      <servlet-mapping >          <servlet-name > DispatcherServlet</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 > 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 >           <listener >          <listener-class > com.ganga.util.MyServletContextListener</listener-class >      </listener >  </web-app > 
 
日期转换工具 package  com.ganga.util;import  org.springframework.core.convert.converter.Converter;import  java.text.ParseException;import  java.text.SimpleDateFormat;import  java.util.Date;public  class  DataConverter  implements  Converter <String, Date> {    @Override      public  Date convert (String source)  {         SimpleDateFormat  simple  =  new  SimpleDateFormat ("yyyy-MM-dd:HH-mm-ss" );         Date  date  =  null ;         try  {             date = simple.parse(source);         } catch  (ParseException e) {             e.printStackTrace();         }         return  date;     } } 
 
修复DBCP的BUG package  com.ganga.util;import  com.mysql.jdbc.AbandonedConnectionCleanupThread;import  javax.servlet.ServletContextEvent;import  javax.servlet.ServletContextListener;import  java.sql.Driver;import  java.sql.DriverManager;import  java.sql.SQLException;import  java.util.Enumeration;public  class  MyServletContextListener  implements  ServletContextListener {    public  void  contextInitialized (ServletContextEvent servletContextEvent)  {     }     public  void  contextDestroyed (ServletContextEvent servletContextEvent)  {                  Enumeration<Driver> drivers = DriverManager.getDrivers();         Driver  driver  =  null ;         while  (drivers.hasMoreElements()) {             try  {                 driver = drivers.nextElement();                 DriverManager.deregisterDriver(driver);             } catch  (SQLException ex) {             }         }         AbandonedConnectionCleanupThread.checkedShutdown();         System.out.println(" 线程释放成功... " );     } } 
 
MyBatisUtils  – 整合后用不到 package  com.ganga.util;import  org.apache.ibatis.io.Resources;import  org.apache.ibatis.session.SqlSessionFactory;import  org.apache.ibatis.session.SqlSessionFactoryBuilder;import  java.io.IOException;import  java.io.InputStream;public  class  MyBatisUtils {    private  static  SqlSessionFactory sqlSessionFactory;     static  {         try  {                          String  resource  =  "mybatis-config.xml" ;             InputStream  inputStream  =  Resources.getResourceAsStream(resource);             sqlSessionFactory = new  SqlSessionFactoryBuilder ().build(inputStream);         } catch  (IOException e) {             e.printStackTrace();         }     }          public  static  SqlSessionFactory getSqlSessionFactory () {         return  sqlSessionFactory;     } } 
 
MyHandlerExceptionResolver package  com.ganga.exception;import  org.springframework.web.servlet.HandlerExceptionResolver;import  org.springframework.web.servlet.ModelAndView;import  javax.servlet.http.HttpServletRequest;import  javax.servlet.http.HttpServletResponse;import  java.io.FileNotFoundException;public  class  MyHandlerExceptionResolver  implements  HandlerExceptionResolver  {    @Override      public  ModelAndView resolveException (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  {         ModelAndView  mav  =  new  ModelAndView ();                  if  (ex instanceof  ClassCastException){             mav.addObject("errors" ,"类转换异常" );         }else  if  (ex instanceof  ArithmeticException){             mav.addObject("errors" ,"除0异常" );         }else  if  (ex instanceof  FileNotFoundException){             mav.addObject("errors" ,"空文件路径异常" );         }else  if  (ex instanceof  NullPointerException){             mav.addObject("errors" ,"空指针异常" );         }else  if  (ex instanceof  MyException){             mav.addObject("errors" ,"自定义异常" );         }         mav.setViewName("/errors.jsp" );         return  mav;     } }