一.概述
SSM框架式Spring,SpringMVC和MyBatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,Controller层,Service层和Dao层四层。使用Spring实现业务对象管理,使用SpringMVC负责请求的转发和视图管理,MyBatis作为数据对象的持久化引擎。
- Dao层(mapper):数据持久层
(1) Dao层的设计就是先设计Dao的接口
(2)在SpringMVC的映射文件中定义此接口的实现类
(3)然后可以在模块调用此接口来进行业务的处理,而不用关系此接口的具体实现类是哪个类,显得结构非常清晰。
(4)Dao层的数据源配置,以及所有的数据库连接都在Spring配置文件中进行配置
- Service层:负责业务模块的逻辑应用设计
(1)可以使用注解将Service加入到IOC容器中
(2)Service层的业务实现,具体要调用到已经定义的Dao层的接口
- Controller层:具体的业务模块流程的控制
(1)在此层中要调用Service层的接口来控制业务逻辑
二.整合步骤
1.导包
(1)Spring
//AOP核心
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
//IOC核心
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
//JDBC核心
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
//测试
spring-test-4.0.0.RELEASE.jar
(2)SpringMVC
//SpringMVC核心
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
//上传下载
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
//JSTL:JSP标准标签库
jstl.jar
standard.jar
//数据校验
hibernate-validator-5.0.0.CR2.jar
hibernate-validator-annotation-processor-5.0.0.CR2.jar
classmate-0.8.0.jar
jboss-logging-3.1.1.GA.jar
validation-api-1.1.0.CR1.jar
//Ajax
jackson-core-2.1.5.jar
jackson-databind-2.1.5.jar
jboss-logging-3.1.1.GA.jar
(3)MyBatis
//MyBatis核心
mybatis-3.4.1.jar
//ehcache整合
ehcache-core-2.6.8.jar
log4j-1.2.17.jar
mybatis-ehcache-1.0.3.jar
slf4j-api-1.7.21.jar
slf4j-log4j12-1.7.21.jar
(4)其他包
//数据源,驱动
mysql-connector-java-8.0.18.jar
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.11.jar
2.写配置
(1)web.xml配置
①配置Spring容器启动;
②配置SpringMVC前端控制器;
③配置字符编码过滤器;
④支持REST风格的过滤器。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SSM</display-name>
<!-- 配置Spring容器启动 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- 指定Spring配置文件位置 -->
<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置SpringMVC的前端控制器 -->
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 支持REST风格的过滤器 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
(2)Spring配置:
①组件扫描
②数据源配置,之前记得导入数据源配置文件dbconfig.properties
③ 配置MyBatis操作数据库(之前配置的JdbcTemplate不再被使用),这个步骤到后面第五步整合会补上
④配置事务控制器,让它控制数据源连接的关闭与提交
⑤开启基于注解的事务,写切入点表达式和事务建议
⑥配置事务建议,在其中配置事务属性,例如需要切入的方法
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 除了控制器不扫描,剩下的业务逻辑组件都需要,包括service,dao -->
<context:component-scan base-package="com.test">
<!-- 扫描排除 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 导入外部配置文件 -->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<!-- 2.配置数据源 -->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcurl}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
</bean>
<!-- 3.配置JdbcTemplate操作数据库 pass -->
<!-- 3.配置MyBatis操作数据库 -->
<!-- 4.配置事务控制,配置事务管理器,让她控制数据源里面的连接的关闭和提交 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--5.开启基于注解的事务:哪些方法切入事务,还要写切入点表达式 -->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut expression="execution(* com.test.service.*.*(..))" id="txPoint"/>
<aop:advisor advice-ref="mytx" pointcut-ref="txPoint"/>
</aop:config>
<!-- 6.配置事务建议
transaction-manager="transManager:指定要配置的事务管理器的id
-->
<tx:advice id="mytx" transaction-manager="transManager">
<!-- 配置事务属性 -->
<tx:attributes>
<tx:method name="*" rollback-for="java.lang.Exception"/>
<tx:method name="insert*"/>
</tx:attributes>
</tx:advice>
</beans>
(3)SpringMVC配置:
①扫描组件
②配置视图解析器
③配置文件上传解析器
④扫描静态资源
⑤扫描动态资源
<?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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
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-4.0.xsd">
<!-- SpringMVC只扫描控制器 ,禁用默认的规则-->
<context:component-scan base-package="com.test" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix" value=".jsp"></property>
<property name="prefix" value="/WEB-INF/pages"></property>
</bean>
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxInMemorySize" value="#{1024*1024*20}"></property>
</bean>
<!-- 扫描静态资源 -->
<mvc:default-servlet-handler/>
<!-- 扫描动态资源 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
(4)MyBatis配置:
①MyBaits全局配置文件:
<?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>
<!-- settings -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启属性按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 开启全局缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
②MyBatis映射文件(假设有Dao层文件):
<?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.test.dao.TeacherDao">
<!--其中有Sql标签和resultMap自定义封装规则-->
</mapper>
(5)最重要的整合步骤(Spring+MyBatis):
①导入整合包
mybatis-spring-1.3.0.jar
②之前整合Spring和SpringMVC时,是加注解将Dao层加入到IOC容器中,现在的Dao层中的文件是一个接口,不能使用注解将其加入到容器中。而且这个Dao层和Dao层的映射文件是由MyBatis负责的。这个整合就是Spring配置中的③ 配置MyBatis操作数据库。
根据MyBatis全局配置文件得到SqlSessionFactory(这个会获得SqlSession),然后指定映射文件的位置。最后一定要将每一个Dao接口的实现加入到容器中。
<!-- 可以根据配置文件得到SqlSessionFactory -->
<bean id="" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置文件位置 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
<property name="dataSource" ref="dataSource"></property>
<!-- 指定xml映射文件的位置 -->
<property name="mapperLocations" value="classpath:/mybatis/mapper/*.xml"></property>
</bean>
<!-- 要把每一个dao接口的实现加入到IOC容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定dao接口所在的包 -->
<property name="basePackage" value="com.test.dao"></property>
</bean>
(6)其他框架的配置,例如之前学习的第三方缓存EhCache 。
3.测试
三.实验:发送一个请求查询数据库的一个数据显示到页面
项目结构如下:
1.实体类:定义对象属性,参照数据库中表的字段来设置
package com.test.bean;
import java.util.Date;
public class Teacher {
private Integer id;
private String name;
private String course;
private String address;
private Date birth;
@Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + ", course=" + course
+ ", address=" + address + ", birth=" + birth + "]";
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
}
2.Dao层接口:
package com.test.dao;
import com.test.bean.Teacher;
public interface TeacherDao {
public Teacher getTeacherByID(Integer id);
}
3.Service层:
package com.test.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.test.bean.Teacher;
import com.test.dao.TeacherDao;
@Service
public class TeacherService {
@Autowired
private TeacherDao teacherDao;
public Teacher getTeacher(Integer id){
return teacherDao.getTeacherByID(id);
}
}
Controller层:
package com.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.test.bean.Teacher;
import com.test.service.TeacherService;
@Controller
public class TeacherController {
@Autowired
TeacherService teacherSerice;
@RequestMapping("/getTeacher")
public String getTeacher(@RequestParam(value="id",defaultValue="1")Integer id,Model model){
Teacher teacher=teacherSerice.getTeacher(id);
model.addAttribute("teacher", teacher);
return "success";
}
}
web.xml,Spring配置文件,SpringMVC配置文件,MyBatis全局配置文件和上面的配置是一样的,不同的是MyBatis映射文件:
<?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.test.dao.TeacherDao">
<resultMap type="com.test.bean.Teacher" id="teacherMap">
<id property="id" column="id"/>
<result property="address" column="address"/>
<result property="course" column="class_name"/>
<result property="name" column="teaname"/>
<result property="birth" column="birthdate"/>
</resultMap>
<!-- public Teacher getTeacherByID(Integer id); -->
<select id="getTeacherByID" resultMap="teacherMap">
select * from t_teacher where id=#{id}
</select>
</mapper>
页面发送请求:
<a href="getTeacher?id=1">查询成功显示</a>
显示页面为: