小白新手web开发简单总结(十五)-数据库连接的相关优化( MyBatis的使用)

目录

前言

一 MyBatis

1.MyBatis几个概念

(1)SqlSession

(2)SqlSessionFactory

(3)SqlSessionFactoryBuilder

(4)SqlSessionFactoryBean

(5)SqlSessionManager

(6)SqlSessionTemplate

(7)SqlSessionDaoSupport

(8)MapperFactoryBean

(9)MapperScannerConfigurer

三 Spring集成MyBatis

四 总结


前言

在ORM框架中通过Proxy模式实际上操作的是实体Model的代理类,该代理类中含有对实体Model属性的set方法,get方法负责从数据库读取数据。在小白新手web开发简单总结(十三)-数据库连接的相关优化( Hibernate的使用)中主要介绍的是Hibernate,该框架是一个全自动框架,相比较与Spring提供的JdbcTemplate具有以下优点:

  • (1)不需要手动将ResultSet中的每行数据转换成实体类对象;
  • (2)不需要手动传入增删改查的参数,框架将自动执行对应的SQL语句。

但是JdbcTemplate具有它的确定性,每次读取操作都是操作的数据库,但是代码比较繁琐(像构建SQL语句的时候,都需要把每次参数依次传入);而Hibernate读取的是缓存数据。

介于两者之间,还存在一种半自动的ORM框架-MyBatis,只负责把ResultSet自动映射到JavaBean,但仍需要写SQL语句。目前只支持mysql、mariadb、oracle、prostgresql。

一 MyBatis

MyBatis同Hibernate一样,都是一个ORM框架。通过配置和原生Map使用简单的XML或注解,将接口和java的POJOs(Plain Old Java Object普通java对象)映射成数据库的记录。

1.MyBatis几个概念

(1)SqlSession

数据库连接客户端和数据库服务端的一种会话。里面维护了客户端和服务器的一些状态信息。

线程不安全,生命周期与线程相关,真正的去操作数据库。

该类是一个接口类。实现类有:DefaultSqlSession、SqlSessionManager、SqlSessionTemplate,默认的为DefaultSqlSession。当然SqlSessionManager、SqlSessionTemplate还具有其他的功能。

  • DefaultSqlSession

从里面的定义的属性中就可以看出,里面含有MyBatis的配置信息Configuration和真正的执行操作数据库的Executor。

public class DefaultSqlSession implements SqlSession {
    //MyBatis的配置信息
    private final Configuration configuration;
    //皮处理器:执行操作数据库
    private final Executor executor;

// ........
}
  •  SqlSessionManager、SqlSessionTemplate

因为还具有其他功能,所以在后面去介绍。

(2)SqlSessionFactory

可以打开一个客户端和数据库服务端的会话,而且重载很多参数来设置不同的数据库连接的类型,当然也可以获取MyBatis的配置信息Configuration。

生命周期与应用的生命周期相同,在应用的运行期间,都能使用通过Configuration来查询到当前的一些配置信息。

该类也是一个接口类。实现类有:DefaultSqlSessionFactory和SqlSessionManager。默认的为DefaultSqlSessionFactory。

  • DefaultSqlSessionFactory

生成SqlSession的工厂。

public class DefaultSqlSessionFactory implements SqlSessionFactory {
    private final Configuration configuration;
//......
    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;

        DefaultSqlSession var8;
        try {
            Environment environment = this.configuration.getEnvironment();
//在配置Mybatis的时候设置的事务管理
            TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            Executor executor = this.configuration.newExecutor(tx, execType);
//得到一个具有事务管理的SqlSession
            var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
        } catch (Exception var12) {
            this.closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
        } finally {
            ErrorContext.instance().reset();
        }

        return var8;
    }
}

从源码中可以看出,最后有DefaultSqlSessionFactory每次都会生成一个新的具有事务管理的DefaultSqlSession。

(3)SqlSessionFactoryBuilder

通过XML、注解或手动配置Java代码的方式来创建SqlSessionFactory实例。

