MyBatis-Spring官方文档 学习笔记
2017-10-31 00:33
579 查看
前言
之前也写过SpringMVC+
MyBatis+
Spring的小项目,但是对
MyBatis的了解还是不够深入,配置也只会生搬硬套。刚好求职失败,遂有空,去阅读以下
MyBatis-Spring的官方文档,深入学习一波。
什么是MyBatis-Spring?
MyBatis-Spring就是帮助你将
MyBatis代码无缝的整合到
Spring中。
Spring将会加载必要的
sqlSessionFactory类和
session类。
配置数据源
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:app.properties</value> </list> </property> </bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> <property name="maxPoolSize" value="20" /> <property name="minPoolSize" value="5" /> <property name="acquireIncrement" value="3" /> <property name="initialPoolSize" value="5"></property> </bean>
配置SqlSessionFactory
我们需要在Spring应用上下文定义一个SqlSessionFactory和数据源
dataSource。在
MyBatis-Spring中,
SqlSessionFacotoryBean调用其
getObject()方法去创建
SqlSessionFactory实例。创建
SqlSessionFactory实例中用到了享元设计模式,是一个种结构型模式。
享元模式(Flyweight Pattern):主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了极少对象数量从而改善应用所需的对象结构的方式。
优点:大大减少对象的创建,降低系统的内存,提供效率。
缺点: 提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部的状态而改变,否则会造成系统的混乱。
言归正传,首先在这个
SqlSessionFactoryBean类中,调用
getObject()时,会判断
sqlSessionFacotory是否为空,如果不为空直接返回
sqlSessionFacotory。如果为空,则调用
afterPropertiesSet()方法。
public SqlSessionFactory getObject() throws Exception { if (this.sqlSessionFactory == null) { afterPropertiesSet(); } return this.sqlSessionFactory; }
afterPropertiesSet()会检查
dataSource和
sqlSessionFactoryBuilder是否为空。接着会调用
buildSqlSessionFactory()方法。
public void afterPropertiesSet() throws Exception { notNull(dataSource, "Property 'dataSource' is required"); notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required"); this.sqlSessionFactory = buildSqlSessionFactory(); }
在
buildSqlSessionFactory()方法会读取
xml配置,然后创建
sqlSessionFactory实例。
protected SqlSessionFactory buildSqlSessionFactory() throws IOException { //...省略几百行代码 return this.sqlSessionFactoryBuilder.build(configuration); }
言归正传,配置如下:
mapperLocations: 我们存放
MyBatis的
mapper.xml文件路径。
typeAliasesPackage:一般对应着我们实体类所在的包。多个
package之间可以用逗号或者分号等来进行分隔。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="com.helping.wechat.model"></property> <property name="mapperLocations" value="classpath*:com/helping/wechat/model/**/mysql/*Mapper.xml" /> </bean>
事务
一个使用MyBatis-Spring的主要原因是它允许
MyBatis参与到
Spring的事务管理中,而不是给
MyBatis创建一个新的事务管理器。
MyBatis-Spring利用了存在
Spring中的
org.springframework.jdbc.datasource.DataSourceTransactionManager。我们可以通过配置
<tx:annotation-driven transaction-manager="transactionManager"/>来使用
@Transactional注解面对切面编程。同时我们也可以通常的
AOP来配置Service层的事务。在事务处理期间,一个单独的
SqlSession对象将会被创建和使用,当事务完成时,这个
Session就会以合适的方式进行提交和回滚。具体配置如下:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 当Service层的方法不是以delete,insert,update,save方法开头时,发生异常时无法进行事务回滚 但是可以通过@Transactional注解在类或者方法上,可以启动事务。 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 任何RuntimeException将触发事务回滚,但是任何Checked Exception不会触发事务回滚 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <t f7a8 x:method name="delete*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"/> <tx:method name="insert*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"/> <tx:method name="update*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"/> <tx:method name="save*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"/> <tx:method name="*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.helping.wechat.service..*.*(..))" id="pc"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pc" order="1"/> </aop:config>
使用SqlSession
在MyBatis中,我们可以使用
SqlSessionFactory来创建
SqlSession。一旦获得了一个
session之后,我们可以使用它来执行映射语句,提交或者回滚。当我们不需要它的时候,我们可以关闭
session。
而在
MyBatis-Spring之后,你不再需要
SqlSessionFactory了,我们的
Dao层可以注入一个线程安全的
SqlSession,然后进行提交或者回滚,最后关闭
session。
SqlSession Template
SqlSession Template是
MyBatis-Spring的核心,这个类负责
MyBatis的
SqlSession。
this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
我们可以知道
SqlSessionTemplate类的构造器第一个参数是
SqlSessionFactory的实例。
SqlSessionTemplate实现了
SqlSession接口。
public class SqlSessionTemplate implements SqlSession { //...省略n行 }
之前的我是这样配置的:
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <bean id="baseDao" abstract="true"> <property name="sqlSessionTemplate" ref="sqlSessionTemplate" /> </bean> <bean id="adminUserDao" class="com.helping.wechat.dao.admin.mybatis.AdminUserDao" parent="baseDao" />
其实没有必要去
Spring.xml去配置
Dao层,
Service层,
Controller类。可以用注解代替,后面会讲到。对了,
SqlSessionTemplate其实也不需要配,
SqlSession我们可以通过
new SqlSessionTemplate()创建出来。
SqlSessionDaoSupport
SqlSessionDaoSupport是一个抽象的支持类,为你提供
SqlSession。我们自定义的
Dao层的实现类继承它就行了。调用
getSession()做你想要的。
SqlSessionDaoSupport内部实现:
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;
}
/**
* Users should use this method to get a SqlSession to call its statement methods
* This is SqlSession is managed by spring. Users should not commit/rollback/close it
* because it will be automatically done.
*
* @return Spring managed thread safe SqlSession
* 返回线程安全的sqlSession
*/
public SqlSession getSqlSession() {
return this.sqlSession;
}
/**
* {@inheritDoc}
*/
protected void checkDaoConfig() {
notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
}
}
看到
getSession()方法的注释写着,用户不应该去提交,回滚,或者关闭
session的操作,因为
session会自动关闭它。这个方法返回的是一个线程安全的
sqlSession。
使用注解代替XML的配置
如果不使用注解,你的Spring.xml配置肯定是多的爆炸,比如这样:
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <bean id="baseDao" abstract="true"> <property name="sqlSessionTemplate" ref="sqlSessionTemplate" /> </bean> <bean id="adminUserDao" class="com.helping.wechat.dao.admin.mybatis.AdminUserDao" parent="baseDao" />
<bean id="adminUserService" class="com.helping.wechat.service.admin.impl.AdminUserService" >
<property name="adminUserDao" ref="adminUserDao" />
</bean>
<bean id="adminUserController" class="com.helping.wechat.controller.admin.AdminUserController" >
<property name="adminUserService" ref="adminUserService" />
</bean>
<bean id="ordinaryUserDao" class="com.helping.wechat.dao.admin.mybatis.OrdinaryUserDao" parent="baseDao" />
<bean id="ordinaryUserService" class="com.helping.wechat.service.admin.impl.OrdinaryUserService" >
<property name="ordinaryUserDao" ref="ordinaryUserDao" />
</bean>
<bean id="ordinaryUserController" class="com.helping.wechat.controller.admin.OrdinaryUserController" >
<property name="ordinaryUserService" ref="ordinaryUserService" />
</bean>
如果使用了
@Service,
@Component,
@Repository,
@Controller,
@Resource,
@Autowired这些注解,这些配置统统可以不要。首先要在
SpringMVC.xml配置自动扫描注解的
tag。
<context:component-scan base-package="com.helping.wechat.controller" /> <context:component-scan base-package="com.helping.wechat.handler" /> <context:component-scan base-package="com.helping.wechat.dao" /> <context:component-scan base-package="com.helping.wechat.service" />
@Service用于标注业务
Service层的类上,有
value这个属性。
@Service(value = "adminUserService") public class AdminUserService implements IAdminUserService { @Resource(name = "adminUserDao") private IAdminUserDao adminUserDao; }
@Controller用于标注控制
Controller层的类上。
@Controller @RequestMapping("/api/admin") public class AdminUserController extends BaseController { @Resource(name = "adminUserService") private IAdminUserService adminUserService; }
@Repository用于标注在
Dao层的类上,有
value这个属性。
@Repository(value = "adminUserDao") public class AdminUserDao extends SqlSessionDaoSupport implements IAdminUserDao { }
@Component就是把类注册到
Spring.xml文件中。
@Component
public abstract class BaseDao {
protected SqlSession sqlSession;
protected SqlSessionFactory sqlSessionFactory;
@Resource(name = "sqlSessionFactory")
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);}
public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
public SqlSession getSqlSession() {
return sqlSession;
}
}
Dao层的类继承它就行了,就可以调用
getSqlSession()进行想要的操作了。
@Resource默认按名称进行装配字段或者
setter方法。名称可以通过
name属性进行指定,如果没有指定
name属性。当注解写在字段上,默认按字段名进行安装名称查找,如果注解写在
setter方法上,默认按属性名进行装配,当找不到与名称相匹配的
bean时候,才会按照类型进行装配。如果
name属性指定了,那么就只能按名称进行装配了。
@Service(value = "adminUserService") public class AdminUserService implements IAdminUserService { @Resource(name = "adminUserDao") private IAdminUserDao adminUserDao; }
@Autowired:默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要运行
null值,可以设置它的
required属性为
false。如果我们想要使用名称进行装配,可以结合
@Qualifier注解使用。
@Autowired public void setAdminUserService(IAdminUserService adminUserService) { this.adminUserService = adminUserService; }
尾言
明天去看看通用Mapper和
pageHelper怎么配置。晚安,地球人。
相关文章推荐
- spring 官方文档,学习笔记
- Rhyme/Spring5.0.2.RELEASE官方英文文档学习笔记(1) Introduction to the Spring IoC container and beans
- MyBatis学习笔记-Spring集成DAO层实现方式记录
- db4o_8.0对象数据库官方文档翻译_学习笔记三
- Spring Boot官方文档学习——使用Spring Boot
- Log4j2官方文档翻译、学习笔记之二——Appender的分类及常用类型示例
- Spring 官方文档第十六章笔记(2):DispatcherServlet
- Jinja2学习笔记暨官方文档的翻译
- Mybatis 学习笔记1 不整合Spring的方式使用mybatis
- DB2学习笔记 --- IBM官方 DB2数据库操作文档指南
- Mybatis学习笔记五:集成Spring
- ES权威指南[官方文档学习笔记]-2
- Spring Boot 官方文档学习(一)入门及使用
- ES权威指南[官方文档学习笔记]-44 How primary and replica shards
- ES权威指南[官方文档学习笔记]-28 What is a document?
- ES权威指南[官方文档学习笔记]-48 Multi-document patterns
- 个人学习笔记----基于Spring4.3.1+mybatis+postgresql+maven搭建的个人用调度平台(二)
- MyBatis 官方文档学习2---XML 映射配置文件
- Spring 4 官方文档学习(⑤)WebSocket支持
- 《Spring+Mybatis》拦截器实现用户权限认证学习笔记与代码