mybatis 个别集成到 spring 框架中应用,上面介绍如何在 spring 中应用 mybatis
-
创立 datasource 实例
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>xxx</value> </property> </bean>
-
创立 SqlSessionFactoryBean 实例
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="plugins"> <array> <bean class="com.learn.springmybatis.ExecutorInterceptor"></bean> </array> </property> </bean>
-
创立数据库操作的 bean
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.learn.springmybatis.UserDao"/> <property name="sqlSessionFactory" ref="sqlSession"></property> </bean>
当然还有具体 java 代码,这里不体现进去。列出上述配置次要阐明 mybatis 应用的大体流程。业务代码最终是拿数据库操作 bean 实例,如 userDao 去操作数据库。那咱们就从 userDao 开始吧,看看业务代码通过 mybatis 是如何和 db 打交道的。
userDao 的实例化过程
上面是 UserDao 的 java 代码,一个 Interface,外面除了有一个注解,啥都没有。那么它是如何实现数据插入的呢?
public interface UserDao {@Insert("insert into user ( id, name, title) values (#{id},#{name}, #{title})")
public int insert(User user);
}
-
userDao 是 MapperFactoryBean 创立的
从 xml 配置咱们能够得悉,userDao 是 MapperFactoryBean 创立,而 MapperFactoryBean 实现类 FactoryBean 接口,Spring 的 FactoryBean 能够依据须要创立不同类型的 bean通过 MapperFactoryBean 的 getObject 获取 userDao 实例
public T getObject() throws Exception {return this.getSqlSession().getMapper(this.mapperInterface); }
this.getSqlSession() 是 new SqlSessionTemplate(sqlSessionFactory)
最终进入 Configuration 的 getMapperpublic <T> T getMapper(Class<T> type, SqlSession sqlSession) {return this.mapperRegistry.getMapper(type, sqlSession); }
最终调用到 MapperRegistry,具体代码如下,通过 type 在 knownMappers 获取 mapperProxyFactory,这里间接用 knownMappers,那么这个 knownMapper 什么时候初始化好的?先留个疑难,不焦急解答。获取到 mapperProxyFactory 后创立新的实例
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type); if (mapperProxyFactory == null) {throw new BindingException("Type" + type + "is not known to the MapperRegistry."); } else { try {return mapperProxyFactory.newInstance(sqlSession); } catch (Exception var5) {throw new BindingException("Error getting mapper instance. Cause:" + var5, var5); } } }
新实例如何创立?看代码,用到 java 的动静代理,sql 的执行,最终会代理到这个 MapperProxy 进行,想晓得 sql 如何执行,只需剖析 MapperProxy 即可。
protected T newInstance(MapperProxy<T> mapperProxy) {return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy); } public T newInstance(SqlSession sqlSession) {MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache); return this.newInstance(mapperProxy); }
- 未完待续