生命周期仅用在初始化方法中。

(4)SqlSessionFactoryBean

生产SqlSessionFactory的工厂bean,并且将通过该类将Spring内置MyBatis来完成访问数据库的部分因素串联到一起,我觉得这更像MyBatis提供给开发者来使用的一个入口。

在Spring容器的整个生命周期。

通过源码看下刚才提到的前面几个因素是怎么在该类中体现出来的:

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
    private Resource configLocation;
    private Configuration configuration;
    private Resource[] mapperLocations;
    private DataSource dataSource;
    private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    private SqlSessionFactory sqlSessionFactory;

    //MyBatis的配置文件,通过注册该bean的时候,通过xml配置
    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }
    //在初始化完该bean的时候,创建SqlSessionFactory
    public void afterPropertiesSet() throws Exception {
        //最终通过sqlSessionFactoryBuilder创建了SqlSessionFactory
        this.sqlSessionFactory = this.buildSqlSessionFactory();
    }
    //后面会介绍的一个Mapper的配置
    public void setMapperLocations(Resource... mapperLocations) {
        this.mapperLocations = mapperLocations;
    }
}

在该类中通常会配置一些:DataSource、MyBatis的配置信息等,然后最终在Spring将SqlSessionFactoryBean初始化该bean的时候,根据我们设置MyBatis的核心配置文件,初始化我们需要的sqlSessionFactory。

其实这个SqlSessionFactoryBean作用和Hibernate中的LocalSessionFactoryBean作用是一样的,SqlSessionFactoryBean用来产生一个sqlSessionFactory,而LocalSessionFactoryBean来产生一个sessionFactory。


前面的都是介绍的是MyBatis提供的读写数据库的基本类,都是用来直接操作数据库的,我觉得SqlSessionFactoryBean可以认为是MyBatis提供给开发者一个快速完成这个过程的一个入口。那么后面介绍的几个是个操作过程进行封装,开发者可以更简便的去操作数据库。

(5)SqlSessionManager

 具有SqlSession和SqlSessionFactory两者的功能。实现了SqlSession和SqlSessionFactory接口。

里面含有sqlSessionFactory和sqlSessionProxy两个变量,分别来实现对应的功能。sqlSessionFactory是就是通过构造函数传入的,而sqlSessionProxy是通过动态代理取得sqlSessionFactory中的成员变量,最终实现方法里面都是调用的这些变量来实现的功能。

所以如果传入的是DefaultSqlSessionFactory,那么相对于单纯的去调用DefaultSqlSessionFactory返回的结果是一致的。

public class SqlSessionManager implements SqlSessionFactory, SqlSession {
    //用来实现SqlSessionFactory功能
    private final SqlSessionFactory sqlSessionFactory;
    //用来实现SqlSession功能
    private final SqlSession sqlSessionProxy;
    private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal();
    // ........
    //每次都会将创建的sqlsession加入到本地线程中
     public void startManagedSession() {
        this.localSqlSession.set(this.openSession());
    }
}

与 DefaultSqlSessionFactory不同的是:

  • SqlSessionManager提供一个localSqlSession本地线程,每次在通过startManagedSession()来获取session实例存放到localSqlSession中。保证每个线程独享一份的SqlSession,保证调用SqlSession线程安全,但是非SqlSession的方法并不是线程安全。
  • 由于localSqlSession本地线程存在,保证在同一线程中实现不同的sql操作,都可复用本地线程session,避免重复创建DefaultSqlSessionFactory中的DefaultSqlSession重复创建。

所以说可以SqlSessionManager是DefaultSqlSessionFactory的优化。

(6)SqlSessionTemplate

因为是SqlSession的实现类,所以具有SqlSession的功能,可以进行操作数据库,但是增加单次操作的事务管理。

public class SqlSessionTemplate implements SqlSession, DisposableBean {
    private final SqlSessionFactory sqlSessionFactory;
    private final ExecutorType executorType;
    private final SqlSession sqlSessionProxy;
    private final PersistenceExceptionTranslator exceptionTranslator;
}

