【mybatis】02-spring集成&扩展
参考:https://mybatis.org/spring/zh_CN/
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession
并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException
。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
IDEA插件:Free mybatis plugin
1、自动对Mapper.java和Mapper.xml进行跳转关联
2、只在mapper.java定义函数,通过alt+enter生成xml的mapper语句
一、SqlSessionFactoryBean
SqlSessionFactory是mybatis的核心,当与spring进行整合时,我们使用mybatis-spring提供的SqlSessionFactoryBean来创建其实例,SqlSessionFactoryBean实现了FactoryBean 接口。
web.xml中指定的spring配置
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 指定mapper.xml配置文件 --> <property name="mapperLocations" value="classpath:mybatis/BoardMapper.xml" />
</bean>
java实现:
@Repository public class BoardMybatisDao extends BaseMybatisDao<User> { @Autowired SqlSessionFactory sqlSessionFactory; public List<Board> getAllBoards() { SqlSession sqlSession = sqlSessionFactory.openSession(); List<Board> allBoards = sqlSession.getMapper(BoardMapper.class).getAllBoards(); return allBoards; } }
二、开启Spring事务
MyBatis-Spring 借助了 Spring 中的 DataSourceTransactionManager
来实现事务管理。一旦配置好了 Spring 的事务管理器,你就可以在 Spring 中按你平时的方式来配置事务。并且支持 @Transactional
注解和 AOP 风格的配置。
在事务处理期间,一个单独的 SqlSession
对象将会被创建和使用。当事务完成时,这个 session 会以合适的方式提交或回滚。
事务配置好了以后,MyBatis-Spring 将会透明地管理事务。这样在你的 DAO 类中就不需要额外的代码了。
在 Spring 的配置文件中创建一个 DataSourceTransactionManager
对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean>
三、使用 SqlSession(不推荐)
使用 MyBatis-Spring 之后,不再需要直接使用 SqlSessionFactory;
bean 可以被注入一个线程安全的 SqlSession
,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。
方案1:基于SqlSessionTemplate
SqlSessionTemplate
是 MyBatis-Spring 的核心。作为 SqlSession
的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的 SqlSession
。 SqlSessionTemplate
是线程安全的,可以被多个 DAO 或映射器所共享使用。
当调用 SQL 方法时(包括由 getMapper()
方法返回的映射器中的方法),SqlSessionTemplate
将会保证使用的 SqlSession
与当前 Spring 的事务相关。 此外,它管理 session 的生命周期,包含必要的关闭、提交或回滚操作。另外,它也负责将 MyBatis 的异常翻译成 Spring 中的 DataAccessExceptions
。
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
现在,这个 bean 就可以直接注入到你的 DAO bean 中了。你需要在你的 bean 中添加一个 SqlSession 属性,就像下面这样:
public class UserDaoImpl implements UserDao { private SqlSession sqlSession; public void setSqlSession(SqlSession sqlSession) { this.sqlSession = sqlSession; } public User getUser(String userId) { return sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); } }
按下面这样,注入 SqlSessionTemplate
:
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl"> <property name="sqlSession" ref="sqlSession" /> </bean>
方案2:基于SqlSessionDaoSupport
SqlSessionDaoSupport
是一个抽象的支持类,用来为你提供 SqlSession
。调用 getSqlSession()
方法你会得到一个 SqlSessionTemplate
,之后可以用于执行 SQL 方法
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { public User getUser(String userId) { return getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); } }
四、注入Mapper(推荐)
与其在数据访问对象(DAO)中手工编写使用 SqlSessionDaoSupport
或 SqlSessionTemplate
的代码,还不如让 Mybatis-Spring 为你创建一个线程安全的映射器,这样你就可以直接注入到其它的 bean 中了
<bean id="fooService" class="org.mybatis.spring.sample.service.FooServiceImpl"> <constructor-arg ref="userMapper" /> </bean>
注入完毕后,映射器就可以在你的应用逻辑代码中使用了:
注意代码中并没有任何的对 SqlSession
或 MyBatis 的引用。你也不需要担心创建、打开、关闭 session,MyBatis-Spring 将为你打理好一切。
public class FooServiceImpl implements FooService { private final UserMapper userMapper; public FooServiceImpl(UserMapper userMapper) { this.userMapper = userMapper; } public User doSomeBusinessStuff(String userId) { return this.userMapper.getUser(userId); } }
1)方案(不推荐):直接注册映射器
方案1:XML
在你的 XML 中加入 MapperFactoryBean
以便将映射器注册到 Spring 中。
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
如果映射器接口 UserMapper 在相同的类路径下有对应的 MyBatis XML 映射器配置文件,将会被 MapperFactoryBean
自动解析。不需要在 MyBatis 配置文件中显式配置映射器,除非映射器配置文件与接口类不在同一个类路径下。 参考 SqlSessionFactoryBean
的 configLocation
属性以获取更多信息。
注意 MapperFactoryBean
需要配置一个 SqlSessionFactory
或 SqlSessionTemplate
。它们可以分别通过 sqlSessionFactory
和 sqlSessionTemplate
属性来进行设置。 如果两者都被设置,SqlSessionFactory
将被忽略。由于 SqlSessionTemplate
已经设置了一个 session 工厂,MapperFactoryBean
将使用那个工厂。
方案2:Java Config
@Configuration public class MyBatisConfig { @Bean public MapperFactoryBean<UserMapper> userMapper() throws Exception { MapperFactoryBean<UserMapper> factoryBean = new MapperFactoryBean<>(UserMapper.class); factoryBean.setSqlSessionFactory(sqlSessionFactory()); return factoryBean; } }
2)方案(推荐):扫描发现映射器
不需要一个个地注册你的所有映射器。你可以让 MyBatis-Spring 对类路径进行扫描来发现它们。有几种办法来发现映射器:
- 使用
<mybatis:scan/>
元素 - 使用
@MapperScan
注解 - 在经典 Spring XML 配置文件中注册一个
MapperScannerConfigurer -- 推荐
<mybatis:scan/>
和 @MapperScan
都在 MyBatis-Spring 1.2.0 中被引入。@MapperScan
需要你使用 Spring 3.1+。
从 2.0.2 版本开始,mapper 扫描机制支持控制 mapper bean 的懒加载 (lazy-initialization
) ,这个选项是可选的。 添加这个选项是为了支持 Spring Boot 2.2 中的懒加载特性。 默认的选项值为 false
(即不开启懒加载)。 如果开发者想使用懒加载的特性,需要显式地将其设置为 true
.
1. <mybatis:scan>
<mybatis:scan base-package="org.mybatis.spring.sample.mapper" />
base-package
属性允许你设置映射器接口文件的基础包。通过使用逗号或分号分隔,你可以设置多个包。并且会在你所指定的包中递归搜索映射器。
不需要为 <mybatis:scan/>
指定 SqlSessionFactory
或 SqlSessionTemplate
,这是因为它将使用能够被自动注入的 MapperFactoryBean
。但如果你正在使用多个数据源(DataSource
),自动注入可能不适合你。 在这种情况下,你可以使用 factory-ref
或 template-ref
属性指定你想使用的 bean 名称。
2. @MapperScan
当你正在使用 Spring 的基于 Java 的配置时(也就是 @Configuration
),相比于使用 <mybatis:scan/>
,你会更喜欢用 @MapperScan
。
@Configuration @MapperScan("org.mybatis.spring.sample.mapper") public class AppConfig { // ... }
这个注解具有与之前见过的 <mybatis:scan/>
元素一样的工作方式。它也可以通过 markerInterface
和 annotationClass
属性设置标记接口或注解类。 通过配置 sqlSessionFactory
和 sqlSessionTemplate
属性,你还能指定一个 SqlSessionFactory
或 SqlSessionTemplate
。
NOTE 从 2.0.4 起,如果 basePackageClasses
或 basePackages
没有定义, 扫描将基于声明这个注解的类所在的包。
3. MapperScannerConfigurer(推荐)
MapperScannerConfigurer
是一个 BeanDefinitionRegistryPostProcessor
,这样就可以作为一个 bean,包含在经典的 XML 应用上下文中。为了配置 MapperScannerConfigurer
,使用下面的 Spring 配置:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="org.mybatis.spring.sample.mapper" /> </bean>
如果你需要指定 sqlSessionFactory
或 sqlSessionTemplate
,那你应该要指定的是 bean 名而不是 bean 的引用,因此要使用 value
属性而不是通常的 ref
属性:
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
在 MyBatis-Spring 1.0.2 之前,sqlSessionFactoryBean
和 sqlSessionTemplateBean
属性是唯一可用的属性。 但由于 MapperScannerConfigurer
在启动过程中比 PropertyPlaceholderConfigurer
运行得更早,经常会产生错误。基于这个原因,上述的属性已被废弃,现在建议使用 sqlSessionFactoryBeanName
和 sqlSessionTemplateBeanName
属性。
Interceptor 拦截器
拦截器可以拦截ParameterHandler、ResultSetHandler、StatementHandler、Executor的执行,我们可以实现:
1、分页插件;
2、Sql语句分析,可以防止全表更新、删除语句执行;
3、字段加密、解密;
4、dao执行耗时统计埋点、慢sql分析上报;
5、动态数据源切换;
等等各种场景
public interface Interceptor {
Object intercept(Invocation var1) throws Throwable;
default Object plugin(Object target) {
return Plugin.wrap(target, this);
}
default void setProperties(Properties properties) {
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理