spring 整合mybatis的问题

javaEasy 发布于 2013/09/02 10:49
阅读 2K+
收藏 0

在Spring整合mybatis的过程中,我的application.xml的配置是这样的:

<!-- 注解式事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- one myBatis文件配置 org.springframework.orm.ibatis3.SqlSessionFactoryBean -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"
value="classpath:config/mybatis-config.xml" />
</bean>
<!--使用自动扫描包的方式来注册各种Mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mms.hhs.webs.system.dao" />
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> -->
</bean>
现在的问题是,我没有使用get和set 让dao注入到service层中,那么我在service中怎样调用 这个dao借口啊,还有在@Controller 中怎样调用service啊,求大神指点啊。

加载中
0
Beyond-Bit
Beyond-Bit

引用来自“javaEasy”的答案

引用来自“Beyond-Bit”的答案

service的包也要在这自动扫描专配吗?

你的service   class不是通过

@Service
public class UserServiceImpl implements UserService
注入的嘛、

所以你的: 

<context:component-scan base-package="com.mms.hhs.webs.system.javaBean" />

也需要扫描到service、

改成:

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

他会从你的基础包开始扫描到你的最后的包结构、


再给你一个官方的doc

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-annotation-config

如你所说:改成:

<context:component-scan base-package="com.mms.hhs.webs.system" >
后报错:
java.lang.ClassCastException: $Proxy10 cannot be cast to com.mms.hhs.webs.system.service.UserService
	at com.mms.hhs.webs.system.javaBean.UsersBean.getSyUserList(UsersBean.java:131)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)


现在的问题是你<tx:annotation-driven transaction-manager="transactionManager" />的问题、


 Spring的文档中这么写的:Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。如果被代理的目标实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。


        所以,解决办法是,如果用JDK动态代理,就必须为被代理的目标实现一个接口(要注意的地方是:需要将ctx.getBean()方法的返回值用接口类型接收);如果使用CGLIB强制代理,就必选事先将CGLIB包导入项目,设置beanNameAutoProxyCreator的proxyTargetClass属性为true。


即修改为:

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

0
javaEasy
javaEasy

刚才没有粘贴好,从新粘贴一下:

<!-- 注解式事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- one myBatis文件配置 org.springframework.orm.ibatis3.SqlSessionFactoryBean -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"
value="classpath:config/mybatis-config.xml" />
</bean>
<!--使用自动扫描包的方式来注册各种Mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mms.hhs.webs.system.dao" />
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> -->
</bean>

0
Beyond-Bit
Beyond-Bit
@Autowired

private Dao entityDao;


注入dao即可

0
飘逸的逸
飘逸的逸

用的注解:

<!-- 添加注解驱动 -->  
<mvc:annotation-driven />

定义一个工具类:


public final class SpringUtil implements ApplicationContextAware {

	private static ApplicationContext context;
	private static SqlSessionFactory sqlSessionFactory = null;  

	@SuppressWarnings("static-access")
	@Override
	public void setApplicationContext(ApplicationContext contex)
			throws BeansException {
		this.context = contex;
	}

	public static Object getBean(String beanName) {
		return context.getBean(beanName);
	}

	public static String getMessage(String key) {
		return context.getMessage(key, null, Locale.getDefault());
	}
	
	public static SqlSessionFactory getSqlSessionFactory(){  
        try {  
        	sqlSessionFactory = (SqlSessionFactory)SpringUtil.getBean("sqlSessionFactory");
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return sqlSessionFactory;
    }  
	
	public static String getLoginUser(){
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();  
		HttpServletRequest request = ((ServletRequestAttributes)ra).getRequest();
		return request.getSession().getAttribute("LOGIN_USER").toString();  
	}
	
}
service Impl层



@Service
public class OrderServiceImpl implements OrderService {}
Controller:


OrderServiceImpl service = (OrderServiceImpl)SpringUtil.getBean("orderServiceImpl");

0
javaEasy
javaEasy

引用来自“Beyond-Bit”的答案

@Autowired

private Dao entityDao;


注入dao即可

不知道为什么好像有点问题:

这是我的service的实现类:

@Service
public class UserServiceImpl implements UserService{