但是与 SqlSession又增加了一些其他的功能:

  • 可以配置或设置SqlSessionFactory,通过SqlSessionFactory中的SqlSession来实现操作数据库;(sqlSessionFactory与sqlSessionProxy的获取同SqlSessionManager)
  • 可以根据ExecutorType生成对应的SqlSession
  • 不同于SqlSession,事务操作需要手动提交。在DefaultSqlSession中默认情况下autoCommit是关闭的,在提交一次数据库的操作之后,需要手动去commit()才能更新数据库。而SqlSessionTemplate并不需要手动调用commit(),并且代码中也明确指出不支持手动调用,否则会抛出异常
    public void commit() {
        throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
    }

所以SqlSession和SqlSessionTemplate之间的关系就是Connection和JdbcTemplate之间的关系。

(7)SqlSessionDaoSupport

该类为抽象类。可以设置SqlSessionTemplate或SqlSessionFactory,不管有没有设置SqlSessionTemplate,最终SqlSessionFactory都是一个具有事务的SqlSessionFactory。在项目中通常需要继承该类,然后通过getSqlSessionTemplate()来执行操作数据库的操作。


public abstract class SqlSessionDaoSupport extends DaoSupport {
    private SqlSessionTemplate sqlSessionTemplate;

    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        if (this.sqlSessionTemplate == null || sqlSessionFactory != this.sqlSessionTemplate.getSqlSessionFactory()) {
            this.sqlSessionTemplate = this.createSqlSessionTemplate(sqlSessionFactory);
        }
    }

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }
  }

所以SqlSessionDaoSupport只不过是对增加了检验是否注入了SqlSessionTemplate和SqlSessionFactory,真正的实现操作数据库还是依赖于SqlSessionTemplate或SqlSessionFactory。我觉得和SqlSessionManager的作用差不多,只不过最终实现方式稍有差别。

每个业务相关的SqlSessionDaoSupport都要分别在Spring进行单独注册。

遗留问题:由于我们不同的业务类都需要继承 SqlSessionDaoSupport,那么是否涉及到重复创建和销毁SqlSessionTemplate和SqlSessionFactory呢?

暂时觉得应该不会的,因为SqlSessionFactory实例是通过xml配置的,在Spring容器加载的时候只会加载该一个实例,而这些SqlSessionDaoSupport的继承子类只不过是引入这个实例而已。


到目前为止,不管是SqlSessionManager、SqlSessionDaoSupport还是SqlSessionTemplate,都需要手动编写访问对象的代码,后面会通过一个例子来看下这三个是怎么读写数据库的。当然MyBatis也提供了一个简化这部分逻辑的一个类MapperFactoryBean。

(8)MapperFactoryBean

用来创建Mapper对象的。把Mapper接口映射成Mapper对象。通过动态代理的方式自动将注入数据映射接口以及的sqlSessionFactory来生成Spring中操作数据库的DaoSupport对象。(遗留问题:感觉这个有点类似HttpServlet与jsp之间的关系)。如果接口映射和具有业务逻辑的SQL映射进行一一匹配,那么该DaoSupport创建成功。


public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
   private Class<T> mapperInterface;

    public void setMapperInterface(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }
}

我们从代码中可以看到,相对于SqlSessionDaoSupport增加了一个mapperInterface,而这个mapperInterface就是数据映射接口(我觉得应该包括两部分:一部分将就是接口文件,另一部分就是那个Mapper文件)。

其实就可以理解为一个具有了自动访问对象的SqlSessionDaoSupport。那么每个业务相关的MapperFactoryBean都要分别在Spring进行单独注册。

(9)MapperScannerConfigurer

像刚才提到的MapperFactoryBean,在实际项目中,肯定会根据业务进行划分成不同的MapperFactoryBean,那么就需要在xml中一一进行配置。MyBatis也提供了一种可以自动查找在给定的类路径下的映射器,并自动将他们创建成MapperFactoryBean,然后注册到Spring中。

