MyBatis Spring 集成源码解析
来源:互联网 发布:js判断ios是否安装app 编辑:程序博客网 时间:2024/06/06 09:05
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
1、Mybatis使用简介
1) SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
String resource = "org/mybatis/example/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2)SqlSession
从 SqlSessionFactory 中获取 SqlSession,既然有了 SqlSessionFactory ,顾名思义,我们就可以从中获得 SqlSession 的实例了。SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。例如:
SqlSession session = sqlSessionFactory.openSession();try { Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);} finally { session.close();}
诚然这种方式能够正常工作,并且对于使用旧版本 MyBatis 的用户来说也比较熟悉,不过现在有了一种更直白的方式。使用对于给定语句能够合理描述参数和返回值的接口(比如说BlogMapper.class),你现在不但可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。
例如:
SqlSession session = sqlSessionFactory.openSession();try { BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101);} finally { session.close();}
以上方法是单独使用Mybatis的方法。下面我们就来探究一下如何与Spring集成起来使用。
2、集成Spring配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.spring.framework.carl" /> <!-- Data Source --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/> <property name="user" value="root"/> <property name="password" value="ilovemysql^^^"/> <property name="maxPoolSize" value="150"/> <property name="minPoolSize" value="10"/> <property name="initialPoolSize" value="20"/> <property name="maxIdleTime" value="3600"/> <property name="acquireIncrement" value="10"/> <property name="idleConnectionTestPeriod" value="1800"/> </bean> <!-- 扫描对应的XML Mapper --> <bean id="userSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations"> <list> <value>classpath:com.spring.framework.carl.user.mapper/*.xml</value> </list> </property> </bean> <!-- 扫描对应的Java Mapper --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.spring.framework.carl.*.mapper"/> <property name="sqlSessionFactoryBeanName" value="userSqlSessionFactory"/> </bean></beans>
以上就是Spring与MyBatis集成的基本文件了。当然有更多配置比如DataSource用数据库连接用properties文件,配置更多的MyBatis属性,如分页插件等等。上面的配置文件只是做讲解使用。
3、集成Spring原理解析
与Spring集成可以分为3个步骤.
1. 把Java类对应的Mapper接口类纳入Spring中的IOC容器管理。
2. 把Java类对应的XML命名空间添加到Mybatis中的Configuration类中的mapperRegistry(用于管理Mybatis的Mapper).
3. 使用Spring中的IOC容器扩展FactoryBean获取到Mapper的实例。(第一步纳入Spring只是接口)
1.纳入SpringIOC容器管理
上面时序图的主要步骤:
利用Spring的扩展BeanFactoryPostProcessor,扫描指定包下面的Mapper类,把类转换成Spring中IOC的Bean对象BeanDefinition,然后注册到IOC容器。并把BeanDefinition的BeanClass替换为MapperFactoryBean.class,这是一个Spring中的FactoryBean.这就和后面第三步的获取Mapper实例结合起来了。具体的代码如下:
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) { GenericBeanDefinition definition; for (BeanDefinitionHolder holder : beanDefinitions) { 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(this.mapperFactoryBean.getClass()); 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); } } }
重点代码如下:
definition.setBeanClass(this.mapperFactoryBean.getClass());
2.初始化Mybatis中的Configuration
上面时序图的主要步骤:
利用Spring的扩展InitializingBean,在IOC容器初始化之前,BeanDefinition设置Properties之后初始化Mybatis的Configuration。把XML的命名空间,也就是步骤一对应的Mapper类注册到Configuration中。
3.获取Mapper实例
上面时序图的主要步骤:
利用Spring的扩展FactoryBean可以见之前的Blog – Spring bean 之 FactoryBean,来进行实例化Mapper。时间是我们的Service中依赖注入Mapper的时候。
4、调用MyBatis中的Mapper
熟悉Spring MVC的朋友都知道其中有一个DispatcherServlet用来分发HTTP的请求。那么MyBatis中也有一个分发(一家之言,嘻嘻),MapperProxy,这个类是实现了InvocationHandler。加上与Spring集成的时候生成实例是Proxy。没有错,就是Java的动态代理,可以参看我之前的Blog – Java JDK 动态代理,本文就到这,希望能成大家起到抛砖引玉的效果。
参考文章:Mybatis官网
- MyBatis Spring 集成源码解析
- Mybatis-spring整合源码解析
- Mybatis JPA-集成方案+源码解析
- Spring集成Mybatis配置与源码分析
- 源码解析:spring + mybatis事务控制
- spring、mybatis加载xml源码解析
- Spring mybatis源码篇章-MybatisDAO文件解析
- Mybatis与Spring集成源码研究之MapperScannerConfigurer
- mybatis+spring源码解析(动态代理 spring初始化)
- mybatis注解+spring集成
- Spring集成MyBatis
- Spring集成Mybatis
- mybatis和spring集成
- spring 集成 mybatis
- Spring集成Mybatis
- spring 集成mybatis
- spring 集成mybatis
- spring mybatis 集成
- reloadRowsAtIndexPaths会闪一下解决方法
- Codeforce 707 A. Brain's Photos
- SQL SELECT(复杂查询) 之 等值查询 内外连接
- Redirection is not supported.解决
- HDU5038 讲道理在一大堆题里真的找不到会的东西的时候就连模拟我也能下的去手..
- MyBatis Spring 集成源码解析
- 词法分析☞正则表达式
- D3DXMatrixRotationAxis Function
- node之初识
- cmake基础
- Java面向对象的三大特征
- # Redis学习笔记
- 数据挖掘鄙视题-整理(多选)
- C++智能指针简单剖析