原生mybatis使用方法:

String resource = "mybatis-config.xml"; 
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
SqlSession session = sqlSessionFactory.openSession();    
try {      
           Employee employee = new Employee(null, "doubi", "1", "[email protected]"); 
           EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);     
           mapper.addEmp(employee);               
           session.commit();    
} finally {
      session.close();    
}  

spring使用方法,直接注入即可

@Autowired
EmployeeMapper employeeMapper

那么spring为我们做了什么?下面研究一下mybatis-spring.jar这个jar包
首先来看一下如何使用spring整合mybatis,下面是使用spring-mybatis的四种方法:
方法一:(使用MapperFactoryBean)


            
            
            
        




  
  

这样做的缺点是每一个mapper接口都要在xml里配置一下

方法二:采用接口org.apache.ibatis.session.SqlSession的实现类
org.mybatis.spring.SqlSessionTemplate

mybatis中, sessionFactory可由SqlSessionFactoryBuilder.来创建。MyBatis-Spring
中,使用了SqlSessionFactoryBean来替代。SqlSessionFactoryBean有一个必须属性dataSource,另外其还有一个通用属性configLocation(用来指定mybatis的xml配置文件路径)。

SqlSessionFactoryBean即相当于原生mybatis中的SqlSessionFactoryBuilder


    
        
            
            
            
        
        

    
        
        
//使用方法:
@Repositorypublic class UserDao{    @Resource    private SqlSessionTemplate sqlSessionTemplate;        public User getUser(int id) {        return sqlSessionTemplate.selectOne(this.getClass().getName() + ".getUser", 1);    }   }

为什么可以这样写,来看一下SqlSessionTemplate

public class SqlSessionTemplate implements SqlSession {  private final SqlSessionFactory sqlSessionFactory;  private final ExecutorType executorType;  private final SqlSession sqlSessionProxy;  private final PersistenceExceptionTranslator exceptionTranslator;  /**   * Constructs a Spring managed SqlSession with the {@code SqlSessionFactory}   * provided as an argument.   *   * @param sqlSessionFactory   */  public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {    this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());  }

........省略......
   public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,      PersistenceExceptionTranslator exceptionTranslator) {    notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");    notNull(executorType, "Property 'executorType' is required");    this.sqlSessionFactory = sqlSessionFactory;    this.executorType = executorType;    this.exceptionTranslator = exceptionTranslator;    this.sqlSessionProxy = (SqlSession) newProxyInstance(        SqlSessionFactory.class.getClassLoader(),        new Class[] { SqlSession.class },        new SqlSessionInterceptor());  }

}

如上面代码所示,SqlSessionTemplate类实现了原生Mybatis中的SqlSession接口,实际上它就是原生mybatis中的SqlSession

方法三:采用抽象类org.mybatis.spring.support.SqlSessionDaoSupport提供SqlSession



    
        
        
        
        
    
public  class BaseDao extends SqlSessionDaoSupport{  //使用sqlSessionFactory  @Autowired   private  SqlSessionFactory sqlSessionFactory;      @Autowired   public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory)    {        super.setSqlSessionFactory(sqlSessionFactory);    }    /**   * 执行insert操作   * @param statement   * @return   */  public int insert(String statement) {    return getSqlSession().insert(statement);  }  /**   * 执行insert操作   * @param statement   * @param parameter   * @return   */  public int insert(String statement, Object parameter) {    return getSqlSession().insert(statement, parameter);  }    public int update(String statement) {    return getSqlSession().update(statement);  }  public int update(String statement, Object parameter) {    return getSqlSession().update(statement, parameter);  }    public int delete(String statement) {    return getSqlSession().delete(statement);  }    public int delete(String statement, Object parameter) {    return getSqlSession().delete(statement, parameter);  }    /**   * 获取一个list集合   * @param statement   * @return   */  public List selectList(String statement) {    return getSqlSession().selectList(statement);  }    /**   * 根据参数 获取一个list集合   * @param statement   * @param parameter   * @return   */  public List selectList(String statement, Object parameter) {    return getSqlSession().selectList(statement, parameter);  }    public Map selectMap(String statement, String mapKey) {    return getSqlSession().selectMap(statement, mapKey);  }  public Map selectMap(String statement, Object parameter, String mapKey) {    return getSqlSession().selectMap(statement, parameter, mapKey);  }    /**   * 获取Object对象   * @param statement   * @return   */  public Object selectOne(String statement) {    return getSqlSession().selectOne(statement);  }    /**   * 获取connection, 以便执行较为复杂的用法   * @return   */  public Connection getConnection() {    return getSqlSession().getConnection();  }  }

