错误信息:
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.task.dao.ProductDao.selectByUserId
网上寻找原因:对应的Mapper映射文件没有被成功扫描到
-
命名空间没有设置对或映射文件名和对应接口名不一致
<!--命名空间没问题--> <mapper namespace="com.task.dao.ProductDao"> <!--映射文件名和对应接口名也一致--> -
对应spring配置文件中的mybatis配置没有设置对
<!--配置扫描也没问题--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.task.dao" /> </bean> -
maven编译后,target目录下没有生成对应的Mapper映射文件
//对应target目录下也存在对应的Mapper映射文件
分析:
由于第一次使用spring中的ApplicationContextAware接口,并且这些方法都是在这里面执行的时候报错的。有可能是这里面的原因。
下面是实现ApplicationContextAware接口的类
public class StaticPageLoader implements ApplicationContextAware {
@Autowired
private InitService initService;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
init();
}
public void init() {
//这个会去调用对应UserDao
initService.init();
}
}
对应InitService中的方法
public class InitServiceImpl implements InitService {
@Autowired
private UserDao userDao;
...
public void init() {
...
userDao.selectDetailById();
...
}
...
}
对应的Mapper映射文件
<!--会将查询的结果映射到下面的resultMap中-->
<select id="selectDetailById" resultMap="selectDetailByIdResultMap">
SELECT * FROM t_user WHERE `id`=#{id}
</select>
<!--这里面有个select,会调用ProductDao.selectByUserId中的方法去查询-->
<!--报错就出在这里,但是对应的Dao和映射文件也没问题-->
<resultMap id="selectDetailByIdResultMap" type="com.task.pojo.User" extends="baseResultMap">
<collection property="products" ofType="com.task.pojo.Product"
select="com.task.dao.ProductDao.selectByUserId"
column="id"
></collection>
</resultMap>
于是,我就在StaticPageLoader类中写了一个方法,直接调用ProductDao和UserDao,然后运行调试看看
public class StaticPageLoader implements ApplicationContextAware {
@Autowired
private InitService initService;
@Autowired
private ProductDao productDao;
@Autowired
private UserDao userDao;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
test();
init();
}
public void init() {
//这个会去调用对应UserDao
initService.init();
}
public void test() {
System.out.println("测试。。。。。。。。。");
productDao.selectByUserId(5);
userDao.selectDetailById(5);
}
}
结果,运行没有问题。
然后又测试了几次,发现只要在init方法之前注入UserDao就可以。
猜测原因
猜猜原因:执行实现ApplicationContextAware的类中的setApplicationContext方法时,并不是所有Bean都已经被加载到了容器中。如果要使用这些Bean,可以使用getBean等方法。
原因有待验证。。。