	@Autowired
	private UsersMapper uMapper;

/**
     * 方法描述:获取所有的数据,转化为json 后 传回前台页面
     * @param request
     * @param response
     * @return
     */
 @RequestMapping(value="/getUsersList.do", method=RequestMethod.POST)
 public String getSyUserList(HttpServletRequest request, HttpServletResponse response) {
 try {
//			    SqlSession sqlSession=mysql_factory.openSession(); 
//				SyUserMapper syUserMapper=sqlSession.getMapper(SyUserMapper.class);;
//				List userlist=syUserMapper.selectAllSyUser();
    request.setCharacterEncoding("UTF-8");
   
    //List userlist=((UserService)getBeansNoRequest("usersMapper")).selectAllUsers();
    List userlist=this.userService.selectAllUsers();
 String pageIndex = request.getParameter("page");
 String pageSize = request.getParameter("rp");
 PageModel pm = new PageModel(userlist, Integer.parseInt(pageSize));
 List ls = pm.getObjects(Integer.parseInt(pageIndex));
 /**
 * ajax异步将json数据返回给前端
 */
 JSONArray jsonList = new JSONArray();
 Map row =new HashMap();
 Map rowdata =null;
 for(int i = 0;i<ls.size();i++){
 rowdata = (Map)ls.get(i);
 row.put("id", rowdata.get("ID"));
 row.put("cell", new Object[] { 
 (rowdata.get("UID")),
 (rowdata.get("UNAME")),
 (rowdata.get("UAGE")),
 (rowdata.get("UADRESS")),
 (rowdata.get("UPWD")),});
 jsonList.put(row);
 }
 Map map= new HashMap();
 map.put("total", userlist.size());
 map.put("page",pageIndex);
 map.put("rows", jsonList);
 JSONObject data = new JSONObject(map);
 response.setCharacterEncoding("UTF-8");
 response.getWriter().write(data.toString());
 response.getWriter().flush();
 response.getWriter().close(); 
 } catch (Exception e) {
 e.printStackTrace();
 }
 return  "/test/test1";
 }

}
这个是我的spring-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
	<!-- 测试没有用连接池 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="url">
			<value>
				jdbc:mysql://127.0.0.1:3306/cateinfo?useUnicode=true&amp;characterEncoding=utf-8
			</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value>root</value>
		</property>
	</bean>
	<!-- 事务配置 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- 注解式事务管理 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<!-- one myBatis文件配置 org.springframework.orm.ibatis3.SqlSessionFactoryBean -->
	<bean id="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation"
			value="classpath:config/mybatis-config.xml" />
	</bean>
	<!-- 注册mapper方式一(手动注册)-->
	<!--<bean id="UsersMapper"
		class="org.mybatis.spring.mapper.MapperFactoryBean">
		<property name="mapperInterface"
		value="com.mms.hhs.webs.dao.UsersMapper" />
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
		</bean>  -->
	<!-- 注册Mapper方式二:也可不指定特定mapper,而使用自动扫描包的方式来注册各种Mapper ,它将会查找类路径下的映射器并
		自动将它们创建成MapperFactoryBeans,bean的命名规则使用Spring对自动侦测组件默认的命名策略来命名(第一个字母小写),
		之后自动装配SqlSessionFactory或SqlSessionTemplate,如果有多个dataSource,
		自动装载将会失效,-->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.mms.hhs.webs.system.dao" />
		<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> -->
	</bean>
	<!-- 把mybatis映射器文件注册到单独的配置文件 application-service.xml中,然后引入包 -->
	<!--  	<import resource="classpath:config/application-service.xml" />  -->
</beans>

0
Beyond-Bit
Beyond-Bit

你的spring 配置还差自动扫描注解bean,加上

<context:component-scan base-package="你的基础包" >
  <context:include-filter type="regex" expression=".service.*"/><!--service层注解-->
</context:component-scan>

0
javaEasy
javaEasy

引用来自“Beyond-Bit”的答案

你的spring 配置还差自动扫描注解bean,加上

<context:component-scan base-package="你的基础包" >
  <context:include-filter type="regex" expression=".service.*"/><!--service层注解-->
</context:component-scan>

这个是我的spring-servlet.xml刚才粘贴错了,粘贴的是application.xml了:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
	<!-- 加载配置javabean所在的位置 对包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能  需要更改-->
	<context:component-scan base-package="com.mms.hhs.webs.system.javaBean" />
	<tx:annotation-driven />

	<bean id="handlerMapping"
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
		<!-- 拦截器配置 -->
		<property name="interceptors">
			<list>
				<bean class="com.mms.hhs.webs.servlet.FiterInterceptor" />
			</list>
		</property>

	</bean>

	<bean
		class="org.springframework.web.servlet.view.BeanNameViewResolver" />
	<bean id="articleXmlView"
		class="org.springframework.web.servlet.view.xml.MarshallingView">
		<constructor-arg>
			<bean
				class="org.springframework.oxm.xstream.XStreamMarshaller">
				<property name="autodetectAnnotations" value="true" />
			</bean>
		</constructor-arg>
	</bean>
	<!--对模型视图名称的解析,即在模型视图名称添加前后缀  -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/" />
		<property name="suffix" value=".jsp"></property>
	</bean>
	<bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<property name="messageConverters">
			<list>
				<ref bean="mappingJacksonHttpMessageConverter" />
			</list>
		</property>

	</bean>
	<!-- 使用 Jackson 的 ObjectMapper 读取/编写 JSON 数据。它转换媒体类型为 application/json 的数据。spring返回json的数据类型-->
	<bean id="mappingJacksonHttpMessageConverter"
		class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />


</beans>
其中这个路径是我的@Controller类所在包,service的包也要在这自动扫描专配吗?
0
Beyond-Bit
Beyond-Bit

service的包也要在这自动扫描专配吗?

你的service   class不是通过

@Service
public class UserServiceImpl implements UserService
注入的嘛、

所以你的: 

<context:component-scan base-package="com.mms.hhs.webs.system.javaBean" />

也需要扫描到service、

改成:

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

他会从你的基础包开始扫描到你的最后的包结构、


再给你一个官方的doc

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-annotation-config

0
雪龙魂

this.userService.selectAllUsers();这句肯定不对,我也是刚搞明白这套整合,不需要mybatis的配置文件完全使用嵌入sql的注解接口即可。你的配置你再看看吧,我感觉少了点啥,如果需要我把我的配置给你看看!

0
雪龙魂
messageConverters这一段配置需要那么复杂吗?你有自己定义的bean?如果没有就去掉,不然会报错。不要相信官方的,因为没有配套配置说明基本没有用,除非你对spring很熟悉很熟悉!
返回顶部
顶部