1 Mybatis

1.1 Mybatis是什么

  • MyBatis 是一款优秀的持久层框架,支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO为数据库中的记录。
  • 详细参考MyBatis中文官网,文档只是补充说明。

1.2 入门项目

1.2.1 创建maven工程并在pom文件中导入相关坐标

  1. <dependency>
  2. <groupId>org.mybatis</groupId>
  3. <artifactId>mybatis</artifactId>
  4. <version>x.x.x</version>
  5. </dependency>

1.2.2 构建 SqlSessionFactory

编写mybatis工具类读取mybatis核心配置文件mybatis-config.xml(一般为数据库链接等配置)

//sqlSessionFactory --> sqlSession
public class MybatisUtils {

    static SqlSessionFactory sqlSessionFactory = null;

    static {
        try {
            //使用Mybatis第一步 :获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例.
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);//默认提交事务
    }
}

1.2.3 编写持久层代码

定义Dao接口及其接口实现类 (由原来的UserDaoImpl转变为一个Mapper配置文件,这个mapper文件必须在mybatis-config.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">

<!--namespace=绑定一个指定的Dao/Mapper接口-->
<mapper namespace="com.baozi.dao.UserDao">
    <select id="getUserList" resultType="com.baozi.pojo.User">
    select * from USER
  </select>
</mapper>

1.2.4 编写测试环境

@Test
public void test(){
    //1.获取SqlSession对象
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    //2.执行SQL
    // 方式一:getMapper
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    List<User> userList = userDao.getUserList();
    for (User user : userList) {
        System.out.println(user);
    }

    //关闭sqlSessionjava
    sqlSession.close();
}

1.3 增删改查

在Mapper映射文件中编写相应的查询语句, 实例如下,编写sql语句即可

 <select id="findUserById" parameterType="int" resultType="itcast.mybatis.po.User">
        SELECT * FROM orderitems WHERE quantity=#{quantity}
  </select>
  • id:就是对应的namespace中的方法名;
  • resultType : Sql语句执行的返回值;
  • parameterType : 参数类型;

注意:增删改查一定要提交事务:sqlSession.commit(),可以在mybatis工具类获取sqlSession对象的时候默认开启

1.4 Map替换实体类

如果实体类或者数据库中的表,字段或者参数过多,应该考虑使用Map

UserMapper接口
//用Map插入用户
public void addUser(Map<String,Object> map);
UserMapper.xml
<!--对象中的属性可以直接取出来 传递map的key-->
<insert id="addUser2" parameterType="map">
    insert into user (id,name,password) values (#{userid},#{username},#{userpassword})
</insert>
测试
@Test
public void test3(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("userid",4);
    map.put("username","王虎");
    map.put("userpassword",789);
    mapper.addUser(map);java
    //提交事务
    sqlSession.commit();
    //关闭资源
    sqlSession.close();
}

1.5 mybatis-config配置解析

  • 环境配置 environments标签
    MyBatis 可以配置成适应多种环境,尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种
  • 属性 properties标签
    可以通过properties属性来实现引用配置文件
  • 类型别名 typeAliases标签
    可以指定一个类起别名,也可以指定一个包这时类的首字母小写的类名来作为它的别名

    <typeAliases>  
    <!--  <typeAlias type="zq.mybatis.test1.User" alias="_User"/> -->  
    <package name="com.how2java.pojo"/>  所在包的名字
    </typeAliases>
    
  • 设置 Settings标签
    这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为,需要调整时参考官网

  • 映射器 mappers标签
    • 接口和他的Mapper配置文件必须同名
    • 接口和他的Mapper配置文件必须在同一个包下
      <!--每一个Mapper.xml都需要在MyBatis核心配置文件中注册-->
      <mappers>
      <mapper resource="com/kuang/dao/UserMapper.xml"/>
      </mappers>
      

1.6 作用域和生命周期

Mybatis - 图1

SqlSessionFactoryBuilder

  • 一旦创建了SqlSessionFactory,就不再需要它了
  • 局部变量

SqlSessionFactory

  • 说白了就可以想象为:数据库连接池
  • SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建一个实例。
  • 因此SqlSessionFactory的最佳作用域是应用作用域(ApplocationContext)。
  • 最简单的就是使用单例模式或静态单例模式。

SqlSession:

  • 连接到连接池的一个请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
  • 用完之后需要赶紧关闭,否则资源被占用!

1.7 结果集映射 resultMap

如果数据库中的字段和实体类中的属性不一致时,需要使用resultMap进行映射

<!--结果集映射-->
<resultMap id="UserMap" type="User">
    <!--column数据库中的字段,property实体类中的属性-->
    <result column="id" property="id"></result>
    <result column="name" property="name"></result>
    <result column="pwd" property="password"></result>
</resultMap>

<select id="getUserList" resultMap="UserMap">
    select * from USER
</select>

实际上Mybatis可以相同字段自己进行映射,只要配置不同的字段即可如

不管是一对一、一对多、还是多对多都要在对应的pojo类中添加相应的属性。

1.7.1 一对多

<!--子查询 (按照查询嵌套)-->
<select id="getStudent" resultMap="StudentTeacher">
    select * from student
</select>
<resultMap id="StudentTeacher" type="student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!--复杂的属性,我们需要单独出来 对象:association 集合:collection-->
    <collection property="teacher" column="tid" javaType="teacher" select="getTeacher"/><!--延时加载-->
</resultMap>
<select id="getTeacher" resultType="teacher">
    select * from teacher where id = #{id}
</select>
=============================================================
    <!--联表查询 (按照结果嵌套)-->
    <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid , s.name sname, t.name tname
        from student s,teacher t
        where s.tid=t.id
    </select>
    <!--结果封装,将查询出来的列封装到对象属性中-->
    <resultMap id="StudentTeacher2" type="student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="teacher">
            <result property="name" column="tname"></result>
        </association>
    </resultMap>

1.7.2 多对一

<!--按结果嵌套查询-->
<select id="getTeacher" resultMap="StudentTeacher">
    SELECT s.id sid, s.name sname,t.name tname,t.id tid FROM student s, teacher t
    WHERE s.tid = t.id AND tid = #{tid}
</select>
<resultMap id="StudentTeacher" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--复杂的属性,我们需要单独处理 对象:association 集合:collection
    javaType=""指定属性的类型!
    集合中的泛型信息,我们使用ofType获取
    -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

1.7.3 多对多

  • 数据库存在两张表及其关联的中间表
  • 建立两个实体类,各自包含对方的一个集合引用
  • 建立两个对应的mapper查询文件,当查询一方的时候可以用获得另一方的所属信息)——

1.7.4 小结

  • 关联 - association 【多对一】
  • 集合 - collection 【一对多】
  • javaType & ofType
    • JavaType用来指定实体类中的类型
    • ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型

1.8 分页

1.8.1 使用Limit分页

接口

//分页
List<User> getUserByLimit(Map<String,Integer> map);
Mapper.xml

Mapper.xml

<!--分页查询-->
<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
    select * from user limit #{startIndex},#{pageSize}
</select>

测试

@Test
public void getUserByLimit(){
    SqlSession sqlSession = MybatisUtils.getSqlSessiojavan();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("startIndex",1);
    map.put("pageSize",2);
    List<User> list = mapper.getUserByLimit(map);
    for (User user : list) {
        System.out.println(user);
    }
}

1.8.2 RowBounds分页

定义接口方法getUserByRowBounds同上

public void getUserByRowBounds(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    //RowBounds实现
    RowBounds rowBounds = new RowBounds(1, 2);
    //通过Java代码层面实现分页
    List<User> userList = sqlSession.selectList("com.kaung.dao.UserMapper.getUserByRowBounds", null, rowBounds);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

1.8.3 分页插件

MyBatis 分页插件 PageHelperhttps://pagehelper.github.io

1.9 注解开发

1.9.1 实例

注解在接口上实现

@Select("select * from user")
List<User> getUsers();

需要在核心配置文件中绑定接口(重点)

- <mappers>
      <mapper class="com.kuang.dao.UserMapper"/>
  </mappers>

1.9.2 关于@Param( )注解

@Select("select * from user where id =#{id}")
List<User> getUsers(@Param(”id“) int id);
  • 基本类型的参数或者String类型,需要加上,引用类型不需要加
  • 我们在SQL中引用的就是我们这里的@Param()中设定的属性

1.10 动态sql

动态SQL就是根据不同的条件生成不同的SQL语句

1.10.1 条件判断

<if test="title!=null">
    and title = #{title}
</if>

1.10.2 分支判断

<choose>
    <when test="title != null">
        AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
        AND author_name like #{author.name}
    </when>
    <otherwise>
        AND featured = 1
    </otherwise>
</choose>

1.10.3 防止sql拼接出错

  <where>
    <if test="state != null">
         state = #{state}
    </if>
      <!-- 当第一个条件没有的时候,where自动去除AND,set自动去除",",trim自定义-->
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>

1.10.4 集合进行遍历

  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>

1.10.5 sql片段

  • 最好基于单表来定义SQL片段
  • 不要存在where标签
<!-- 使用SQL标签抽取公共部分-->
<sql id="if-title-author">
    <if test="title!=null">
        title = #{title}
    </if>
    <if test="author!=null">
        and author = #{author}
    </if>
</sql>
<!-- 使用Include标签引用-->
<select id="queryBlogIF" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <include refid="if-title-author"></include>
    </where>
</select>

1.11 MyBatis缓存

MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存。默认情况下,只有一级缓存开启二级缓存需要手动开启和配置,他是基于namespace级别的缓存。为了提高可扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来定义二级缓存。

Mybatis - 图2

1.11.1 一级缓存

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中
  • 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
  • 缓存失效
    • 查询不同的东西
    • 增删改操作,可能会改变原来的数据,所以必定会刷新缓存
    • 查询不同的Mapper.xml
    • 手动清理缓存 sqlSession.clearCache()

1.11.2 二级缓存

二级缓存也叫全局缓存,基于namespace级别(一个mapper文件)的缓存,一个名称空间,对应一个二级缓存 工作机制 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中,如果会话关闭了,这个会员对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中新的会话查询信息,就可以从二级缓存中获取内容。 二级缓存需要手动开启和配置

开启全局缓存

<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>

在Mapper.xml中使用二级缓存

<!--在当前Mapper.xml中使用二级缓存,可以配置属性-->
<cache/>

1.12 MyBatis Plus

MyBatis Plus官网

1.12.1 入门项目步骤

1、创建数据库 mybatis_plus 创建user表

2、使用SpringBoot创建项目导入依赖,不要同时导入 mybatis 和 mybatis-plus

3、配置数据库连接源, 配置日志等

# 配置日志 
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

4、传统方式pojo-dao(配置mapper.xml文件)-service-controller

    使用MyBatis Plus后直接在mapper接口上注解开发
// 在对应的Mapper上面继承基本的类 BaseMapper 
@Repository // 代表持久层 
public interface UserMapper extends BaseMapper<User> { 
    // 所有的CRUD操作都已经编写完成了 
    // 你不需要像以前的配置一大堆文件了! 
}

5、在主启动类上去开启@MapperScan(“com.kuang.mapper”)扫描mapper包下的所有接口

1.12.2 主键生成策略

通过设置@TableId(type = IdType.AUTO) 可以让Mybatis-plus自动为我们生成雪花算法的ID号,参数类型为自增

1.12.3 自动填充功能

当操作实体的时候,某些字段需要自动填充,例如创建时间、修改时间。

数据库级别

在数据库表中新增字段 create_time, update_time,并设置其默认属性即可

代码级别(MP实现,参考官方文档)

  • 实体字段注解填充@TableField(.. fill = FieldFill.INSERT)

    @TableField(fill = FieldFill.INSERT) 
    private Date createTime; 
    @TableField(fill = FieldFill.INSERT_UPDATE) 
    private Date updateTime;
    
  • 自定义实现类 MyMetaObjectHandler

1.12.4 乐观锁

乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试。 悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

使用方式:

  • 数据库中增加version字段
  • 实体类加对应的字段

    @Version //乐观锁Version注解
    private Integer version;
    
  • 注册乐观锁组件

    // 扫描我们的 mapper 文件夹 
    @MapperScan("com.kuang.mapper") 
    @EnableTransactionManagement 
    @Configuration // 配置类 
    public class MyBatisPlusConfig { 
      // 注册乐观锁插件 
      @Bean 
      public OptimisticLockerInterceptor optimisticLockerInterceptor() { 
          return new OptimisticLockerInterceptor(); 
      } 
    }
    

1.12.5 CRUD

// 测试查询 
@Test 
public void testSelectById(){ 
User user = userMapper.selectById(1L); 
    System.out.println(user); 
}
// 测试批量查询! 
@Test 
public void testSelectByBatchId(){ 
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); 
    users.forEach(System.out::println); 
}
// 按条件查询之一使用map操作 
@Test public void testSelectByBatchIds(){
    HashMap<String, Object> map = new HashMap<>();
    // 自定义要查询 
    map.put("name","狂神说Java"); 
    map.put("age",3);
    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

// 测试删除 
@Test public void testDeleteById(){ 
    userMapper.deleteById(1240620674645544965L); 
}
// 通过id批量删除 
@Test public void testDeleteBatchId(){ userMapper.deleteBatchIds(Arrays.asList(1240620674645544961L,124062067464554496 2L)); 
                                     }
// 通过map删除 
@Test public void testDeleteMap(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","狂神说Java");
    userMapper.deleteByMap(map);
}

1.12.6 分页查询

  • 配置拦截器组件

    // 分页插件 
    @Bean 
    public PaginationInterceptor paginationInterceptor() { 
    return new PaginationInterceptor(); 
    }
    
  • 使用Page对象

    // 测试分页查询 
    @Test public void testPage(){ 
      // 参数一:当前页 // 参数二:页面大小 
      Page<User> page = new Page<>(2,5); userMapper.selectPage(page,null);
      page.getRecords().forEach(System.out::println);
      System.out.println(page.getTotal()); 
    }
    

1.12.7 逻辑删除

物理删除 :从数据库中直接移除 逻辑删除 :再数据库中没有被移除,而是通过一个变量来让他失效! deleted = 0 => deleted = 1

1.12.8 条件构造器-Wrapper

复杂查询可以使用条件构造器

@Test void contextLoads() { 
    // 查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12 
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.isNotNull("name") 
        .isNotNull("email") 
        .ge("age",12);
    userMapper.selectList(wrapper).forEach(System.out::println);
}

1.13 MyBatis批量插入

方案:
1.开启批处理:for循环一条条插入
优点:JDBC中的预编译功能有缓存功能后面SQL执行比较快
缺点:如果应用服务器和数据库服务器不是同一台,需要考虑IO时间
2.拼接一条插入sql :insert into 表名(字段1,字段2) values(‘aa’,’bb’),(‘cc’,’dd’)…
优点:只会有一次网络IO连接
缺点:生成的sql太长,需要修改数据库的设置;太长的sql,数据库的解析器解析时间也会变长
最佳实践:

  1. 数据库连接参数加上&rewriteBatchedStatements=true (核心步骤:MySQL JDBC 驱动在默认情况下会无视executeBatch() 语句,把我们期望批量执行的一组语句拆散,一条一条地发给数据库,批量插入实际上是单条插入)
  2. 使用原生代码或者MP的savebatch方法 ```sql // 开启批处理模式(BATCH),这样只会使用一个SqlSession SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH); UserMapper um = session.getMapper(UserMapper.class); //循环执行插入 …

session.commit();


<a name="e4b48eb8"></a>
## 4.SSM整合
<a name="677592ba"></a>
### 4.1 基本环境搭建

1. 新建一Maven项目,添加web的支持,导入相关的pom依赖
1. 建立基本结构和配置框架
   - com.kuang.pojo
   - com.kuang.dao
   - com.kuang.service
   - com.kuang.controller
   - mybatis-config.xml
   - applicationContext.xml
<a name="860891c9"></a>
### 4.2 Mybatis层编写

<a name="b1d21a36"></a>
##### (1)编写MyBatis的核心配置文件

```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>
       <package name="com.kuang.pojo"/>
   </typeAliases>
   <mappers>
       <mapper resource="com/kuang/dao/BookMapper.xml"/>
   </mappers>

</configuration>

(2)编写数据库对应的实体类

(3)编写Dao层的 Mapper接口和对应的 Mapper.xml 文件

(4)编写Service层的接口和实现类

4.3 spring层编写

(1)配置Spring整合MyBatis,编写Spring整合Mybatis的相关的配置文件- spring-dao.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"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

   <!-- 配置整合mybatis -->
   <!-- 1.关联数据库文件 -->
   <context:property-placeholder location="classpath:database.properties"/>

   <!-- 2.数据库连接池 -->
   <!--数据库连接池
       dbcp 半自动化操作 不能自动连接
       c3p0 自动化操作(自动的加载配置文件 并且设置到对象里面)
   -->
   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <!-- 配置连接池属性 -->
       <property name="driverClass" value="${jdbc.driver}"/>
       <property name="jdbcUrl" value="${jdbc.url}"/>
       <property name="user" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>

       <!-- c3p0连接池的私有属性 -->
       <property name="maxPoolSize" value="30"/>
       <property name="minPoolSize" value="10"/>
       <!-- 关闭连接后不自动commit -->
       <property name="autoCommitOnClose" value="false"/>
       <!-- 获取连接超时时间 -->
       <property name="checkoutTimeout" value="10000"/>
       <!-- 当获取连接失败重试次数 -->
       <property name="acquireRetryAttempts" value="2"/>
   </bean>

   <!-- 3.配置SqlSessionFactory对象 -->
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <!-- 注入数据库连接池 -->
       <property name="dataSource" ref="dataSource"/>
       <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
       <property name="configLocation" value="classpath:mybatis-config.xml"/>
   </bean>

   <!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
   <!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <!-- 注入sqlSessionFactory -->
       <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
       <!-- 给出需要扫描Dao接口包 -->
       <property name="basePackage" value="com.kuang.dao"/>
   </bean>
</beans>

(2)Spring整合service层相关的配置文件- spring-service.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"
      xmlns:context="http://www.springframework.org/schema/context"
      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">

   <!-- 扫描service相关的bean -->
   <context:component-scan base-package="com.kuang.service" />

   <!--BookServiceImpl注入到IOC容器中-->
   <bean id="BookServiceImpl" class="com.kuang.service.BookServiceImpl">
       <property name="bookMapper" ref="bookMapper"/>
   </bean>

   <!-- 配置事务管理器 -->
   <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!-- 注入数据库连接池 -->
       <property name="dataSource" ref="dataSource" />
   </bean>

</beans>

4.4 springMVC层编写

(1)编写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">

   <!--DispatcherServlet-->
   <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:applicationContext.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>

   <!--encodingFilter-->
   <filter>
       <filter-name>encodingFilter</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>encodingFilter</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

   <!--Session过期时间-->
   <session-config>
       <session-timeout>15</session-timeout>
   </session-config>
</web-app>

(2)Spring整合MCV层相关的配置文件- spring-mvc.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"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      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
   https://www.springframework.org/schema/mvc/spring-mvc.xsd">

   <!-- 配置SpringMVC -->
   <!-- 1.开启SpringMVC注解驱动 -->
   <mvc:annotation-driven />
   <!-- 2.静态资源默认servlet配置-->
   <mvc:default-servlet-handler/>

   <!-- 3.配置jsp 显示ViewResolver视图解析器 -->
   <beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="viewClass"value="org.springframework.web.servlet.view.JstlView" />
       <property name="prefix" value="/WEB-INF/jsp/" />
       <property name="suffix" value=".jsp" />
   </bean>

   <!-- 4.扫描web相关的bean -->
   <context:component-scan base-package="com.kuang.controller" />
</beans>

(3)Spring配置整合文件,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">

   <import resource="spring-dao.xml"/>
   <import resource="spring-service.xml"/>
   <import resource="spring-mvc.xml"/>

</beans>