使用时需要在mysql数据库中执行文件中的user.sql,并修改spring-mybatis.xml中的连接信息
// 读取MyBatis配置文件InputStreaminputStream =Resources.getResourceAsStream("mybatis-config.xml");// 从配置文件中构建 SqlSessionFactory (全局只有一个,用于构建 SqlSession)SqlSessionFactorysessionFactory =newSqlSessionFactoryBuilder().build(inputStream);// 使用 SqlSessionFactory 创建 SqlSession(请求作用域,用后销毁)SqlSessionsession =sessionFactory.openSession(true);// 获取对应 MapperUserMappermapper =session.getUser(UserMapper.class);// 执行查询Useruser =mapper.findById(1);// 关闭 sessionsession.close();一、 对于SqlSessionFactoryBuilder ,使用sqlSessionFactoryBean (实现了Spring的FactoryBean)替代,用来创建SqlSessionFactory
<!-- 使用SqlSessionFactoryBean 替代 SqlSessionFactoryBuilder--><beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 指定数据源--> <propertyname="dataSource"ref="dataSource" /><!-- 使用 mapper 对应的xml文件路径--> <propertyname="mapperLocations"value="classpath*:sample/config/mappers/**/*.xml" /><!-- 还可注入其他属性,如configLocation等--></bean>
二、 对于SqlSession,提供SqlSessionTemplate, 它线程安全(可以简单理解为每次创建新的SqlSession),提供了执行SQL方法,翻译异常功能
// =============================主要源码===========================================publicclassSqlSessionTemplateimplementsSqlSession,DisposableBean {privatefinalSqlSessionFactorysqlSessionFactory;privatefinalExecutorTypeexecutorType;privatefinalSqlSessionsqlSessionProxy;publicSqlSessionTemplate(SqlSessionFactorysqlSessionFactory,ExecutorTypeexecutorType,PersistenceExceptionTranslatorexceptionTranslator) {// SqlSessionInterceptor会拦截,保证获取到新的 sqlSession来执行(线程安全)this.sqlSessionProxy = (SqlSession)newProxyInstance(SqlSessionFactory.class.getClassLoader(),newClass[] {SqlSession.class },newSqlSessionInterceptor()); }// 实现了sqlSession的执行操作方法@Overridepublic <T>TselectOne(Stringstatement) {returnthis.sqlSessionProxy.selectOne(statement); }// ...}privateclassSqlSessionInterceptorimplementsInvocationHandler {@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable {// 获取sqlSessionSqlSessionsqlSession =getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,SqlSessionTemplate.this.executorType,SqlSessionTemplate.this.exceptionTranslator);try {Objectresult =method.invoke(sqlSession,args);returnresult; }catch (Throwablet) {Throwableunwrapped =unwrapThrowable(t);// 包装处理异常throwunwrapped; } }}使用(只需注入 SqlSessionFactory)
<beanid="sqlSession"class="org.mybatis.spring.SqlSessionTemplate"> <constructor-argindex="0"ref="sqlSessionFactory" /></bean>
之后可以注入此 sqlSession正常使用
三、对于Mapper接口,提供了 MapperFactoryBean(可以为每个mapper声明一个MapperFactoryBean)
SqlSessionDaoSupport
// 主要方法如下,可以实现此类,通过 getSqlSession 方法获取 sqlSessionTemplate 执行// 通常的实现类是 MapperFactoryBeanpublicabstractclassSqlSessionDaoSupportextendsDaoSupport {privateSqlSessionTemplatesqlSessionTemplate;protectedSqlSessionTemplatecreateSqlSessionTemplate(SqlSessionFactorysqlSessionFactory) {returnnewSqlSessionTemplate(sqlSessionFactory); }publicSqlSessiongetSqlSession() {returnthis.sqlSessionTemplate; }}MapperFactoryBean
publicclassMapperFactoryBean<T>extendsSqlSessionDaoSupportimplementsFactoryBean<T> {privateClass<T>mapperInterface;@OverridepublicTgetObject()throwsException {returngetSqlSession().getMapper(this.mapperInterface); }}使用(提供SqlSessionFactory 与要实现的接口)
<beanid="userMapper"class="org.mybatis.spring.mapper.MapperFactoryBean"><!-- 指定接口,接口对应的mapper文件需要在sqlSessionFActory中指定--> <propertyname="mapperInterface"value="org.mybatis.spring.sample.mapper.UserMapper" /> <propertyname="sqlSessionFactory"ref="sqlSessionFactory" /></bean>
MapperFactoryBean 是一个 FactoryBean, 它会返回传入的 UserMapper 接口的实例,之后可以使用此方法
publicclassFooServiceImplimplementsFooService {privateUserMapperuserMapper;publicvoidsetUserMapper(UserMapperuserMapper) {this.userMapper =userMapper; }publicUserdoSomeBusinessStuff(StringuserId) {returnthis.userMapper.getUser(userId); }}四、使用 MapperScannerConfigurer 简化多个 MapperFactoryBean 声明,可以配置扫码的包,其下的接口会被自动创建成对应的 MapperFactoryBean
<!-- 扫描路径下的所有接口,自动将它们创建成 MapperFactoryBean--><beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"> <propertyname="basePackage"value="org.mybatis.spring.sample.mapper" /></bean>
使用时可以直接注入对应的Mapper接口使用