目录
1 添加依赖2 控制层配置类3 业务层配置类4 持久层配置类4.1 方式14.1.1 合起来配置(会出现问题)4.1.2 分开配置
4.2 方式2
5 配置类的初始化6 实际测试
1 添加依赖
在项目下的pom.xml里面设置打包方式为pom
配置日志
class="ch.qos.logback.core.ConsoleAppender">
新建module,module下面的pom.xml文件里设置打包方式为war
将Web Module Deployment Descriptor添加为……\src\main\webapp\WEB-INF\web.xml将Web Resource Directory设置为……\src\main\webapp
2 控制层配置类
控制层的配置类,需要配置controller,SpringMVC 在src文件的自己的包(如com.example)下建包config,新建WebJavaConfig.java
声明@Configuration注解,代表配置类
实现implements接口WebMvcConfigurer
实现功能与对应方式
实现功能方式controller@ComponentScan({“com.example.controller”})全局异常处理器@ComponentScan({“com.example.exceptionhandler”})handlerMapping,handlerAdapter@EnableWebMvc静态资源处理configurer.enable()视图解析器前后缀registry.jsp(“/WEB-INF/views/”,“jsp”)json转换器registry.addInterceptor(new XXInterceptor()).addPathPatterns(“”).excludePathPatterns(“”)拦截器@EnableWebMvc 实现代码
@Configuration
@EnableWebMvc
@ComponentScan({"com.example.controller","com.example.exceptionhandler"})
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 XXInterceptor()).addPathPatterns("").excludePathPatterns("");
}
}
3 业务层配置类
业务层配置类:需要配置service,aop,tx 在src文件下的包(如com.example)-> config,新建ServiceJavaConfig.java
声明@Configuration注解,代表配置类
实现功能与对应方式
实现功能方式service@ComponentScan(“com.example.service”)aop代理@EnableAspectJAutoProxytx事务管理@EnableTransactionManagement指定具体的事务管理器transactionManager(DataSource dataSource) 注意:其中TransactionManager(DataSource dataSource)需要注入连接池(配置mybatis的配置类后IOC可以自动注入)
实现代码
@EnableTransactionManagement
@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.example.service")
public class ServiceJavaConfig {
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
4 持久层配置类
配置mapper代理对象,连接池和mybatis核心组件配置 mybatis之前自己调用官方api使用的核心方法有:
//1.读取外部配置文件
InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);
//3.创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.获取mapper代理对象
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
//5.数据库方法调用
int rows = empMapper.deleteEmpById(1);
System.out.println("rows = " + rows);
//6.提交和回滚
sqlSession.commit();
sqlSession.close();
注意:
其中事务的提交也可以使用sqlSessionFactory.openSession(true)来自动提交并不是所有的类对象都需要存储到IOC容器中,只需要:
将SqlSessionFactory实例存储到IoC容器将Mapper实例存储到IoC容器
4.1 方式1
保留mybatis的外部配置文件(xml), 但是数据库连接信息交给Druid连接池配置,不使用mybatis-config.xml中自带的配置
数据库连接配置文件 Resources->jdbc.propertiesjdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql:///mybatis-example
jdbc.driver=com.mysql.cj.jdbc.Driver
mybatis核心配置文件 mybatis-config.xml
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
4.1.1 合起来配置(会出现问题)
配置类文件 MapperJavaConfig.java
实现功能方式数据库配置文件@PropertySource(“classpath:jdbc.properties”),@Value(“${jdbc.user}”)数据库连接池配置DataSource dataSource()数据库工厂SqlSessionFactoryBean sqlSessionFactoryBeanmapper的类与xml配置MapperScannerConfigurer mapperScannerConfigurer
但是这种方式(如下)会产生问题:初始化顺序(SqlSessionFactoryBean和MapperScannerConfigurer会早于Value注解生效)可能会导致属性注入@Value读取为null,因此需要拆分配置类
出现问题: 当配置类被加载时,Spring容器会首先处理Bean的定义和初始化,其中包括sqlSessionFactoryBean和mapperScannerConfigurer的初始化。在这个过程中,如果@Value注解所在的Bean还没有被完全初始化,可能会导致注入的属性值为null 解决方法: 分开配置时,会把所有对象全都生成之后缓存起来,再统一进行互相引用。因此可以进行分开配置
@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,指定连接池对象和外部配置文件即可
* @param dataSource 需要注入连接池对象
* @return 工厂Bean
*/
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
//实例化SqlSessionFactory工厂
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//设置连接池
sqlSessionFactoryBean.setDataSource(dataSource);
//设置配置文件
//包裹外部配置文件地址对象
Resource resource = new ClassPathResource("mybatis-config.xml");
sqlSessionFactoryBean.setConfigLocation(resource);
return sqlSessionFactoryBean;
}
/**
* 配置Mapper实例扫描工厂,配置 * @return */ @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); //设置mapper接口和xml文件所在的共同包 mapperScannerConfigurer.setBasePackage("com.example.mapper"); return mapperScannerConfigurer; } } 4.1.2 分开配置 将MapperJavaConfig.java拆分为数据库配置类DataSourceJavaConfig.java和 mybatis配置类MapperJavaConfig.java 数据库配置类DataSourceJavaConfig.java @Configuration @PropertySource("classpath:jdbc.properties") public class DataSourceJavaConfig { @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配置类MapperJavaConfig.java @Configuration public class MapperJavaConfig { /** * 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可 * @param dataSource 需要注入连接池对象 * @return 工厂Bean */ @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){ //实例化SqlSessionFactory工厂 SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); //设置连接池 sqlSessionFactoryBean.setDataSource(dataSource); //设置配置文件 //包裹外部配置文件地址对象 Resource resource = new ClassPathResource("mybatis-config.xml"); sqlSessionFactoryBean.setConfigLocation(resource); return sqlSessionFactoryBean; } /** * 配置Mapper实例扫描工厂,配置 * @return */ @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); //设置mapper接口和xml文件所在的共同包 mapperScannerConfigurer.setBasePackage("com.example.mapper"); return mapperScannerConfigurer; } } 4.2 方式2 不使用mybatis-config.xml配置文件,全部使用配置类。可以避免xml文件解析效率低的问题 数据库连接池配置类如上节DataSourceJavaConfig.java@Configuration @PropertySource("classpath:jdbc.properties") public class DataSourceJavaConfig { @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; } } 创建文件config->MapperJavaConfig.java(与上节不同)@Configuration public class MapperJavaConfigNew { /** * 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可 * @param dataSource 需要注入连接池对象 * @return 工厂Bean */ @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){ //实例化SqlSessionFactory工厂 SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); //设置连接池 sqlSessionFactoryBean.setDataSource(dataSource); //TODO: 替代xml文件的java配置 /* */ //settings [包裹到一个configuration对象,切记别倒错包] org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); configuration.setMapUnderscoreToCamelCase(true); configuration.setLogImpl(Slf4jImpl.class); configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL); sqlSessionFactoryBean.setConfiguration(configuration); //typeAliases sqlSessionFactoryBean.setTypeAliasesPackage("com.example.pojo"); //分页插件配置 PageInterceptor pageInterceptor = new PageInterceptor(); Properties properties = new Properties(); properties.setProperty("helperDialect","mysql"); pageInterceptor.setProperties(properties); sqlSessionFactoryBean.addPlugins(pageInterceptor); return sqlSessionFactoryBean; } /** * 配置Mapper实例扫描工厂,配置 * @return */ @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); //设置mapper接口和xml文件所在的共同包 mapperScannerConfigurer.setBasePackage("com.example.mapper"); return mapperScannerConfigurer; } } 5 配置类的初始化 Spring的初始化类:将上述所有配置类进行初始化config->SpringIoCInit.java继承AbstractAnnotationConfigDispatcherServletInitializer,需要实现三个方法 public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { //指定root容器对应的配置类 @Override protected Class>[] getRootConfigClasses() { return new Class>[] {MapperJavaConfig.class, ServiceJavaConfig.class, DataSourceJavaConfig.class }; } //指定web容器对应的配置类 @Override protected Class>[] getServletConfigClasses() { return new Class>[] { WebJavaConfig.class }; } //指定dispatcherServlet处理路径,通常为 / @Override protected String[] getServletMappings() { return new String[] { "/" }; } } 6 实际测试 下一节:【SSM】4. SSM项目的配置测试demo用一个简单的小demo来测试整个配置,附上所有的代码