遗留问题:后面增加一个图再来更详细的描述下这几个元素的相互之间的联系

解决问题:终于经过几天在地铁上下班路上的时间,整理了这几个概念直接的关系如图所示:

通过这个图还是比较清晰的可以看到这些这几个类直接的关系:

  • (1)SqlSession是最终封装了读写数据库功能,默认的实现类为DefaultSqlSession;
  • (2)SqlSessionFactory是最终生产SqlSession,但是相比较于单纯的SqlSession,是从数据库连接池里拿出的一次就有事务管理的连接,默认的实现类为DefaultSqlSessionFactory;
  • (3)SqlSessionFactoryBean是注册在Spring中,用来生成一个SqlSessionFactory的bean;
  • (4)SqlSessionMananger、SqlSessionTemplate、SqlSessionDaoSupport、MapperFactoryBean、MapperScannerConfigurer都是对MyBatis来读写数据库的整个过程的封装,最终实现都是通过传入的SqlSessionFactory实例中动态代理获取SqlSession来读写数据库,只是在这过程中处理方式有所不同:SqlSessionMananger、SqlSessionTemplate、SqlSessionDaoSupport需要主动调用读写数据库的语句;而MapperFactoryBean、MapperScannerConfigurer可以自动执行语句。

三 Spring集成MyBatis

在小白新手web开发简单总结(十四)-MySQL的安装与简单使用中主要是通过JdbcTemplate来读写MySQL数据库,那么现在通过一个实例来看下Spring是怎么集成MyBatis以及MyBatis的几种读写数据的方式

  • 1.添加MyBatis依赖

MyBatis并不像Hibernate那样,Spring已经内置集成,所以在使用MyBatis的时候,除去引入MyBatis本身的库:

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.4</version>
        </dependency>

还需要增加一个与Spring的集成库:

       <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.4</version>
        </dependency>
  • 2.通过mybatis-generator生成实体model的Book.java以及Mapper映射文件BookMapper.java和BookMapper.xml

因为代码比较多,所以自行到项目中去查看代码:分别对应com.wj.mysql.model.Book、com.wj.mysql.model.BookMapper(还没有搞明白为什么不能和xml文件单独命名)以及resource/mysql/BookMapper.xml文件。

代码以及上传到github:https://github.com/wenjing-bonnie/sql-web.git对应的代码的tag为example15-xxx(因为项目在一直更新,所以通过打tag的方式来标记这次代码)

注意这里面的select()是根据业务需求新增的映射关系。 当然可以根据业务需求,自行增删。IDEA需要安装Free MyBatis plugin插件 ,才可以自动生成。另外还要注意一个问题就是,这个MyBatis不支持HSQLDB数据库,所以从这篇开始,在项目中使用MySQL数据库,之前在小白新手web开发简单总结(十四)-MySQL的安装与简单使用有简单的来介绍了一点MySQL数据库。

  • 3.添加MyBatis的配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <!--别名-->
    <typeAliases>
        <typeAlias alias="book" type="com.wj.mysql.model.Book"/>
    </typeAliases>
    <!--映射文件的位置-->
    <mappers>
        <mapper resource="mysql/BookMapper.xml"/>
    </mappers>

</configuration>

其中<typeAlias>是为com.wj.mysql.model.Book起了别名;<mappers>为生成的xml的文件的路径。

  • 4.增加Spring的注册的配置文件application-context-mysql.xml和相应的java代码来实现逻辑

相比较于小白新手web开发简单总结(十四)-MySQL的安装与简单使用的访问MySQL的不同,这里需要增加ORM相关的代码。下面通过四种不同的方式来实现访问MySQL数据库。

相同点:都需要先注入SqlSessionFactoryBean,用来产生SqlSessionFactory实例

    <!--配置SessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" name="sqlSessionFactory">
        <property name="dataSource" ref="mysqlDataSource"/>
        <property name="configLocation" value="classpath:config/mybatis-config.xml"/>
    </bean>