    如上代码,一个Dao类继承了SqlSessionDaoSupport类后,就可以在类中注入SessionFactory,进而通过getSqlSession()获取当前SqlSession

    下面是SqlSessionDaoSupport的源码,它是一个抽象类,并拥有sqlSession属性,在setSqlSessionFactory方法中实例化了该sqlSession:

    public abstract class SqlSessionDaoSupport extends DaoSupport {  private SqlSession sqlSession;  private boolean externalSqlSession;  public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {    if (!this.externalSqlSession) {      this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);    }  }  public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {    this.sqlSession = sqlSessionTemplate;    this.externalSqlSession = true;  }  public SqlSession getSqlSession() {    return this.sqlSession;  }  protected void checkDaoConfig() {    notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");  }}
    方法四:(也是最常见的使用方法,使用MapperScannerConfigurer,它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean)

    由于直接使用MapperFactoryBean会在配置文件中配置大量mapper,因此这里使用包扫描的方式通过注解获取该bean



        
        
        




        
        

//使用如下代码,即可完成注入br/>@Resource
private UserDao userDao;

下面看一下MapperScannerConfigurer这个类:

public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {  private String basePackage;  private boolean addToConfig = true;  private SqlSessionFactory sqlSessionFactory;  private SqlSessionTemplate sqlSessionTemplate;  private String sqlSessionFactoryBeanName;  private String sqlSessionTemplateBeanName;  private Class annotationClass;  private Class markerInterface;  private ApplicationContext applicationContext;  private String beanName;  private boolean processPropertyPlaceHolders;  private BeanNameGenerator nameGenerator;

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {    if (this.processPropertyPlaceHolders) {      processPropertyPlaceHolders();    }    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);    scanner.setAddToConfig(this.addToConfig);    scanner.setAnnotationClass(this.annotationClass);    scanner.setMarkerInterface(this.markerInterface);    scanner.setSqlSessionFactory(this.sqlSessionFactory);    scanner.setSqlSessionTemplate(this.sqlSessionTemplate);    scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);    scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);    scanner.setResourceLoader(this.applicationContext);    scanner.setBeanNameGenerator(this.nameGenerator);    scanner.registerFilters();    scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));  }

ClassPathMapperScanner :

public Set<BeanDefinitionHolder> doScan(String... basePackages) { Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages); if (beanDefinitions.isEmpty()) { logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration."); } else { for (BeanDefinitionHolder holder : beanDefinitions) { GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition(); if (logger.isDebugEnabled()) { logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + definition.getBeanClassName() + "' mapperInterface"); } // the mapper interface is the original class of the bean // but, the actual class of the bean is MapperFactoryBean definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName()); definition.setBeanClass(MapperFactoryBean.class); definition.getPropertyValues().add("addToConfig", this.addToConfig); boolean explicitFactoryUsed = false; if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) { definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName)); explicitFactoryUsed = true; } else if (this.sqlSessionFactory != null) { definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory); explicitFactoryUsed = true; } if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) { if (explicitFactoryUsed) { logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); } definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName)); explicitFactoryUsed = true; } else if (this.sqlSessionTemplate != null) { if (explicitFactoryUsed) { logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); } definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate); explicitFactoryUsed = true; } if (!explicitFactoryUsed) { if (logger.isDebugEnabled()) { logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'."); } definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); } } } return beanDefinitions; }

总结:spring-mybatis与原生Mybatis相比,如下概念:

1)SqlSessionFactory类在两者中都存在

2)前者用SqlSessionFactoryBean生成SqlSessionFactory,后者则使用SqlSessionFactoryBuilder;

3)前者使用SqlSessionTemplate,后者使用SqlSession,实际上前者实现了后者

4)MapperFactoryBean中实现了原生mybatis中下面的步骤,因此通过该类可以直接获取到一个mapper接口的实现对象


`EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);    `

以上是个人总结,如有错误,欢迎指正

最后
喜欢的可以关注我的公众号:java小瓜哥的分享平台