目录
前言
在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语句来实现业务逻辑。