Spring与MyBatis整合优化

本文介绍两种MyBatis-Spring整合优化方案:使用MapperFactoryBean和MapperScannerConfigurer注入映射器,减少每次调用getMapper()方法的反射操作,提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在上一篇文章中,我们使用了老老实实的方式对两个框架进行了整合,我们在每一个服务层组件都声明了一个SqlSessionTemplate对象,在调用数据层的时候通过getMapper()方法映射得到某个接口,然后调用里面的方法。

直接在业务组件调用getMapper()方法并不是最佳选择,每一次调用这个方法就会做一次反射。mybatis-spring整合包中提供了相关组件,可以不必每次都调用getMapper()方法,而是通过配置的方式直接为业务对象注入映射器实现。接下来我们就对整合做一下优化。

优化前的要求

1、映射的命名空间(即映射文件的命名空间)要与映射器接口的包路径对应;

2、映射元素的id必须和映射器接口的方法名一致。

3、以下代码、修改都是基于上一篇博文的,各位可以先看一下上一篇博文的目录结构以及里面的代码,因为只需要在一些地方做修改,没必要再把所有代码都拿过来。

开始优化

第一种优化——使用MapperFactoryBean注入映射器

我们不再在服务层实现类中定义SqlSessionTemplate对象,而是定义它所依赖的接口,此处以UserServiceImpl为例。所需要的代码、以及目录结构与上一篇博文都一样,没有代码的朋友可以去上一篇博文找代码,或者自己撸。

package com.Blog.ServiceImpl;

import com.Blog.Dao.StudentDao;
import com.Blog.Entity.Student;
import com.Blog.Service.StudentService;
import org.apache.ibatis.annotations.Param;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("studentService")  //使用注解定义服务层Bean,可以删除配置文件中的配置
public class StudentServiceImpl implements StudentService {

    @Autowired
    @Qualifier("studentDao")
    private StudentDao studentDao;  //所依赖的Dao层接口

    @Override
    public Student getStudent(@Param("id") int id) {
        return studentDao.getStudent(id);
    }
}

 因为我们用注解的方式定义了Service层的一个Bean,所以可以将之前在配置文件中定义的id为studentService的Bean删除了。又因为我们不再显式直接使用SqlSessionTemplate对象,所以也可进行删除。综上,我们需要在spring-mybatis.xml中做的操作:

删除第三步、第四步,并在第二步之后加上以下代码:

<!--定义一个Bean,类即是org.mybatis.spring.mapper.MapperFactoryBean,指定它里面的mapperInterface是我们要指向的接口-->
    <bean id="studentDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.Blog.Dao.StudentDao" />
        <property name="sqlSessionFactory" ref="factory" />
    </bean>

因为我们是用注解定义的组件,所以不要忘了扫描我们的包:

<context:component-scan base-package="com.Blog.ServiceImpl" />

其他的都不需要动,运行测试类,是没有问题的。

那么MapperFactoryBean到底是一个什么东西呢?

MapperFactoryBean是SqlSessionDaoSupport的子类,需要通过一个SqlSessionFactory实例来创建SqlSessionTemplate实例,所以我们为其注入了一个id为factory的Bean组件。这个类还有一个属性是mapperInterface属性,即映射器接口,我们只需要指定为要映射的接口的路径,就相当于调用了getMapper()方法反射得到这个接口的信息。最后我们在StudentServiceImpl类中通过注解的方式为studentDao属性注入依赖,就可以调用相关的方法了。

需要注意的是,如果映射器对应的SQL映射文件与映射器的类路径相同,那么该映射文件可以自动被MapperFactoryBean解析,在配置SqlSessionFactoryBean时可以不用mapperLocations属性来扫描SQL映射文件。反之,仍然需要进行扫描引入。因为我们定义的接口和对应的映射文件不在同一包下,名称也不一样,所以我们还是手动扫描了。

第二种——使用MapperScannerConfigurer注入映射器

在上面的优化中,我们使用MapperFactoryBean对映射器进行配置,简化了DAO模块的编码。但是,如果有多个接口,即需要配置多个映射器的时候,相应的配置项就会变得很多。为了简化配置工作量,mybatis-spring整合包中提供了MapperScannerConfigurer,它可以扫描指定包中的接口,并为它们直接注册为MapperFactoryBean。

将第一种优化中配置MapperFactoryBean的代码替换为以下代码:

<!--使用MapperScannerConfigurer扫描指定包的接口,并自动生成MapperFactoryBean-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.Blog.Dao" />
    </bean>

运行也是没问题的。

basePackage属性中可以指定多个包,用逗号或分号隔开;

MapperScannerConfigurer会为所有由它创建的映射器开启自动装配。也就是说我们不用显式注入SqlSessionFactory实例,它会自动从容器中扫描。如果容器中有多个SqlSessionFactory实例,此时需要显式指定所依赖的SqlSessionFactory,如下

<!--使用MapperScannerConfigurer扫描指定包的接口,并自动生成MapperFactoryBean-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="factory" />
        <property name="basePackage" value="com.Blog.Dao" />
    </bean>

映射器被注入到容器中之后,Spring会根据其接口名称为其命名,规则是首字母小写的非完全限定类名。例如StudentDao接口,会被命名为studentDao,所以我们可以直接在StudentServiceImpl中为studentDao属性注入依赖。所以这就需要我们命名规范,养成良好的命名习惯。

总结

多对比几种实现方式,选择最好的方式!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值