一、问题
在Mybatis架构的最上层就是接口层,它定义的是与数据库交互的方式。还记不记得我们在前面章节说的那两种方式?不记得没关系,我们回忆一下。
-
Mybatis提供的API
使用Mybatis提供的API进行操作,通过获取SqlSession对象,然后根据Statement Id 和参数来操作数据库。
String statement = "com.viewscenes.netsupervisor.dao.UserMapper.getUserList";
List<User> result = sqlsession.selectList(statement);
-
mapper接口
定义Mapper接口,里面定义一系列业务数据操作方法。在Service层通过注入mapper属性,调用其方法就可以执行数据库操作。就像下面这样
public interface UserMapper {
List<User> getUserList();
}
@Service
public class UserServiceImpl implements UserService{
@Autowired
UserMapper userDao;
@Override
public List<User> getUserList() {
return userDao.getUserList();
}
}
那么,问题就来了。UserMapper 只是个接口,并没有任何实现类。那么,我们在调用它的时候,它是怎样最终执行到我们的SQL语句的呢?
二、扫描
1、配置信息
说到这,我们就要看配置文件中的另外一个Bean。通过指定基本包的路径,Mybatis可以通过Spring扫描下面的类,将其注册为BeanDefinition对象。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.viewscenes.netsupervisor.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
或者有的朋友项目里还有个annotationClass的属性,即
<property name="annotationClass" value="org.springframework.stereotype.Repository" />
它的作用就是在扫描的包的时候,会过滤定义的annotationClass。如果有这个注解才会被扫描,通常会在类上以@Repository来标识。不过它的作用也仅是为了过滤而已,我们也完全可以自定义这个注解。比如:
@MyDao
public interface UserMapper {}
<property name="annotationClass" value="com.viewscenes.netsupervisor.util.MyDao" />
当然了,如果你确定基本包路径下的所有类都要被注册,那就不必配置annotationClass。
2、扫描基本包
我们来到 org.mybatis.spring.mapper.MapperScannerConfigurer
这个类,可以看到它实现了几个接口。其中的重点是 BeanDefinitionRegistryPostProcessor
。它可以 动态的注册Bean信息,方法为 postProcessBeanDefinitionRegistry()
。
publ