• mybatis与Spring


    提问1:如果没有spring-mybatis,我们如何在spring中使用定义bean,如何使用事务?

    mybatis-Spring为我们带来多种方式的Mapper接口的注册,扫描,识别。

    如果不使用mybatis-spring也可以。需要手工在配置文件中,注册SqlSessionFactory,SqlSession,注册具体的Mapper

    1、我们自己来注册,现在xml中声明一个自定义的factoryBean

    <bean id="sqlSessionFactory" class="org.mybatis.example.spring.self.init.SqlSessionBuilderFactory">
            <property name="mapperLocation" value="mybatis-config.xml"/>
        </bean>

    2、自定义的factorybean的代码

    package org.mybatis.example.spring.self.init;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.springframework.beans.factory.FactoryBean;
    
    
    public class SqlSessionBuilderFactory implements FactoryBean<SqlSessionFactory> {
    
    
        private String mapperLocation;
        @Override
        public SqlSessionFactory getObject() throws Exception {
            return (new SqlSessionFactoryBuilder()).build(this.getClass().getClassLoader().getResourceAsStream(mapperLocation));
        }
    
        @Override
        public Class<?> getObjectType() {
            return null;
        }
        
    
        public void setMapperLocation(String mapperLocation) {
            this.mapperLocation = mapperLocation;
        }
    }

    3.service层的调用

    package org.mybatis.example.spring.service;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.example.mapper.MybatistestMapper;
    import org.mybatis.example.model.Mybatistest;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.annotation.Resource;
    import java.util.Date;
    import java.util.Random;
    
    @Service("daoCallerInjectWithSqlSession")
    public class DaoCallerInjectWithSqlSession {
    
        @Resource(name="sqlSessionFactory")
        SqlSessionFactory sqlSessionFactory;
    
        @Transactional
        public void  updateDb(Mybatistest test){
    
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            MybatistestMapper mapper =sqlSession.getMapper(MybatistestMapper.class);
    
            mapper.selectByPrimaryKey(test.getId());
    
            Random random =new Random();
            test.setMykey(String.valueOf(random.nextInt(500)));
            test.setMyvalue(random.nextBoolean());
            test.setCreateTime(new Date());
            test.setCreateUser("ccc");
            test.setIsDelete((byte)0);
            sqlSession.getMapper(MybatistestMapper.class).updateByPrimaryKey(test);
            sqlSession.commit();
        }
    }

    通过以上方式,可以获取sqlSession对象,并完成事务.

    使用mybatis-spring,是如何为我们获取Mapper,以及管理事务?

     一、事务的管理过程:

    以下序列图,描述了Mapper的创建

     1、

      mybatis-Spring初始化sqlSessionFactory,在初始化过程中,

      设置事务管理器为Spring管理的事务管理器。mybatis自带的事务,是通过事务管理器来创建

      先来回顾下,mybatis是如何创建事务的

      1.1 关于事务的创建。mybatis-spring在创建sqlsession时,从transactionManager创建一个事物,赋值给sqlSession,sqlSession在执行过程中,通过这个transaction来获取链接,提交事务。

      1.2 关于sqlSessionTemplate的说明。不适用Spring的时候,每次请求数据库可以创建一个新的sqlSession.并且事务由调用方,手动管理。而在mybatis-spring中,sqlSession这个接口被泛化,

        所有的Mapper需要sqlSession的时候,得到的都是sqlSessionTemplate这个对象,这个对象在真正执行之前,创建sqlSession,并为sqlSession分配spring管理的事务。

        来看一段sqlSessionTemple的代理对象初始化的代码
        

     private class SqlSessionInterceptor implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          SqlSession sqlSession = getSqlSession(
              SqlSessionTemplate.this.sqlSessionFactory,
              SqlSessionTemplate.this.executorType,
              SqlSessionTemplate.this.exceptionTranslator);

      在真正执行sqlSession方法的时候,会初始化sqlSession.从spring的TransactionSynchronizationManager对象,获取sqlsession。

    2、来看第二章序列图,当调用Service层,service层调用Mapper的时候,是如何处理请求,管理事务的

      

     红色的线,代表Spring的事务管理。

    2.1 在Mapper执行开始前,Spring-AOP创建事务,和当前线程绑定

    2.2 sqlSessionTemplate创建真正的SqlSession,执行sql时会获取sqlSession中的transaction,通过transaction获取链接

    2.3当执行完毕后,AOP通过当前线程获取事务,并提交事务。

    二、Mybatis-spring中的MapperBean注册

    方式一、Spring配置文件中定义MapperFactoryBean

     <bean id="mybatisTestMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" >
            <property name="mapperInterface" value="org.mybatis.example.mapper.MybatistestMapper"/>
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>

    MapperFactoryBean的类图:

    因为继承了InitiaLizingBean ,所以会在afterproperties中初始化Mapper.

    继承DaoSupport后,可以获得sqlSessionFactory,用来进行Mapper的初始化。

    方式二、通过Spring handler,解析xml中的节点,到指定路径匹配Mapper,转换成MapperFactoryBean

        <mybatis:scan base-package="org.mybatis.example.mapper" factory-ref="sqlSessionFactory" />

    方式三、直接配置MapperScannerConfigurer,实现方式同上

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="basePackage" value="org.mybatis.spring.sample.mapper" />
    </bean>

    方式四、通过注解方式配置basePackage,手段不同,实现方式同二、三

    @Configuration
     @MapperScan("org.mybatis.spring.sample.mapper")
     public class AppConfig {
    }
  • 相关阅读:
    leafletjs加载 tiff
    vue echarts 宽度100% 显示不正常
    动态加载天地图
    MongoDB常用的几种过滤器
    Element中loading被dialog盖住问题
    安装xlsxjs 出现@vue/vueloaderv15@15.10.0 无法安装~~~~
    EasyPlayer.js 很不错的视频播放
    xlsxjs 在处理导出数据函数无效
    若依使用系统配置
    libreoffice 基于OpenOffice 与Microsoft兼容
  • 原文地址:https://www.cnblogs.com/marioS/p/10426809.html
Copyright © 2020-2023  润新知