编写SqlMapConfig.xml核心配置文件,配置连接信息、加载mapper文件、别名等等
需要编写Mapper.xml和Mapper接口、使用namespace关联
需要引入mybatis依赖
编写application.xml核心配置文件,注入对象
配置包扫描,使用注解注入@Controller、@Service、@Repository、@Competent
使用@Autowird、@Qualifier、@Recource注解注入对象
配置aop切面、
配置aop事务,开启aop事务支持
并设置事务管理器使用、@Transacational
注解配置aop事务
需要提供数据源、事务管理器
编写dispatcher-servlet.xml核心配置文件
包扫描、开启springmvc注解支持
、放行静态资源、视图解析器、拦截器等
整合所需依赖:
<dependencies>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.19version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>5.1.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>5.1.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.1.6.RELEASEversion>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.8version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.8.1version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-slf4j-implartifactId>
<version>2.12.0version>
dependency>
dependencies>
druid.username=root
druid.password=123456
druid.url=jdbc:mysql:///privilege?characterEncoding=utf8
druid.driverClassName=com.mysql.jdbc.Driver
spring中同样使用了日志进行信息的输出,但是spring4和spring5之间的日志又有些不同,spring5需要通过jcl和log4j2实现。
各种日志技术简述:
log4j,jcl,log4j2,slf4j
日志接口(slf4j)
slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如slf4j-log4j12、log4j-slf4j-impl)
log4j
log4j是apache实现的一个开源日志组件
log4j2
og4j2是log4j 1.x和logback的改进版,采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活
jcl:
common.logging和log4j2的集成包
配置文件:
(扩展https://logging.apache.org/log4j/2.x/manual/configuration.html)
log4j2.xml
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
Console>
Appenders>
<Loggers>
<Logger name="cn.nyse.dao" level="trace" >
<AppenderRef ref="Console"/>
Logger>
<Root level="debug">
<AppenderRef ref="Console"/>
Root>
Loggers>
Configuration>
Spring整合MyBatis的核心就是把MyBatis的核心配置文件(SqlMapConfig.xml)给去除
让我们回想一下MyBatis的核心配置文件中都配了什么?
MyBatis和Spring的集成工作是由MyBatis团队完成的。所以我们首先要先引入MyBatis和Spring的集成依赖包
SqlSession Factory Bean
为整合应用提供 SqlSession对象资源
MapperFactory Bean
根据指定 Mapper接口生成Bean实例
根据指定包批量扫描 Mapper接口井生成实例
SqlSessionFactoryBean
在单独使用Mybatis时,所有操作都是围绕SqlSession展开的, Sqlsession是通过 SqlSession Factory获取的,Sqlsession Factory又是通过 Sqlsession Factory Builder创建生成在 Spring和 MyBatis整合应用时,同样需要 SqlSession,mybatis-spring ja提供了一个 SqlSession Factory Bean这个组件作用就是通过原 SqlSession Factory Builder生成SqlSession Factory对象,为整合应用提供 Sqlsession对象。
MapperScannerConfigurer
在定义MapperScannerConfigurer时,只需要指定一个basePackage即可, basePackage用于指定 Mapper接口所在的包,在这个包及其所有子包下面的 Mapper接口都将被搜索到,并把它们注册为一个个MapperFactory Bean对象,多个包之间可以使用逗号或者分号进行分隔
/*
整合spring与mybatis
整合事务
1.读取配置文件,声明数据源对象
2.声明配置SqlSessionFactoryBean
3.声明配置MapperScannerConfigurer
4.声明配置事务管理器
5.开启事务注解支持
6.开启包扫描,扫码服务层
*/
@Configuration
//@PropertySource(encoding = "utf-8",value = "classpath:db.properties")
//开启mapper扫描,自动扫描mapper包下的接口,并且创建代理子类 替代MapperScannerConfigurer
//annotationClass指定注解标记类
@MapperScan(basePackages = {
"cn.nyse.dao"})
@EnableTransactionManagement//开启事务注解支持
@ComponentScan(basePackages = "cn.nyse.service")
public class ContextConfig {
//如果Properties文件的属性名命名符合configFromPropety的参数Properties的命名规则,则自动赋值
@Bean
public DruidDataSource getDataSource(){
Properties props = new Properties();
try {
props.load(ContextConfig.class.getClassLoader().getResourceAsStream("db.properties"));
DruidDataSource dataSource = new DruidDataSource();
dataSource.configFromPropety(props);
return dataSource;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//DruidDataSource dataSource:spring容器会自动从自己的bean里面按照类型查找是否存在
//如果有则注入给改方法参数
@Bean
public SqlSessionFactoryBean getFactoryBean(DruidDataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
//1.配置数据源
factoryBean.setDataSource(dataSource);
//2.配置别名
factoryBean.setTypeAliasesPackage("cn.nyse.entity");
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration ();
configuration.setLogImpl(Log4j2Impl.class);//配置mybatis 日志类
configuration.setMapUnderscoreToCamelCase(true);//开启支持驼峰命名
factoryBean.setConfiguration(configuration);
//xml映射文件 配置
// PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
// try {
// factoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath:/cn/nyse/dao/*.xml"));
// } catch (IOException e) {
// e.printStackTrace();
// }
return factoryBean;
}
//创建事务管理器bean
@Bean
public DataSourceTransactionManager getTransactionManager(DruidDataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
public class User {
private Integer id;
private String username;
private String password;
private String birthday;
private String address;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday='" + birthday + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public interface UserMapper {
@Select("select * from user where id=#{id}")
User findById(Integer id);
}
事务的四个关键属性(ACID):
属性 | 解释 |
---|---|
原子性(atomicity) | 事务是一个原子操作, 由一系列动作组成. 事务的原子性确保动作要么全部完成要么完全不起作用 |
一致性(consistency) | 一旦所有事务动作完成, 事务就被提交. 数据和资源就处于一种满足业务规则的一致性状态中 |
隔离性(isolation) | 可能有许多事务会同时处理相同的数据, 因此每个事物都应该与其他事务隔离开来, 防止数据损坏 |
持久性(durability) | 一旦事务完成, 无论发生什么系统错误, 它的结果都不应该受到影响. 通常情况下, 事务的结果被写到持久化存储器中 |
spring注解事务配置:
1.引入事务依赖包
2.在spring配置文件中添加spring事务管理器
3.在spring配置文件中开启事务注解支持
4.在需要管理事务的服务层上添加事务注解
public interface UserService {
User findById(Integer id);
}
@Service //注入到ioc容器
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public User findById(Integer id){
return userMapper.findById(id);
}
//通过模拟异常查看事务回滚情况
public User insertBatch(User user){
int result = userMapper.insert(user);
String str = null;//模拟异常
str.length;
result += userMapper.insert(user);
return result;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ContextConfig.class)
public class TestSSM {
@Autowired
UserService userService;
@Test
public void testFindById(){
User user = userService.findById(1);
System.out.println(user);
}
}
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<context-param>
<param-name>contextClassparam-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContextparam-value>
context-param>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>cn.nyse.config.ContextConfigparam-value>
context-param>
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>cn.nyse.config.SpringmvcConfigparam-value>
init-param>
<init-param>
<param-name>contextClassparam-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContextparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>characterEncodingfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
ContextLoderListener,DispatcherServlet两者都是通过加载配置文件创建spring容器实例
ContextLoderListener:
是监听器,启动Web容器时,自动通过context-param的配置装配spring容器的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。context-param的作用就是设置监听器的初始化属性
通过ContextLoderListener创建的spring容器,是应用中的spring父容器,其他spring子容器共用父容器
常用于加载除Controller层以外的service层、dao层等组件
DispatcherServlet:
servlet,web容器启动后实例化,比listener、filter的实例化都要晚,通过读取init-param来配置装配spring容器的配置信息。
通过dispatcherServlet创建的spring容器是子容器,会自动将spring父容器传入
用于加载Controller层
@Configuration
@ComponentScan(basePackages = "cn.nyse.controller")//开启报扫描
@EnableWebMvc//开启mvc注解支持
public class SpringmvcConfig implements WebMvcConfigurer {
//容器管理视图bean
@Bean
public InternalResourceViewResolver getResourvler(){
return new InternalResourceViewResolver("/WEB-INF/view/",".jsp");// /WEB-INF/view/fee/fee_list.jsp
}
//配置默认静态资源放行
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();//放行静态资源
}
}
package com.dfbz.controller;
import com.dfbz.entity.User;
import com.dfbz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findById")
@ResponseBody
public User findById(Integer id){
return userService.findById(id);
}
}