该项目的环境为:
Java:1.7
使用的IDE是:
IDEA
使用的Jar包为:
spring:4.3.12.RELEASE
mybatis:3.4.1
mybatis-spring:1.3.0
并且使用了通用Mapper
com.github.abel533:3.0.0
出现的问题为:在使用了@Service注解的类中使用@Autowired注入Mapper接口时,IDEA提示:不能自动注入,没有该类型的Beans,也就是容器中没有Mapper接口。
先看配置:
<context:component-scan base-package="com.jblog" />
......
<!-- sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml" />
<property name="mapperLocations" value="classpath:mapper/*.xml" />
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.jblog.manager.pojo"/>
</bean>
<!-- 开启注解扫描
<context:component-scan base-package="com.devin.*"></context:component-scan>-->
<!-- mapper扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.jblog.manager.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
可以确定上面的包名还有xml文件路径都没有问题。
还有mybatis的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 驼峰自动映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 注意插件的顺序,优先执行分页助手 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="rowBoundsWithCount" value="true" />
</plugin>
<plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
<!--主键自增回写方法,默认值MYSQL,详细说明请看文档 -->
<property name="IDENTITY" value="MYSQL" />
<!--通用Mapper接口,多个通用接口用逗号隔开 -->
<property name="mappers" value="com.github.abel533.mapper.Mapper" />
</plugin>
</plugins>
</configuration>
再看看java代码:
IService接口:
/**
* 通用接口
*/
public interface IService<T> {
T selectByKey(Object key);
int save(T entity);
int delete(Object key);
int updateAll(T entity);
int updateNotNull(T entity);
List<T> selectByExample(Object example);
}
BloggerService接口:
public interface BloggerService extends IService<Blogger> {
Blogger getByUserName(String userName);
}
BaseService类:
public class BaseService<T> implements IService<T> {
@Autowired
protected Mapper<T> mapper;
@Override
public T selectByKey(Object key) {
return mapper.selectByPrimaryKey(key);
}
@Override
public int save(T entity) {
return mapper.insert(entity);
}
@Override
public int delete(Object key) {
return mapper.deleteByPrimaryKey(key);
}
@Override
public int updateAll(T entity) {
return mapper.updateByPrimaryKey(entity);
}
@Override
public int updateNotNull(T entity) {
return mapper.updateByPrimaryKeySelective(entity);
}
@Override
public List<T> selectByExample(Object example) {
return mapper.selectByExample(example);
}
BloggerServiceImpl类:
@Service("bloggerService")
public class BloggerServiceImpl extends BaseService<Blogger> implements BloggerService {
@Autowired
private BloggerMapper bloggerMapper;
@Override
public Blogger getByUserName(String userName) {
Example example = new Example(Blogger.class);
Example.Criteria criteria = example.createCriteria();
if(StringUtil.isNotEmpty(userName)) {
criteria.andEqualTo("userName", userName);
}
List<Blogger> bloggers = selectByExample(example);
return bloggers.size() > 0 ? bloggers.get(0) : null;
}
}
如果把
@Autowired
private BloggerMapper bloggerMapper;
去掉,单单使用通用接口的方法,不往service注入自定义的接口,可以顺利地继续数据库操作。
网上百度了找了很多方法,说是配置文件的问题,我也照改了,并不起作用;还有在BaseService上加上abstract修饰符等等,都解决不了问题。
而且BaseService中成功地注入了通用Mapper啊,于是往BloggerServiceImpl类中也注入通用Mapper,发现报了一样的错误,于是把@Service("bloggerService")
去掉,发现错误没有了,于是把所有的Mapper接口都注入到BaseService解决了问题。
可是我就是想在对应的service中注入Mapper接口,既然容器中没有Mapper接口,那么手动使用@Repository注解,通过注解扫描把Mapper接口放到容器中呢?尝试了一下,也可以解决问题。
难道使用MapperScannerConfigurer扫描到的Mapper接口跟使用@Service注解标注的service类存放的容器不是同一个吗?好像也不太可能吧,本人小白,想不通。
之前的项目也没有存在这样的问题啊,一样的配置文件,区别是没有用到通用Mapper。看了别人使用通用Mapper,还是一样的配置文件,一样的写法,也不需要@Repository注解,是可以在@Service标注的类中使用@Autowired的。
本人的水平非常有限,虽然解决了问题,可是依旧没有找到问题的根源,希望看到该博文的知道问题的前辈可以指点迷津,万分感谢!
没有及时更新,很抱歉。
在IDEA中,settings->inspections->spring->autowriting for bean class,把ERROR改成WARNING,虽然一样提示容器中没有bean,但是项目可以正常运行,本人觉得是IDEA的问题。