SSM Spring_SpringMVC_MyBatis
>> 本次随笔,在于记录学习过程,便于后期快速复习, 分二阶段处理
A: 常规方式下的集成使用;
B: 真正的SSM集成使用;
-------------------------------------------------------------------------------------------------------------------
A: 常规处理
准备: 工程项目结构配置
准备: 坐标引用
1 <dependencies> 2 <!--servlet 和 jsp --> 3 <dependency> 4 <groupId>javax.servlet</groupId> 5 <artifactId>javax.servlet-api</artifactId> 6 <version>4.0.1</version> 7 <scope>provided</scope> 8 </dependency> 9 <dependency> 10 <groupId>javax.servlet</groupId> 11 <artifactId>jsp-api</artifactId> 12 <version>2.0</version> 13 </dependency> 14 <dependency> 15 <groupId>jstl</groupId> 16 <artifactId>jstl</artifactId> 17 <version>1.2</version> 18 </dependency> 19 20 <!--数据源和mybatis 相关--> 21 <dependency> 22 <groupId>mysql</groupId> 23 <artifactId>mysql-connector-java</artifactId> 24 <version>8.0.24</version> 25 </dependency> 26 <dependency> 27 <groupId>com.alibaba</groupId> 28 <artifactId>druid</artifactId> 29 <version>1.2.6</version> 30 </dependency> 31 <dependency> 32 <groupId>org.mybatis</groupId> 33 <artifactId>mybatis</artifactId> 34 <version>3.5.5</version> 35 </dependency> 36 <dependency> 37 <groupId>org.mybatis</groupId> 38 <artifactId>mybatis-spring</artifactId> 39 <version>2.0.5</version> 40 </dependency> 41 42 <!--Spring 相关--> 43 <dependency> 44 <groupId>org.springframework</groupId> 45 <artifactId>spring-context</artifactId> 46 <version>5.2.12.RELEASE</version> 47 </dependency> 48 <dependency> 49 <groupId>org.aspectj</groupId> 50 <artifactId>aspectjweaver</artifactId> 51 <version>1.9.6</version> 52 </dependency> 53 <dependency> 54 <groupId>org.springframework</groupId> 55 <artifactId>spring-jdbc</artifactId> 56 <version>5.2.10.RELEASE</version> 57 </dependency> 58 <dependency> 59 <groupId>org.springframework</groupId> 60 <artifactId>spring-tx</artifactId> 61 <version>5.2.10.RELEASE</version> 62 </dependency> 63 <dependency> 64 <groupId>org.springframework</groupId> 65 <artifactId>spring-webmvc</artifactId> 66 <version>5.2.12.RELEASE</version> 67 </dependency> 68 69 <!--其它--> 70 <dependency> 71 <groupId>junit</groupId> 72 <artifactId>junit</artifactId> 73 <version>4.12</version> 74 <scope>test</scope> 75 </dependency> 76 <dependency> 77 <groupId>org.springframework</groupId> 78 <artifactId>spring-test</artifactId> 79 <version>5.1.7.RELEASE</version> 80 </dependency> 81 </dependencies>
01. 数据库建表
1 Create Table Account( 2 id int not null primary key auto_increment, 3 name varchar(50), 4 money double(7,2) 5 )
02. POJO 对象的创建
1 public class Account { 2 private Integer id; 3 private String name; 4 private Double money; 5 6 //省略 getter 和 setter 7 }
03. 配置 mapper 接口 ( 若觉得 mapper 不太好理解,就当成 dao 接口理解)
1 public interface AccountMapper { 2 /*保存数据*/ 3 void save(Account account); 4 /*加载全部数据*/ 5 List<Account> findAll(); 6 }
04. 配置 service 接口及实现类的编写(常规方法下)
1 public interface AccountService { 2 /*保存数据*/ 3 void save(Account account); 4 /*加载全部数据*/ 5 List<Account> findAll(); 6 }
1 @Service("accountService") 2 public class AccountServiceImpl implements AccountService{ 3 4 @Override 5 public void save(Account account) { 6 try { 7 InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml"); 8 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); 9 SqlSession sqlSession = factory.openSession(true); 10 AccountMapper mapper = sqlSession.getMapper(AccountMapper.class); 11 mapper.save(account); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } 15 } 16 17 @Override 18 public List<Account> findAll() { 19 try { 20 InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml"); 21 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); 22 SqlSession sqlSession = factory.openSession(true); 23 AccountMapper mapper = sqlSession.getMapper(AccountMapper.class); 24 List<Account> accountList = mapper.findAll(); 25 return accountList; 26 } catch (IOException e) { 27 e.printStackTrace(); 28 } 29 return null; 30 } 31 }
05. 前端控制器的编写
1 @Controller 2 @RequestMapping("/account") 3 public class AccountController { 4 5 @Autowired 6 private AccountService accountService; 7 8 @RequestMapping("/save") 9 public String save(Account account){ 10 accountService.save(account); 11 return "forward:/account/findAll"; 12 } 13 14 @RequestMapping("/findAll") 15 public ModelAndView findAll(){ 16 List<Account> accountList = accountService.findAll(); 17 ModelAndView modelAndView = new ModelAndView(); 18 modelAndView.addObject("accountList",accountList); 19 modelAndView.setViewName("accountlist"); 20 return modelAndView; 21 } 22 }
06. 数据库连接参数配置 jdbc.properties
1 jdbc.driver=com.mysql.cj.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/ssm 3 jdbc.username=root 4 jdbc.password=123456
07. 日志配置文件 log4j.properties
1 ### direct log messages to stdout ### 2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender 3 log4j.appender.stdout.Target=System.out 4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 6 7 ### direct messages to file mylog.log ### 8 log4j.appender.file=org.apache.log4j.FileAppender 9 log4j.appender.file.File=D:\\Demos\\Java\\mylog.log 10 log4j.appender.file.layout=org.apache.log4j.PatternLayout 11 log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 12 13 ### set log levels - for more verbose logging change 'info' to 'debug' ### 14 15 log4j.rootLogger=all, stdout
08. mybatis 模块业务配置文件 XxxxMapper.xml (注意别名的配置)
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="club.wuyu.mapper.AccountMapper"> 6 <!--插入记录--> 7 <insert id="save" parameterType="account"> 8 insert into account values (#{id},#{name},#{money}) 9 </insert> 10 11 <!--加载数据--> 12 <select id="findAll" resultType="account"> 13 select * from account 14 </select> 15 </mapper>
09. mybatis 核心配置文件 sqlConfig.xml (名称自行决定,无格式要求) : 注意别名和mapper映射配置,可以直接配置包名,而不用一个一个配置
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!--数据库连接配置--> 7 <properties resource="jdbc.properties"/> 8 <!--别名--> 9 <typeAliases> 10 <!--<typeAlias type="club.wuyu.domain.Account" alias="account"/>--> 11 <package name="club.wuyu.domain"/> 12 </typeAliases> 13 <!--环境配置--> 14 <environments default="dev"> 15 <environment id="dev"> 16 <transactionManager type="JDBC"></transactionManager> 17 <dataSource type="POOLED"> 18 <property name="driver" value="${jdbc.driver}"/> 19 <property name="url" value="${jdbc.url}"/> 20 <property name="username" value="${jdbc.username}"/> 21 <property name="password" value="${jdbc.password}"/> 22 </dataSource> 23 </environment> 24 </environments> 25 <!--映射配置--> 26 <mappers> 27 <!--<mapper resource="club/wuyu/mapper/AccountMapper.xml"/>--> 28 <package name="club.wuyu.mapper"/> 29 </mappers> 30 </configuration>
10. Spring 配置文件 applicationContext.xml (排除了控制器的扫描)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation=" 6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 8 "> 9 10 <!--包扫描--> 11 <context:component-scan base-package="club.wuyu"> 12 <!--排除控制器的扫描--> 13 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 14 </context:component-scan> 15 16 </beans>
11. SpringMVC配置文件 sping-mvc.xml (名称自定义,无要求; )
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 10 "> 11 12 <!--包扫描--> 13 <context:component-scan base-package="club.wuyu.controller"/> 14 <!--注解驱动--> 15 <mvc:annotation-driven> 16 <!--响应编码,配置后不用在控制器上配置 produces--> 17 <!-- @RequestMapping(value = "/xxx",produces = "text/html;charset=UTF-8") --> 18 <mvc:message-converters> 19 <bean class="org.springframework.http.converter.StringHttpMessageConverter"> 20 <constructor-arg value="utf-8"/> 21 </bean> 22 </mvc:message-converters> 23 </mvc:annotation-driven> 24 <!--内部资源视图解析器--> 25 <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 26 <property name="prefix" value="/WEB-INF/pages/"/> 27 <property name="suffix" value=".jsp"/> 28 </bean> 29 <!--静态资源访问权限开放--> 30 <mvc:default-servlet-handler/> 31 32 </beans>
12. web.xml 配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 7 <!--监听器--> 8 <context-param> 9 <param-name>contextConfigLocation</param-name> 10 <param-value>classpath:applicationContext.xml</param-value> 11 </context-param> 12 <listener> 13 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 14 </listener> 15 16 <!--SpringMVC前端控制器--> 17 <servlet> 18 <servlet-name>DispatcherServlet</servlet-name> 19 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 20 <init-param> 21 <param-name>contextConfigLocation</param-name> 22 <param-value>classpath:spring-mvc.xml</param-value> 23 </init-param> 24 <load-on-startup>1</load-on-startup> 25 </servlet> 26 <servlet-mapping> 27 <servlet-name>DispatcherServlet</servlet-name> 28 <url-pattern>/</url-pattern> 29 </servlet-mapping> 30 31 <!--字符编码过滤器--> 32 <filter> 33 <filter-name>CharacterEncodingFilter</filter-name> 34 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 35 <init-param> 36 <param-name>encoding</param-name> 37 <param-value>utf-8</param-value> 38 </init-param> 39 </filter> 40 <filter-mapping> 41 <filter-name>CharacterEncodingFilter</filter-name> 42 <url-pattern>/*</url-pattern> 43 </filter-mapping> 44 45 </web-app>
---------------------------------------------------------------------------------------------
B: SSM 整合
>> 核心处理点,主要在于业务层的确 Service;
从 04. 配置 service 接口及实现类的编写 这一项中所展示的源码看,myBatis核心配置文件被多次加载,内部业务中,多数代码完全一样,区别只在于获取 mapper 以后的业务处理不同;
---------------------------------------------------------------------------------------
01. 将 SqlSessionFactory 整合到 Spring 当中去
02. 在 applicationConfig.xml 中进行配置 (让 Spring 容器可以产生 Mapper 的实现类)
1 <!--SSM整合 mapper 扫描--> 2 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 3 <!--配置基础扫描包--> 4 <property name="basePackage" value="club.wuyu.mapper"/> 5 </bean>
03. 在 applicationConfig.xml 中进行配置,事务管理增强
1 <!--声明式事务控制--> 2 <!--事务管理器--> 3 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 4 <property name="dataSource" ref="dataSource"/> 5 </bean> 6 <!--增强事务织入--> 7 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 8 <tx:attributes> 9 <!--对所有方法:增强--> 10 <tx:method name="*"/> 11 </tx:attributes> 12 </tx:advice> 13 <!--切面配置--> 14 <aop:config> 15 <!--切点表达式--> 16 <aop:pointcut id="txPointCut" expression="execution(* club.wuyu.service.impl.*.*(..))"/> 17 <!--切点配置--> 18 <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> 19 </aop:config>
04. 修改服务端实现代码
1 @Service("accountService") 2 public class AccountServiceImpl implements AccountService { 3 4 @Autowired 5 private AccountMapper accountMapper; 6 7 @Override 8 public void save(Account account) { 9 accountMapper.save(account); 10 } 11 12 @Override 13 public List<Account> findAll() { 14 List<Account> accountList = accountMapper.findAll(); 15 return accountList; 16 } 17 }
>> 整合后的 applicationConfig.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:aop="http://www.springframework.org/schema/aop" 7 xsi:schemaLocation=" 8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 11 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 12 "> 13 <!--包扫描--> 14 <context:component-scan base-package="club.wuyu"> 15 <!--排除控制器的扫描--> 16 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 17 </context:component-scan> 18 19 <!--SSM整合SqlSessionFactory--> 20 <!--加载数据库连接配置文件--> 21 <context:property-placeholder location="classpath:jdbc.properties"/> 22 <!--配置数据源--> 23 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 24 <property name="driverClassName" value="${jdbc.driver}"/> 25 <property name="url" value="${jdbc.url}"/> 26 <property name="username" value="${jdbc.username}"/> 27 <property name="password" value="${jdbc.password}"/> 28 </bean> 29 <!--配置mybatis的 SqlSessionFactory--> 30 <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 31 <property name="dataSource" ref="dataSource"/> 32 <property name="configLocation" value="classpath:sqlMapConfig.xml"/> 33 </bean> 34 35 <!--SSM整合 mapper 扫描--> 36 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 37 <!--配置基础扫描包--> 38 <property name="basePackage" value="club.wuyu.mapper"/> 39 </bean> 40 41 <!--声明式事务控制--> 42 <!--事务管理器--> 43 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 44 <property name="dataSource" ref="dataSource"/> 45 </bean> 46 <!--增强事务织入--> 47 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 48 <tx:attributes> 49 <!--对所有方法:增强--> 50 <tx:method name="*"/> 51 </tx:attributes> 52 </tx:advice> 53 <!--切面配置--> 54 <aop:config> 55 <!--切点表达式--> 56 <aop:pointcut id="txPointCut" expression="execution(* club.wuyu.service.impl.*.*(..))"/> 57 <!--切点配置--> 58 <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> 59 </aop:config> 60 61 </beans>
>> 整合后的 sqlMapConfig.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!--别名--> 7 <typeAliases> 8 <!--<typeAlias type="club.wuyu.domain.Account" alias="account"/>--> 9 <package name="club.wuyu.domain"/> 10 </typeAliases> 11 </configuration>
-----------------------------------------------------------------------------
C: 开发过程中较容易忽略而造成错误的地方
>> 01. 坐标引用,容易忽略 aspectjweaver 的引用
>> 02. 控制器函数中返回的 ModelAndView , 配置返回数据集时,容易忽略属性名称这项
* modelAndView.addObject( 属性名, 对象)
很容易直接配置成: modelAndView.addObject(对象)
>> 03. 前端页面中使用 jstl 进行遍历时,接收参数容易 缺少 ${} 配置
* <c:forEach items="${accountList}" var="account">
很容易直接配置成: <c:forEach items="accountList" var="account">
-----------------------------------------------------------------------------
D: 关闭服务时,异常的处理
>> JDBC 驱动相关异常
>> 解决方式 ( 新增监听类 DriverManagerListener 并在 web.xml 中进行配置 )
1 package club.wuyu.listener; 2 3 import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread; 4 5 import javax.servlet.ServletContextEvent; 6 import javax.servlet.ServletContextListener; 7 import java.sql.DriverManager; 8 import java.sql.SQLException; 9 10 public class DriverManagerListener implements ServletContextListener { 11 12 @Override 13 public void contextInitialized(ServletContextEvent sce) { 14 //ServletContextListener.super.contextInitialized(sce); 15 } 16 17 @Override 18 public void contextDestroyed(ServletContextEvent sce) { 19 //ServletContextListener.super.contextDestroyed(sce); 20 21 while (DriverManager.getDrivers().hasMoreElements()){ 22 try { 23 DriverManager.deregisterDriver(DriverManager.getDrivers().nextElement()); 24 } catch (SQLException e) { 25 e.printStackTrace(); 26 } 27 } 28 AbandonedConnectionCleanupThread.checkedShutdown(); 29 } 30 }
在 web.xml 中配置监听
1 <listener> 2 <listener-class>club.wuyu.listener.DriverManagerListener</listener-class> 3 </listener>
问题解决了