# ssm-example
**Repository Path**: maomaochonglee/ssm-example
## Basic Information
- **Project Name**: ssm-example
- **Description**: ssm框架整合模板
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-06-17
- **Last Updated**: 2021-06-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 项目简介
此项目实现了SSM框架的简单整合,并基于整合的框架实现了对Account数据的增删改查。
# SSM框架整合
## 1. 创建maven管理的web项目
## 2. 导入ssm框架整合相关jar包坐标
所需jar包坐标如下:
```xml
5.2.0.RELEASE
3.4.5
2.9.8
org.springframework
spring-context
${spring-version}
org.mybatis
mybatis
${mybatis-version}
org.springframework
spring-jdbc
${spring-version}
org.springframework
spring-test
${spring-version}
org.springframework
spring-webmvc
${spring-version}
com.fasterxml.jackson.core
jackson-core
${jackson-version}
com.fasterxml.jackson.core
jackson-databind
${jackson-version}
com.fasterxml.jackson.core
jackson-annotations
${jackson-version}
mysql
mysql-connector-java
5.1.6
org.mybatis
mybatis-spring
1.3.0
org.aspectj
aspectjweaver
1.8.13
junit
junit
4.12
javax.servlet
javax.servlet-api
3.0.1
provided
javax.servlet
jsp-api
2.0
provided
jstl
jstl
1.2
com.alibaba
druid
1.0.13
c3p0
c3p0
0.9.1.2
org.projectlombok
lombok
1.16.20
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
utf-8
8080
/
```
## 3. 搭建基本环境
### 3.1 数据库构建
```sql
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(40) DEFAULT NULL,
`money` float DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
INSERT INTO `account` VALUES ('1', 'tom', '1000');
INSERT INTO `account` VALUES ('2', 'rose', '1000');
INSERT INTO `account` VALUES ('3', 'jack', '1000');
```
### 3.2 项目基本结构搭建

## 4. 配置Spring框架环境
### 4.1 创建Spring核心配置文件
在`resources`目录下,创建Spring框架的核心配置文件,通常命名为`applicationContext.xml`

### 4.2 编辑配置文件
开启Spring组件的包扫描,确保项目中的组件可以被框架扫描识别,成功注册到IoC容器进行管理。
配置文件编辑如下:
```xml
```
### 4.3 测试Spring框架环境
创建AccountService接口,并创建AccountServiceImpl类实现此接口,将此类注册到IoC容器中,然后模拟Controller层的调用,测试环境搭建情况。
#### 创建AccountService接口
```java
import com.maomaochongtech.pojo.Account;
import java.io.IOException;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 06:47
**/
public interface AccountService {
List findAll();
}
```
#### 创建AccountServiceImpl类
```java
import com.maomaochongtech.pojo.Account;
import com.maomaochongtech.service.AccountService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 06:48
**/
@Service
public class AccountServiceImpl implements AccountService {
@Override
public List findAll() {
Account a1 = Account.builder().id(1).name("小明").money(1000f).build();
Account a2 = Account.builder().id(2).name("小红").money(2000f).build();
return Arrays.asList(a1, a2);
}
```
#### 测试代码
```java
import com.maomaochongtech.pojo.Account;
import com.maomaochongtech.service.AccountService;
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;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 06:54
**/
//引入Spring整合JUnit
@RunWith(SpringJUnit4ClassRunner.class)
//引入Spring核心配置文件
@ContextConfiguration(locations = "classpath:applicationContext-service.xml")
public class Test01 {
@Autowired
private AccountService accountService;
/**
* 测试Spring环境搭建情况
*/
@Test
public void test1() {
List list = accountService.findAll();
for (Account account : list) {
System.out.println(account);
}
}
}
```
## 5. 配置MyBatis框架环境
### 5.1 创建MyBatis核心配置文件
在`resources`文件夹中创建MyBatis的核心配置文件,通常命名为:`mybatisConfig.xml`

