SSM 整合
1.整合问题
-
需要几个IOC 容器?
常见操作是创建两个 ioc容器,web容器和 root容器
-
每个容器装那些组件?
容器名 盛放组件 web 容器 web相关组件(controller、springmvc核心组件) root 容器 业务和持久层相关组件(service、aop、tx、dataSource、mybatis、mapper) root 容器是web容器的父容器
因为在 controller中注入了 service,所以需要调用到 root容器的service
-
需要几个配置文件?
可以根据分层来,也可以根据 知识点来分
配置名 对应内容 对应容器 WebJavaConfig controller、springmvc web容器 ServiceJavaConfig service、aop、tx root容器 MapperJavaConfig mapper、dataSource 、mybatis root容器 在 springmvc 的 初始化类中
getRootConfigClass 方法指定的是 root容器的配置类
getServletConfigClasses 方法指定的是 web容器的配置类
2.导入依赖
<properties>
<spring.version>6.0.6</spring.version>
<jakarta.annotation-api.version>2.1.1</jakarta.annotation-api.version>
<jakarta.jakartaee-web-api.version>9.1.0</jakarta.jakartaee-web-api.version>
<jackson-databind.version>2.15.0</jackson-databind.version>
<hibernate-validator.version>8.0.0.Final</hibernate-validator.version>
<mybatis.version>3.5.11</mybatis.version>
<mysql.version>8.0.25</mysql.version>
<pagehelper.version>5.1.11</pagehelper.version>
<druid.version>1.2.8</druid.version>
<mybatis-spring.version>3.0.2</mybatis-spring.version>
<jakarta.servlet.jsp.jstl-api.version>3.0.0</jakarta.servlet.jsp.jstl-api.version>
<logback.version>1.2.3</logback.version>
<lombok.version>1.18.26</lombok.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--
需要依赖清单分析:
spring
ioc/di
spring-context / 6.0.6
jakarta.annotation-api / 2.1.1 jsr250
aop
spring-aspects / 6.0.6
tx
spring-tx / 6.0.6
spring-jdbc / 6.0.6
springmvc
spring-webmvc 6.0.6
jakarta.jakartaee-web-api 9.1.0
jackson-databind 2.15.0
hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Final
mybatis
mybatis / 3.5.11
mysql / 8.0.25
pagehelper / 5.1.11
整合需要
加载spring容器 spring-web / 6.0.6
整合mybatis mybatis-spring x x
数据库连接池 druid / x
lombok lombok / 1.18.26
logback logback/ 1.2.3
-->
<dependencies>
<!--spring pom.xml依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>${jakarta.annotation-api.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--
springmvc
spring-webmvc 6.0.6
jakarta.jakartaee-web-api 9.1.0
jackson-databind 2.15.0
hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Final
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>${jakarta.jakartaee-web-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- jsp需要依赖! jstl-->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>${jakarta.servlet.jsp.jstl-api.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!--
mybatis
mybatis / 3.5.11
mysql / 8.0.25
pagehelper / 5.1.11
-->
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- 整合第三方特殊依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- 日志 , 会自动传递slf4j门面-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
3.整合 SpringMVC
SpringMVC 的配置类放 controller和springmvc的配置
该配置类需要的配置
-
controller组件
-
全局异常处理
-
配置 HandlerMapping和 HandlerAdapter
-
静态资源处理
-
jsp 视图解析器前后缀
-
json转化器
-
拦截器
package com.ztone.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//创建 handlerMapping 和 handlerAdapter 和json 转化器
@EnableWebMvc
//标注该类是配置类
@Configuration
//扫描注解,controller 和全局异常处理器
@ComponentScan({"com.ztone.controller","com.ztone.exception"})
//实现接口,简化配置springmvc组件
public class WebMvcJavaConfig implements WebMvcConfigurer {
//静态资源处理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//配置视图解析器
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views",".jsp");
}
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//registry.addInterceptor(new xxx).addPathPatterns("");
}
}
4.service层的配置
该配置类主要放service层的配置和 aop 和 tx
-
扫描service层的类
-
开启aop 注解支持
-
@Before、@After、@AfterReturning、@AfterThrowing、@Around、@Aspect、@Order
-
-
tx 声明式事务管理
-
对应的事务管理器实现
-
开启事务注解支持
-
package com.ztone.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration
//开启aop注解支持
@EnableAspectJAutoProxy
//开启事务注解支持
@EnableTransactionManagement
public class ServiceJavaConfig {
//配置事务管理器
public TransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
5.mapper层配置
之前在使用mybatis 时,需要SqlSessionFactory、SqlSession、mapper等
public void test() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Map map = new HashMap();
map.put("name","zhangsan");
map.put("salary",200.0);
int i = mapper.insertEmpMap(map);
//System.out.println(employee);
sqlSession.close();
}
那么需要全部放入到ioc容器吗?
把 SqlSessionFactory和 mapper放到ioc容器即可。
mybatis提供了 封装 SqlSessionFactory 和 Mapper实例化的逻辑的 FactoryBean组件
我们只需要创建 SqlSessionFactoryBean 即可,这个 FactoryBean有getObject 方法,该方法实例化了 SqlSessionFactory
如果想要保留 mybatis-config 配置文件,那么里面只需要配置 设置、插件、别名等
环境和mapper 不需要再该文件中配置了
所以最终mapper层的配置文件需要做的是:
-
配置SqlSessionFactoryBean
-
配置mapper 的代理类对象
-
DataSourse 数据库连接池
package com.ztone.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import javax.sql.DataSource;
@Configuration
//读取数据库文件
@PropertySource("classpath:jdbc.properties")
public class MapperJavaConfig {
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driver;
//配置连接池
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
return dataSource;
}
//创建SqlsessionFactoryBean,由于还存在 myvatis-config 配置文件,还需要读取该配置文件
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//指定数据库连接池对象
sqlSessionFactoryBean.setDataSource(dataSource);
//指定外部配置文件
Resource resource = new ClassPathResource("mybatis-config.xml");
sqlSessionFactoryBean.setConfigLocation(resource);
return sqlSessionFactoryBean;
}
//将mapper代理对象加入到ioc 容器,指定一个包,把该包下的mapper接口生成代理对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.ztone.mapper"); //mapper接口和xml文件所在的共同包
return mapperScannerConfigurer;
}
}
现在会存在一个问题:数据库的user、password 等读不到,原因是SqlSessionFactoryBean 和 MapperScannerConfigurer 读取的顺序会早于 @Value,导致 dataSource 中的数据还没有值就放到SqlSessionFactoryBean
解决方案就是把 dataSource 连接池分开配置放到另一个配置类中
package com.ztone.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@Configuration
//读取数据库文件
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driver;
//配置连接池
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
return dataSource;
}
}
当完全抛弃掉 mybatis-config.xml 配置文件,该如何设置
还是再 SqlSessionFactoryBean中,之前调用读取配置文件的方法改为 设置配置
-
settings
调用setConfiguration 存储setting的配置。该方法需要传入一个Configuration类,通过对Configuration类的设置进行配置(开启驼峰式映射、开启日志输出、开启resultMap自动映射)
-
typeAliases
调用 setTypeAliasesPackage,传入起别名的包名
-
plugins
调用 addPlugins,传入 插件类
...
@Configuration
public class MapperJavaConfigNoXML {
//创建SqlsessionFactoryBean,由于还存在 myvatis-config 配置文件,还需要读取该配置文件
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//指定数据库连接池对象
sqlSessionFactoryBean.setDataSource(dataSource);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
//开启驼峰映射
configuration.setMapUnderscoreToCamelCase(true);
//开启日志
configuration.setLogImpl(Slf4jImpl.class);
//开启resultMap 自动映射
configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);
sqlSessionFactoryBean.setConfiguration(configuration);
// 别名 typeAliaces
sqlSessionFactoryBean.setTypeAliasesPackage("com.ztone.pojo");
//插件 plugins
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect","mysql");
pageInterceptor.setProperties(properties);
sqlSessionFactoryBean.addPlugins(pageInterceptor);
return sqlSessionFactoryBean;
}
//将mapper代理对象加入到ioc 容器,指定一个包,把该包下的mapper接口生成代理对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.ztone.mapper"); //mapper接口和xml文件所在的共同包
return mapperScannerConfigurer;
}
}
解决前后端跨域问题:在Controller上加注解 @CrossOrigin
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)