欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

SSM第九讲 Spring+SpringMVC+MyBatis框架整合

Spring+SpringMVC+MyBatis框架整合

一、SSM框架整合

1.回顾

MyBatis环境

编写SqlMapConfig.xml核心配置文件,配置连接信息、加载mapper文件、别名等等

需要编写Mapper.xml和Mapper接口、使用namespace关联

需要引入mybatis依赖

Spring环境

编写application.xml核心配置文件,注入对象

配置包扫描,使用注解注入@Controller、@Service、@Repository、@Competent

使用@Autowird、@Qualifier、@Recource注解注入对象

配置aop切面、

配置aop事务,开启aop事务支持<tx:annotation-driven transaction-manager="transactionManager" />并设置事务管理器使用、@Transacational注解配置aop事务

需要提供数据源、事务管理器

SpringMVC环境

编写dispatcher-servlet.xml核心配置文件

包扫描、开启springmvc注解支持<mvc:annotation-driven/>、放行静态资源、视图解析器、拦截器等

2.创建项目

在这里插入图片描述

整合所需依赖:

 <dependencies> 
    <dependency> 
      <groupId>mysql</groupId>  
      <artifactId>mysql-connector-java</artifactId>  
      <version>5.1.47</version> 
    </dependency>  
    <dependency> 
      <groupId>com.alibaba</groupId>  
      <artifactId>druid</artifactId>  
      <version>1.1.19</version> 
    </dependency>  
    <!--mybatis依赖-->  
    <dependency> 
      <groupId>org.mybatis</groupId>  
      <artifactId>mybatis</artifactId>  
      <version>3.5.1</version> 
    </dependency>  
    <!--spring、springmvc依赖-->  
    <dependency> 
      <groupId>org.springframework</groupId>  
      <artifactId>spring-webmvc</artifactId>  
      <version>5.1.6.RELEASE</version> 
    </dependency>  
    <!--jdbc包(事务管理器在这里)-->  
    <dependency> 
      <groupId>org.springframework</groupId>  
      <artifactId>spring-orm</artifactId>  
      <version>5.1.6.RELEASE</version> 
    </dependency>  
    <dependency> 
      <groupId>org.springframework</groupId>  
      <artifactId>spring-aspects</artifactId>  
      <version>5.1.6.RELEASE</version> 
    </dependency>  
    <!--aop包-->  
    <!--mybatis整合spring包-->  
    <dependency> 
      <groupId>org.mybatis</groupId>  
      <artifactId>mybatis-spring</artifactId>  
      <version>1.3.1</version> 
    </dependency>  
    <!--jstl包-->  
    <dependency> 
      <groupId>javax.servlet</groupId>  
      <artifactId>jstl</artifactId>  
      <version>1.2</version> 
    </dependency>  
    <!--servletAPI-->  
    <dependency> 
      <groupId>javax.servlet</groupId>  
      <artifactId>javax.servlet-api</artifactId>  
      <version>3.1.0</version>  
      <scope>provided</scope> 
    </dependency>  
    <!--单元测试-->  
    <dependency> 
      <groupId>junit</groupId>  
      <artifactId>junit</artifactId>  
      <version>4.12</version> 
    </dependency>  
    <!--spring整合junit-->  
    <dependency> 
      <groupId>org.springframework</groupId>  
      <artifactId>spring-test</artifactId>  
      <version>5.1.6.RELEASE</version> 
    </dependency>  
    <!--springmvc对象转json支持包-->  
    <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId>  
      <artifactId>jackson-databind</artifactId>  
      <version>2.9.8</version> 
    </dependency> 
     
     <!--显示 spring5、mybatis日志 依赖-->
     <dependency><!-- log4j2的API实现包 -->
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.8.1</version>

    </dependency>
    <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.12.0</version>
        </dependency>
  </dependencies> 

 

db.properties

druid.username=root
druid.password=123456
druid.url=jdbc:mysql:///privilege?characterEncoding=utf8
druid.driverClassName=com.mysql.jdbc.Driver

 

3.spring5 日志整合

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

<?xml version="1.0" encoding="UTF-8"?>
<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>

 

4.Spring整合MyBatis

Spring整合MyBatis的核心就是把MyBatis的核心配置文件(SqlMapConfig.xml)给去除

让我们回想一下MyBatis的核心配置文件中都配了什么?

  1. 别名
  2. 数据源配置
  3. 加载mapper文件

mybatis-spring.jar

MyBatis和Spring的集成工作是由MyBatis团队完成的。所以我们首先要先引入MyBatis和Spring的集成依赖包

  • SqlSession Factory Bean

    为整合应用提供 SqlSession对象资源

  • MapperFactory Bean

​ 根据指定 Mapper接口生成Bean实例

  • MapperScanner Configurer

​ 根据指定包批量扫描 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整合配置类

/*
整合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;
    }
}

 

dao层

public interface UserMapper {
    @Select("select * from user where id=#{id}")
    User findById(Integer id);
}

 

5.spring声明式事务

  • 事务管理是企业级应用程序开发中必不可少的技术, 用来确保数据的完整性和一致性.。
  • 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用。

事务的四个关键属性(ACID):

属性 解释
原子性(atomicity) 事务是一个原子操作, 由一系列动作组成. 事务的原子性确保动作要么全部完成要么完全不起作用
一致性(consistency) 一旦所有事务动作完成, 事务就被提交. 数据和资源就处于一种满足业务规则的一致性状态中
隔离性(isolation) 可能有许多事务会同时处理相同的数据, 因此每个事物都应该与其他事务隔离开来, 防止数据损坏
持久性(durability) 一旦事务完成, 无论发生什么系统错误, 它的结果都不应该受到影响. 通常情况下, 事务的结果被写到持久化存储器中
  • Spring 的核心事务管理抽象是PlatformTransactionManager它为事务管理封装了一组独立于技术的方法. 无论使用Spring 的哪种事务管理策略(编程式或声明式), 事务管理器都是必须的。
  • DataSourceTransactionManager:在应用程序中只需要处理一个数据源, 而且通过 JDBC 存取。
  • JtaTransactionManager: 在 JavaEE 应用服务器上用 JTA(Java Transaction API) 进行事务管理
  • HibernateTransactionManager:用 Hibernate 框架存取数据库
  • 事务管理器以普通的 Bean 形式声明在 Spring IOC 容器中

spring注解事务配置:

1.引入事务依赖包

2.在spring配置文件中添加spring事务管理器

3.在spring配置文件中开启事务注解支持

4.在需要管理事务的服务层上添加事务注解

service层

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);
    }
}

 

6.Spring整合SpringMVC

配置web.xml:

<!--监听web容器启动就加载ioc容器-->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextClass</param-name>
		<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
	</context-param>
	<!--配置全局参数,让监听器能够识别到spring的配置文件所在-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>cn.nyse.config.ContextConfig</param-value>
	</context-param>
	<!--spring核心(前端控制器)-->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!--配置springmvc配置文件的位置-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>cn.nyse.config.SpringmvcConfig</param-value>
		</init-param>
		<init-param>
			<param-name>contextClass</param-name>
			<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<!--拦截除jsp之外所有请求-->
		<url-pattern>/</url-pattern>
	</servlet-mapping>


	<!--处理中文乱码过滤器-->
	<filter>
		<filter-name>characterEncoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncoding</filter-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层

springmvc配置类


@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();//放行静态资源
    }




}

 

controller:

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);
    }
}

作者:易兮科技 | 来源:https://blog.csdn.net/m0_47157676

赞(0) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » SSM第九讲 Spring+SpringMVC+MyBatis框架整合

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