# 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 项目基本结构搭建 ![image-20210617141726987](img/Readme.assert/image-20210617141726987.png) ## 4. 配置Spring框架环境 ### 4.1 创建Spring核心配置文件 在`resources`目录下,创建Spring框架的核心配置文件,通常命名为`applicationContext.xml` ![image-20210617141938437](img/Readme.assert/image-20210617141938437.png) ### 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` ![image-20210617145515672](img/Readme.assert/image-20210617145515672.png) ### 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` ![image-20210617155431339](img/Readme.assert/image-20210617155431339.png) ### 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整合项目执行流程分析 ![image-20210617163524442](img/Readme.assert/image-20210617163524442.png) 项目打包成war包之后,部署在tomcat服务器中。 tomcat启动时会加载web.xml文件,web.xml文件配置了ContextLoaderListener上下文事件监听器,在ServletContext对象创建时,会触发监听器事件,读取contextConfigLocation中定义的父容器Spring的核心配置文件,自动装配ApplicationContext的配置信息,产生WebApplicationContext对象并初始化。 接着创建DispatcherServlet对象,通过init方法初始化,完成springmvc.xml关联的子容器的初始化。 springmvc子容器可以通过父容器获取bean对象(注入)。