不同点:四种方法读写数据库的方式不同,下面分别去介绍:

(1)通过SqlSessionTemplate来读写数据库

1)在application-context-mysql.xml中增加SqlSessionTemplate注册

    <!--方法一:通过SqlSessionTemplate来读写数据库-->
        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" name="sqlSessionTemplate">
            <constructor-arg type="org.apache.ibatis.session.SqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>

2)查询数据代码逻辑

    //方法一
    @Resource
    private SqlSessionTemplate sqlSessionTemplate; 
   
    @Override
    public List<Book> select() {
        return selectByTemplate();
    }    
    private List<Book> selectByTemplate() {
        List<Book> books = sqlSessionTemplate.selectList("com.wj.mysql.model.BookMapper.select");
        return books;
    }

对应的tag为example15-SqlSessionTemplate 。

(2)通过DaoSupport来读写数据库

1)编写BookDaoSupport类继承SqlSessionDaoSupport


public class BookDaoSupport extends SqlSessionDaoSupport implements BookMapper {
  @Override
    public List<Book> select() {
        return getSqlSessionTemplate().selectList("com.wj.mysql.model.BookMapper.select");
    }
}

2)在application-context-mysql.xml中增加BookDaoSupport注册

    <!--方法二:通过DaoSupport来读写数据库-->
        <bean id="bookDaoSupport" class="com.wj.mysql.service.BookDaoSupport">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>

3)查询数据代码逻辑 (在对应的com.wj.mysql.service.BookServiceImpl)

    //方法二
    @Resource
    private BookDaoSupport bookDaoSupport;    

    @Override
    public List<Book> select() {
        return selectByDaoSupport();
    }
    private List<Book> selectByDaoSupport() {
        return bookDaoSupport.select();
    }

如果有多个业务逻辑类,那么就要去写多个类去继承SqlSessionDaoSupport,然后依次在Spring的配置文件中增加注册。

对应的tag为example15-SqlSessionDaoSupport。

(3)通过MapperFactoryBean来读写数据库

1)在application-context-mysql.xml中增加MapperFactoryBean注册

    <!--方法三:单个定义Book的mapper文件,为单个接口文件生成代理对象-->
        <bean id="bookMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
            <property name="mapperInterface" value="com.wj.mysql.model.BookMapper"/>
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>

2)查询数据代码逻辑(在对应的com.wj.mysql.service.BookServiceImpl)

    //方法三
    @Autowired
    private BookMapper bookService;
    @Override
    public List<Book> select() {
        return selectByMapper();
    }
    private List<Book> selectByMapper() {
        return bookService.select();
    }

如果有多个业务逻辑类,那么就要有多个MapperFactoryBean在Spring的配置文件中依次增加注册。

对应的tag为example15-Mapper。

(4)通过MapperScannerConfigurer来读写数据库

1)在application-context-mysql.xml中增加MapperScannerConfigurer注册

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.wj.mysql.model"/>
    </bean>

2)查询数据代码逻辑(在对应的com.wj.mysql.service.BookServiceImpl)

其中该逻辑与(3)通过MapperFactoryBean来读写数据库中的方式一致,只不过是省去了将多个业务逻辑类的依次注册过程,MapperScannerConfigurer会自行扫描对应的basePackage下面的所有文件。

对应的tag为example15-MapperScannerConfigurer。

所有的代码以及上传到github:https://github.com/wenjing-bonnie/sql-web.git对应的代码的tag为example15-xxx(因为项目在一直更新,所以通过打tag的方式来标记这次代码)。可以分别切换到不同的tag,运行项目成功之后,可以通过“http://localhost:8080/mybatis”来依次查看对应的结果。前提是本地已经有了一个MySql数据库的服务,具体的MySql数据库的配置信息在jdbc.properties配置文件中。

相比较小白新手web开发简单总结(十四)-MySQL的安装与简单使用中通过JdbcTemplate来读写数据库,还需要将返回的表数据映射成实体对象,要方便很多。

