SSM 框架(Spring + SpringMVC + MyBatis)是 Java EE 开发中常用的企业级解决方案,三者各司其职:Spring 负责核心的依赖注入和事务管理,SpringMVC 处理 Web 层请求,MyBatis 简化数据库操作。本文将详细介绍如何通过 “XML + 注解” 的方式整合 SSM 框架,从环境搭建到完整功能实现,一步步带你掌握整合精髓。
一、整合环境搭建
1. 整合说明与思路
- 整合方式:采用 XML 配置文件 + 注解结合的方式,兼顾灵活性和开发效率。
- 核心思路:
- 先搭建 Spring 基础环境;
- 再整合 SpringMVC,实现 Web 层与业务层的交互;
- 最后整合 MyBatis,完成业务层与数据层的对接。
2. 数据库与表结构
首先创建用于测试的数据库和表,以 “账户管理” 为例:
-- 创建数据库
create database ssm;
-- 创建账户表
create table account(
id int primary key auto_increment,
name varchar(20),
money double
);
3. Maven 工程配置
创建 Maven Web 工程,在pom.xml
中引入所需依赖,包括 Spring、SpringMVC、MyBatis、数据库驱动、日志等:
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<mysql.version>5.1.6</mysql.version>
<mybatis.version>3.4.5</mybatis.version>
</properties>
<dependencies>
<!-- Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- MyBatis及整合依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version> <!-- 德鲁伊连接池 -->
</dependency>
<!-- Web相关 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 编译配置 -->
<build>
<finalName>ssm</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
4. 实体类编写
在ssm_domain
模块中创建账户实体类Account
,封装数据:
package cn.tx.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id; // 主键
private String name; // 账户名称
private Double money; // 金额
// Getter、Setter与toString方法
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 Double getMoney() { return money; }
public void setMoney(Double money) { this.money = money; }
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
二、Spring 框架基础配置
Spring 是整合的核心,负责管理 Service、Dao 等对象的依赖注入。
1. Spring 配置文件(applicationContext.xml)
创建applicationContext.xml
,开启 Service 层的注解扫描:
<?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层注解(@Service) -->
<context:component-scan base-package="cn.tx.service"></context:component-scan>
</beans>
2. 编写 Service 层并测试
-
Service 接口:定义核心业务方法
package cn.tx.service; import cn.tx.domain.Account; import java.util.List; public interface AccountService { List<Account> findAll(); // 查询所有账户 void save(Account account); // 新增账户 }
-
Service 实现类:使用
@Service
注解交由 Spring 管理package cn.tx.service.Impl; import cn.tx.domain.Account; import cn.tx.mapper.AccountMapper; import cn.tx.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class AccountServiceImpl implements AccountService { @Autowired // 后续会注入Mapper private AccountMapper accountMapper; @Override public List<Account> findAll() { System.out.println("业务层:查询所有账户"); return accountMapper.findAll(); } @Override public void save(Account account) { accountMapper.save(account); } }
-
测试 Spring 环境:通过 Junit 测试 Spring 是否能正常加载 Service
package cn.tx.test; import cn.tx.service.AccountService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring { @Test public void testSpring() { // 加载Spring配置文件 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取Service对象 AccountService service = ac.getBean(AccountService.class); // 调用方法(此时Mapper未注入,仅测试Spring加载) service.findAll(); } }
三、Spring 整合 SpringMVC
目标:实现 Web 层(Controller)对业务层(Service)的调用,即 Controller 中能注入 Service 对象。
1. SpringMVC 配置
(1)配置前端控制器(web.xml)
在web.xml
中配置DispatcherServlet
,指定 SpringMVC 配置文件:
<!-- 前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载SpringMVC配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup> <!-- 启动时加载 -->
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern> <!-- 拦截.do结尾的请求 -->
</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>
(2)SpringMVC 核心配置(springmvc.xml)
创建springmvc.xml
,配置注解扫描(Controller)、视图解析器等:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描Controller层注解 -->
<context:component-scan base-package="cn.tx.controller"></context:component-scan>
<!-- 视图解析器:指定JSP路径前缀和后缀 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/" /> <!-- JSP存放路径 -->
<property name="suffix" value=".jsp" /> <!-- 后缀 -->
</bean>
<!-- 开启SpringMVC注解支持(如@RequestMapping) -->
<mvc:annotation-driven />
</beans>
2. 测试 SpringMVC 单独工作
(1)编写 Controller
创建AccountController
,处理页面请求:
package cn.tx.controller;
import cn.tx.domain.Account;
import cn.tx.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
@RequestMapping("/account") // 父路径
public class AccountController {
@Autowired // 注入Service(整合核心)
private AccountService accountService;
// 查询所有账户
@RequestMapping("/findAll.do")
public ModelAndView findAll() {
System.out.println("表现层:查询所有账户");
List<Account> list = accountService.findAll();
ModelAndView mv = new ModelAndView();
mv.setViewName("suc"); // 跳转至成功页面
return mv;
}
// 新增账户
@RequestMapping("/save.do")
public String save(Account account) {
accountService.save(account);
return "suc"; // 跳转至成功页面
}
}
(2)编写页面
-
首页(index.jsp):提供查询和新增入口
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <h3>账户管理</h3> <a href="/account/findAll.do">查询所有账户</a> <form action="/account/save.do" method="post"> <h3>新增账户</h3> 姓名:<input type="text" name="name"><br> 金额:<input type="text" name="money"><br> <input type="submit" value="保存"> </form> </body> </html>
-
成功页(pages/suc.jsp):操作成功后跳转
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <h1>操作成功!</h1> </body> </html>
3. 整合核心:让 Spring 与 SpringMVC 共享容器
SpringMVC 的容器是 Spring 容器的子容器,需确保 Spring 容器在项目启动时加载,才能让 Controller 注入 Service。
在web.xml
中配置 Spring 监听器,指定 Spring 配置文件路径:
原理:监听器在项目启动时加载applicationContext.xml
,初始化 Spring 容器;SpringMVC 容器启动时会作为子容器,可访问父容器(Spring)中的 Bean(如 Service),因此 Controller 能注入 Service。
四、Spring 整合 MyBatis
目标:让 Spring 管理 MyBatis 的核心对象(如SqlSession
、Mapper
),实现 Service 对 Mapper 的调用。
1. MyBatis 配置(整合前准备)
(1)编写 Mapper 接口与映射文件
-
Mapper 接口:
AccountMapper
(数据访问层)package cn.tx.mapper; import cn.tx.domain.Account; import org.apache.ibatis.annotations.Insert; import org.springframework.stereotype.Repository; import java.util.List; @Repository // 标识为数据访问层组件 public interface AccountMapper { List<Account> findAll(); // 查询所有 @Insert("insert into account (name, money) values (#{name}, #{money})") void save(Account account); // 新增(注解方式,也可XML配置) }
-
XML 映射文件(AccountMapper.xml):放在
classpath:mapper/
目录下<?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="cn.tx.mapper.AccountMapper"> <!-- 对应Mapper接口全类名 --> <!-- 查询所有账户 --> <select id="findAll" resultType="cn.tx.domain.Account"> select * from account </select> </mapper>
2. 整合到 Spring(核心配置)
修改applicationContext.xml
,添加数据源、MyBatis 整合配置和事务管理:
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描所有组件(Service、Mapper等) -->
<context:component-scan base-package="cn.tx"/>
<!-- 1. 配置德鲁伊连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <!-- 新版驱动 -->
<property name="url" value="jdbc:mysql://localhost:3306/ssm?useSSL=false&serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!-- 2. 配置SqlSessionFactory(MyBatis核心) -->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> <!-- 关联数据源 -->
<property name="mapperLocations" value="classpath:mapper/*.xml" /> <!-- 加载Mapper映射文件 -->
<property name="typeAliasesPackage" value="cn.tx.domain" /> <!-- 实体类别名包(简化映射文件) -->
</bean>
<!-- 3. 扫描Mapper接口,生成代理对象(交由Spring管理) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sessionFactory" /> <!-- 关联SqlSessionFactory -->
<property name="basePackage" value="cn.tx.mapper" /> <!-- Mapper接口所在包 -->
</bean>
<!-- 4. 事务管理 -->
<!-- 平台事务管理器 -->
<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="find*" read-only="true" /> <!-- 查询方法只读 -->
<tx:method name="*" propagation="REQUIRED" /> <!-- 其他方法需要事务 -->
</tx:attributes>
</tx:advice>
<!-- AOP织入事务 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.tx.service.*Impl.*(..))" />
</aop:config>
</beans>
2. 整合测试
部署项目到 Tomcat,访问http://localhost:8080/ssm/index.jsp
:
- 点击 “查询所有账户”:Controller 调用 Service,Service 调用 Mapper,最终从数据库查询数据并跳转至成功页;
- 填写表单提交:数据通过 Controller→Service→Mapper 保存到数据库,完成新增功能。
五、总结
SSM 整合的核心是职责分离与依赖注入:
- Spring:管理所有 Bean(Service、Mapper、事务),通过依赖注入解耦;
- SpringMVC:处理 Web 请求,通过 Spring 容器获取 Service;
- MyBatis:简化数据库操作,通过 Spring 管理核心对象,无需手动创建
SqlSession
。
本文通过 “环境搭建→Spring→SpringMVC 整合→MyBatis 整合” 的步骤,实现了完整的账户查询与新增功能。关键配置包括各框架的 XML 文件、依赖管理和包扫描,开发者可根据实际需求扩展更多功能(如分页、复杂查询等)。
你的实现代码在细节上做了优化(如使用sqlSessionFactoryBeanName
避免配置顺序问题、调整包结构),更符合实际开发规范,值得参考!