### 5.2 编辑配置文件
MyBatis核心配置文件如下:
```xml
```
数据库相关参数配置在`jdbc.properties`中,同样也放置在`resources`中:
```properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://数据库服务器ip:3306/springtest
jdbc.username=root
jdbc.password=root
```
### 5.3 测试MyBatis框架环境
#### 创建DAO层接口
创建AccountDao接口,实现简单的查询。
```java
import com.maomaochongtech.pojo.Account;
import org.apache.ibatis.annotations.Param;
import java.io.IOException;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 07:12
**/
public interface AccountDao {
List findAll() throws IOException;
}
```
#### 创建sql映射文件
在resources文件夹中,创建与Dao层接口同名的sql映射文件:`AccountDao.xml`
```xml
```
#### 测试代码
```java
import com.maomaochongtech.dao.AccountDao;
import com.maomaochongtech.pojo.Account;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 07:21
**/
public class Test02 {
@Test
public void test1() throws IOException {
//读取mybatis的核心配置文件流
InputStream is = Resources.getResourceAsStream("mybatisConfig.xml");
//使用配置信息构建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//使用工厂创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//动态代理生成AccountDao的代理类
AccountDao mapper = sqlSession.getMapper(AccountDao.class);
//调用findAll方法,查询所有账户信息
List list = mapper.findAll();
for (Account account : list) {
System.out.println(account);
}
//关闭资源
sqlSession.close();
is.close();
}
}
```
### 5.4 优化事务管理,使用注解
修改applicationContext.xml,将事务管理机制和切面配置信息注释掉,然后配置开启事务的注解驱动。
```xml
```
然后在Service层,使用注解配置事务机制。
```java
@Service
//默认传播行为是required的,同时是非只读
@Transactional(propagation = Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
//假查询不需要加
public List findAll() {
Account a1 = Account.builder().id(1).name("小明").money(1000f).build();
Account a2 = Account.builder().id(2).name("小红").money(2000f).build();
return Arrays.asList(a1, a2);
}
@Override
//查询时设置为supports,且是只读事务
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public List findAccountAll() throws IOException {
List list = accountDao.findAll();
return list;
}
@Override
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public Account findAccountById(Integer id) {
Account account = accountDao.findAccountById(id);
return account;
}
@Override
public int updateAccount(String name, float money, Integer id) {
int row = accountDao.updateAccount(name, money, id);
return row;
}
@Override
public int deleteAccount(Integer id) {
int row = accountDao.deleteAccount(id);
return row;
}
@Override
public int addAccount(String name, float money) {
int row = accountDao.addAccount(name, money);
return row;
}
}
```
注意:声明式事务管理也有两种常用的方式,
- 一种是基于tx和aop名字空间的xml配置文件,
- 另一种就是基于`@Transactional`注解。显然基于注解的方式更简便和防spring侵入。
## 6. 整合Spring及MyBatis
在实现Spring框架整合MyBatis框架时,需要导入相关jar包:`mybatis-spring`,环境准备阶段已经导入相关坐标。
### 6.1 修改Spring核心配置文件
修改Spring的核心配置文件,配置整合Mybatis的相关信息。
#### 数据库连接信息
```xml
```
#### 数据源信息
```xml
```
#### 集成Mybatis工厂类信息
```xml
```
#### sql映射文件扫描器信息
```xml
```
#### 事务管理器信息
```xml
```
#### 事务管理机制
```xml
```
#### 切面信息
```xml
```
#### 完整配置实例
```xml
```
### 6.2 测试整合环境
通过Service层调用Dao层,测试Spring框架和MyBatis框架的整合情况。
#### AccountService接口
```java
import com.maomaochongtech.pojo.Account;
import java.io.IOException;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 06:47
**/
public interface AccountService {
List findAll();
//连接dao层测试
List findAccountAll() throws IOException;
}
```
#### AccountServiceImpl类
```java
import com.maomaochongtech.dao.AccountDao;
import com.maomaochongtech.pojo.Account;
import com.maomaochongtech.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 06:48
**/
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public List findAll() {
Account a1 = Account.builder().id(1).name("小明").money(1000f).build();
Account a2 = Account.builder().id(2).name("小红").money(2000f).build();
return Arrays.asList(a1, a2);
}
//调用dao层,查询所有账户
@Override
public List findAccountAll() throws IOException {
List list = accountDao.findAll();
return list;
}
}
```
#### 测试代码
```java
import com.maomaochongtech.pojo.Account;
import com.maomaochongtech.service.AccountService;
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;
import java.io.IOException;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 07:55
**/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-service.xml")
public class Test01 {
@Autowired
private AccountService accountService;
@Test
public void test1() throws IOException {
List list = accountService.findAccountAll();
for (Account account : list) {
System.out.println(account);
}
}
}
```
## 7. 配置SpringMVC框架环境
### 7.1 创建SpringMVC核心配置文件
在resources文件夹下创建SpringMVC核心配置文件,通常命名为`springmvc.xml`

