SSM整合
步骤分析
首先来分析一下如何把Spring,SpringMVC,Mybatis整合到一起。
步骤
①Spring整合上Mybatis:通过Service层Dao层都注入Spring容器中;
②引入配置SpringMVC:把Controller层注入SpringMVC容器中
③让web项目启动时自动读取spring配置文件来创建Spring容器:可以使用ContextLoaderListener来实现Spring容器的创建。
常见疑惑
- 为什么要用两个容器?因为Controller如果不放在MVC容器中会没有效果,无法处理请求。而Service如果不放在Spring容器中,声明事务也无法使用。
- SpringMVC容器中的Controller需要依赖Service,能从Spring容器中获取到所依赖的Service对象么?Spring容器相当于父容器,MVC容器相当于是子容器。子容器除了可以使用自己容器中的对象还可以使用父容器中的对象。
- 是什么让两个容器产生这种父子容器关系的?在ContextLoaderListener中,会在创建好容器后把容器存入servletContext域。这样在DispatcgerServlet启动时,创建完SpringMVC容器后会从servletContext域中获取到Spring容器对象,设置为其父容器,这样子容器就能获取到父容器中的bean了。
准备工作
①创建web模块:在ProjectStructure中+web。将web文件夹放入main中,并改名为wabapp;并在pom文件中更改打包方式为war。
在pom中引入所有依赖
1 | <dependencies> |
数据库初始语句
1 | CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis_db` /*!40100 DEFAULT CHARACTER SET utf8 */; |
相关配置
①整合Spring和Mybatis
在resources目录下创建Spring核心配置文件:applicationContext.xml内容如下:
1 |
|
在resources目录下创建jdbc.properties文件,内容如下:
1 | jdbc:mysql://localhost:3306/mybatis_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC = |
在resources目录下创建mybatis-config.xml ,内容如下:
1 |
|
在resources目录下创建log4j.properties ,内容如下:
1 | ### direct log messages to stdout ### |
②SpringMVC引入
在resources目录下创建spring-mvc.xml,内容如下:
1 |
|
webapp中修改web.xml文件
1 |
|
③Spring整合入web项目
让web项目启动的时候就能够创建Spring容器。可以使用Spring提供的监听器ContextLoaderListener,所以我们需要在web.xml中配置这个监听器,并且配置上Spring配置文件的路径。
1 | <!--配置spring的配置文件路径--> |
编写相关Controller、Service、dao
1 | package cn.xiaohupao.controller; |
1 | package cn.xiaohupao.service; |
1 | package cn.xiaohupao.service.impl; |
1 | package cn.xiaohupao.dao; |
1 |
|
案例
响应格式统一
我们要保证一个项目中所有接口返回的数据格式的统一。这样无论是前端还是移动端开发获取到我们的数据后都能更方便的进行统一处理。
我们将定义以下结果封装类:
1 | package cn.xiaohupao.common; |
@JsonInclude(JsonInclude.Include.NON_NULL)这个注解可以将值为null的属性转换为json格式的时候不出现。
之前的Controller接口可以修改为返回封装的类型:
1 | package cn.xiaohupao.controller; |
查询所有用户
1 | package cn.xiaohupao.controller; |
1 | package cn.xiaohupao.service; |
1 | package cn.xiaohupao.service.impl; |
1 | package cn.xiaohupao.dao; |
1 | <select id="findAll" resultType="cn.xiaohupao.domain.User"> |
分页查询用户
分页查询的结果除了要包含查询到的用户数据外还要有当前页数,每页条数,总记录数这些分页数据。
分页数据封装类:
1 | package cn.xiaohupao.common; |
分页查询实现:
1 | package cn.xiaohupao.controller; |
1 | package cn.xiaohupao.service; |
1 | package cn.xiaohupao.service.impl; |
插入查询
Controller层
1 | package cn.xiaohupao.controller; |
Service层
1 | package cn.xiaohupao.service; |
Dao层
1 | package cn.xiaohupao.dao; |
Mapper映射文件
1 | <insert id="insertUser"> |
测试
1 | { |
1 | POST http://localhost:80/user |
1 | { |
删除用户
Controller层
1 | package cn.xiaohupao.controller; |
Service层
1 | package cn.xiaohupao.service; |
1 | package cn.xiaohupao.service.impl; |
Dao层
1 | package cn.xiaohupao.dao; |
Mapper映射文件
1 | <delete id="deleteUserById"> |
测试
1 | GET http://localhost:80/deleteUser/4 |
1 | { |
更新用户
Controller层
1 | package cn.xiaohupao.controller; |
Service层
1 | package cn.xiaohupao.service; |
1 | package cn.xiaohupao.service.impl; |
Dao层
1 | package cn.xiaohupao.dao; |
Mapper映射文件
1 | <update id="updateUser"> |
测试
1 | { |
1 | PUT http://localhost:80/user |
1 | { |
异常统一处理
我们可以使用@ControllerAdvice实现对异常的统一处理。让异常出现时也能返回响应一个JSON。
1 | package cn.xiaohupao.exception; |
拦截器测试
实现HandlerInterceptor接口,重写接口中的方法。在Spring-mvc中配置拦截器
1 | package cn.xiaohupao.interceptor; |
1 | <!--配置拦截器--> |
声明式事务测试
当作好相应配置时,只要在Service方法上加上@Transactional注解即可。
1 | package cn.xiaohupao.controller; |
1 | package cn.xiaohupao.service; |
1 | package cn.xiaohupao.service.impl; |
AOP测试
注意,自己去使用AOP进行增强时,应该是对Service进行增强。不能对Controller进行增强,因为切面类会被放入父容器,而我们的Controller是在子容器中的。父容器不能访问子容器。
并且我们如果需要对Controller进行增强,使用拦截器也会更加的好用。
1 | package cn.xiaohupao.aspect; |