四 总结

  • 1.无法读取.properties中的配置项,提示Cannot load JDBC driver class '${jdbc.mysql.driverClass}'”

问题:在集成MyBatis,数据库的相关信息配置在.properities中,使用MapperScannerConfigurer来配置映射文件的时候,如下:

   
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" name="sqlSessionFactory">
        <property name="dataSource" ref="mysqlDataSource"/>
        <property name="configLocation" value="classpath:config/mybatis-config.xml"/>
    </bean>    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.wj.mysql.model"/>
   </bean>

结果抛出以下异常“Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.mysql.driverClass}'”

Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.mysql.driverClass}'
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:418)
	at com.wj.mysql.service.MysqlBookManagerService.createDatabase(MysqlBookManagerService.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)

原因:有些说  <property name="sqlSessionFactoryBeanName" ref="sqlSessionFactory"/>(这种方式在项目中直接报错,不知道具体其他的博客中的是怎么写的代码)其实更换成  <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>就可以解决这个问题,但是发现更改了之后,并不能解决问题。

最终原因是:在xml中配置了default-autowire="byName"属性,导致会提前初始化一些类。会认为里面的这些变量,当把${jdbc.mysql.driverClass}成字符串。另外在声明org.mybatis.spring.mapper.MapperScannerConfigurer的时候,如果只有一个DataSource,其实是不需要就没有必要去指定SqlSessionFactory或SqlSessionTemplate,MapperScannerConfigurer会自动装配sqlSessionFactory。

解决方案:去掉default-autowire="byName"

  • 2.MyBatis是一个ORM框架,可以简化DAO层代码,方便的将表数据转换成Java对象;
  • 3.SqlSession是真正的去读写数据库的类,是一个接口类,默认的实现类为DefaultSqlSession;
  • 4.SqlSessionFactory负责生成SqlSession,是从数据库连接池中获取的一次就有事务操作(如果配置事务则使用配置的事务,如果没有配置事务,使用MyBatis提供对的默认事务管理)的连接,是一个接口类,默认的实现类为DefaultSqlSessionFactory;
  • 5.SqlSessionFactoryBean负责生成SqlSessionFactory的实例,通常注册在Spring中,用来实例化一个SqlSessionFactory;
  • 6.SqlSessionManager实现了SqlSession和SqlSessionFactory,但最终SqlSession和SqlSessionFactory接口对应的功能,其实还是传入的SqlSessionFactory实例来实现SqlSessionFactory功能,通过动态代理从SqlSessionFactory中获取的SqlSession来实现SqlSession的功能;
  • 7.SqlSessionTemplate实现了SqlSession,最终其实还是通过动态代理获取传入的SqlSessionFactory中的SqlSession来实现SqlSession的功能,相比较于SqlSessionFactory的SqlSession,增加了单次操作的事务管理;
  • 8.SqlDaoSuppport是实现了Spring中的DaoSupport,增加了是否配置SqlSessionFactory或SqlSessionTemplate的操作,最终还是需要传入的SqlSessionFactory或SqlSessionTemplate来实现操作数据库;
  • 9.每个业务类,需要单独去继承SqlDaoSuppport,来完成对应的数据库操作;
  • 10.MapperFactoryBean是继承SqlDaoSuppprt,相比较开发者继承SqlDaoSuppport,不需要开发者去编写操作数据库的代码,只需要调用对应的方法就可以;
  • 11.每个业务类对应的MapperFactoryBean需要分别在Spring中注册,来完成对应的数据库操作;
  • 12.MapperScannerConfigurer可以省去对每个业务类对应的MapperFactoryBean一一在Spring中注册,可直接通过配置basePackage的方式,将所有的Mapper一一注册到Spring中。
  • 13.与Mapper相关的对应生成的.xml和接口文件,可根据业务需求进行增加和修改。接口文件就只添加接口,而xml文件要根据对应的xml规范增加相应的SQL语句来实现业务逻辑。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值