### 7.2 编辑配置文件
在springmvc.xml中,配置SpringMVC框架相关参数。
```xml
```
### 7.3编辑web.xml文件
编辑`web.xml`文件,配置SpringMVC核心控制器`DispatcherServlet`。
#### 配置DispatcherServlet
```xml
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
DispatcherServlet
/
```
#### 配置编码过滤器
可以解决项目中出现的乱码问题
```xml
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
```
#### 完整示例
```xml
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
DispatcherServlet
/
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
```
### 7.4 测试SpringMVC环境
创建TestController,测试SpringMVC环境搭建情况。
```java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author maomaochong
* @date 2021/06/17 08:34
**/
@Controller
public class TestController {
@RequestMapping("/ssmtest1")
public String test1() {
System.out.println("test1 run...");
return "success";
}
}
```
## 8. 整合Spring及SpringMVC
Spring及SpringMVC的整合相对流程较为简单,通过web.xml的配置,加载Spring的核心配置文件即可。
### 8.1 修改web.xml文件
#### 配置监听器
此处配置为项目提供了spring支持,初始化了Ioc容器。
配置监听器,监听ServletContext创建时触发监听事件,读取contextConfigLocation中定义的spring的核心配置文件,自动装配ApplicationContext的配置信息,产生WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。
```xml
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
```
### 8.2 SSM整合测试
通过Controller层调用Service层,继而调动dao层,完成指定账户查询。
#### SsmController类
```java
import com.maomaochongtech.pojo.Account;
import com.maomaochongtech.pojo.Result;
import com.maomaochongtech.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
/**
* @author maomaochong
* @date 2021/06/17 09:00
**/
@Controller
@RequestMapping("/account")
public class SsmController {
@Autowired
private AccountService accountService;
@GetMapping(value = "/{id}")
@ResponseBody
public Result findAccountById(@PathVariable Integer id) {
Account account = accountService.findAccountById(id);
Result result = Result.builder().isSuccess(true).data(account).build();
System.out.println(result);
return result;
}
}
```
## 9. 框架整合优化
我们注意到,Spring的核心配置文件中,不但有Service层的相关配置,同时Dao层的相关配置也在其中,管理起来不太方便。实际开发中通常将这两部分的配置进行分离,下面我们就做一下两部分的分离优化操作。
首先将applicationContext.xml文件复制一份,重复名为applicationContext-dao.xml,在其中删除与配置Dao层无关的内容即可:
```xml
```
然后将原文件重复名为applicationContext-service.xml,删除与Service层无关的内容,即可:
```xml
```
然后需要在applicationContext-service.xml文件中引入dao层的配置文件,然后修改web.xml文件中加载的Spring核心配置文件的名称为applicationContext-service.xml,保证tomcat启动后能够正确加载它来进行Spring容器的初始化:
**组合Service层和Dao层配置文件有两种方式:**
**方式一:**
applicationContext-service.xml中引入:
```xml
```
web.xml中更新Spring核心配置文件的名称:
```xml
contextConfigLocation
classpath:applicationContext-service.xml
```
**方式二:**
不需要在Service层配置文件中引入Dao层配置文件,只需要在web.xml文件中修改读取配置文件路径的方式即可实现:
```xml
contextConfigLocation
classpath:applicationContext-*.xml
```
## 10. SSM整合项目执行流程分析

项目打包成war包之后,部署在tomcat服务器中。
tomcat启动时会加载web.xml文件,web.xml文件配置了ContextLoaderListener上下文事件监听器,在ServletContext对象创建时,会触发监听器事件,读取contextConfigLocation中定义的父容器Spring的核心配置文件,自动装配ApplicationContext的配置信息,产生WebApplicationContext对象并初始化。
接着创建DispatcherServlet对象,通过init方法初始化,完成springmvc.xml关联的子容器的初始化。
springmvc子容器可以通过父容器获取bean对象(注入)。