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); }
- 未完待续
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。