最近一直项目中一直在使用Spring+SpringMVC+Mybatis 框架,根据自己对这三个框架的了解搭建了一个这样的工程(工程测试可用),期间遇到不少问题,跟大家分享下(具体代码下载地址在文章最后)。
文章分成两大模块:
一、工程代码模块;
二、配置信息和自我理解模块。
项目的工程目录结构是:
一、工程代码模块:
UserController.class
package cn.zyy.ssm.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.zyy.ssm.service.UserService;
@Controller
public class UserController {
@Autowired
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@RequestMapping("/list")
public String getList(ModelMap map){
map.addAttribute("list", userService.getList());
return "/list.jsp";
}
}
UserService接口:
package cn.zyy.ssm.service;
import java.util.List;
import cn.zyy.ssm.vo.User;
public interface UserService {
public List<User> getList();
}
UserServiceImpl.class
package cn.zyy.ssm.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.zyy.ssm.dao.UserDao;
import cn.zyy.ssm.service.UserService;
import cn.zyy.ssm.vo.User;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao useDao;
@Override
public List<User> getList() {
return useDao.getList();
}
}
UserDao接口
package cn.zyy.ssm.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import cn.zyy.ssm.vo.User;
@Repository("userDao")
public interface UserDao {
public List<User> getList();
}
User.class
package cn.zyy.ssm.vo;
public class User {
private int id;
private String name;
private String pwd;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
user.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zyy.ssm.dao.UserDao">
<select id="getList" resultType="User">
select id,name,pwd from user
</select>
</mapper>
applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
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/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 读取属性文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:db.properties"></property>
</bean>
<!-- 配置dataSource -->
<bean id = "dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置sqlSessionFactory: 将spring和mybatis整合-->
<bean id = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value=""></property>
<property name="mapperLocations" value="classpath:cn/zyy/ssm/xml/*.xml"></property>
<property name="typeAliasesPackage" value="cn.zyy.ssm.vo"/>
</bean>
<!--配置 MapperScannerConfigurer:将Mapper接口生成代理注入到Spring -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="basePackage" value="cn.zyy.ssm.dao"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id = "txManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务传播特性 -->
<tx:advice id = "txAdvice" transaction-manager = "txManage">
<tx:attributes>
<tx:method name="get" propagation = "REQUIRED"/>
<tx:method name="update" propagation = "REQUIRED"/>
<tx:method name="delete" propagation = "REQUIRED"/>
<tx:method name="insert" propagation = "REQUIRED"/>
<tx:method name="*" propagation = "REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* cn.zyy.ssm.*.*(..))" id="pointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
<!-- 进行包的自动扫描 -->
<context:component-scan base-package="cn.zyy.ssm"></context:component-scan>
</beans>
db.properties
jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test
jdbc.username = root
jdbc.password = 553226
springmvc.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 包的自动扫描 -->
<context:component-scan base-package="cn.zyy.ssm"></context:component-scan>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ssmTest</display-name>
<!-- spring的配置 文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springmvc(前端控制器)的配置文件 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table width="80%" align="center">
<tr>
<td>id</td>
<td>姓名</td>
<td>密码</td>
</tr>
<c:forEach items="${list }" var="bean">
<tr>
<td>${bean.id }</td>
<td>${bean.name }</td>
<td>${bean.pwd }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
以上就是全部的代码,大体是按照工程目录结构自上往下的顺序来整理的。
二、配置信息和自我理解模块
SSM整合的配置文件大概可分为三个:web.xml 、applicationContext.xml、SpringMvc.xml文件:web.xml主要用于加载前端控制器、加载各种配置文件和设置过滤器等;applicationContext.xml主要负责整合mybatis和spring的相关配置、SpringMvc.xml文件主要负责Springmvc的相关配置。
这里我重点说明下applicationContext.xml文件中的相关配置:
1、 关于MapperFactoryBean,我们知道在Mybatis的所有操作都是基于一个SqlSession的,而SqlSession是由SqlSessionFactory来产生的,SqlSessionFactory又是由SqlSessionFactoryBuilder来生成的。但是Mybatis-Spring是基于SqlSessionFactoryBean的。在使用Mybatis-Spring的时候,我们也需要SqlSession,而且这个SqlSession是内嵌在程序中的,一般不需要我们直接访问。SqlSession也是由SqlSessionFactory来产生的,但是Mybatis-Spring给我们封装了一个SqlSessionFactoryBean,在这个bean里面还是通过SqlSessionFactoryBuilder来建立对应的SqlSessionFactory,进而获取到对应的SqlSession。通过SqlSessionFactoryBean我们可以通过对其指定一些属性来提供Mybatis的一些配置信息。所以接下来我们需要在Spring的applicationContext配置文件中定义一个SqlSessionFactoryBean。
<!-- 配置sqlSessionFactory: 将spring和mybatis整合-->
<bean id = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value=""></property>
<property name="mapperLocations" value="classpath:cn/zyy/ssm/xml/*.xml"></property>
<property name="typeAliasesPackage" value="cn.zyy.ssm.vo"/>
</bean>
在定义SqlSessionFactoryBean的时候,dataSource属性是必须指定的,它表示用于连接 数据库的数据源。当然,我们也可以指定一些其他的属性,下面简单列举几个:
- mapperLocations:它表示我们的Mapper文件存放的位置,当我们的Mapper文件跟对应的Mapper接口处于同一位置的时候可以不用指定该属性的值。
- configLocation:用于指定Mybatis的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的SqlSessionFactoryBuilder,但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。
- typeAliasesPackage:它一般对应我们的实体类所在的包,这个时候会自动取对应包中不包括包名的简单类名作为包括包名的别名。多个package之间可以用逗号或者分号等来进行分隔。
接下来就是在Spring的applicationContext文件中定义我们想要的Mapper对象对应的MapperScannerConfigurer了,通过这个类Mybatis-Spring会自动为我们注册Mapper对应的MapperFactoryBean对象,如果我们需要使用MapperScannerConfigurer来帮我们自动扫描和注册Mapper接口的话我们需要在Spring的applicationContext配置文件中定义一个MapperScannerConfigurer对应的bean。对于MapperScannerConfigurer而言有一个属性是我们必须指定的,那就是basePackage。basePackage是用来指定Mapper接口文件所在的基包的,在这个基包或其所有子包下面的Mapper接口都将被搜索到。:
<!--配置 MapperScannerConfigurer:将Mapper接口生成代理注入到Spring -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="basePackage" value="cn.zyy.ssm.dao"></property>
</bean>
这样MapperScannerConfigurer就会扫描指定基包下面的所有接口,并把它们注册为一个个MapperFactoryBean对象。
2、在SSM搭建过程中遇到的一些问题:
(1)web.xml文件中:
<!-- spring的配置 文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
关于Spring的配置,当初param-name,我写的不是contextConfigLocation,然后运行程序一直显示无法解析applicationContext.xml文件。
(2)user.xml文件中:
<mapper namespace="cn.zyy.ssm.dao.UserDao">
<select id="getList" resultType="User">
select id,name,pwd from user
</select>
</mapper>
开始的时候,mapper的namespace写的是cn.zyy.ssm.dao,导致访问数据库一直失败,最后修改成cn.zyy.ssm.dao.UserDao才OK。
(3)在VO类User类中,最开始的时候,我除了类成员变量的setter和getter方法外,还添加了一个类构造方法,一直报错,最后去掉这个构造方法,工程就可以正常运行了。
这是我在搭建工程中自己的总结,最后的遇到的问题,我只是解决了,但是暂时还不知道原理,我会进一步学习,当然如果有高手指点下,我会很感激的。
工程代码下载地址是:http://download.youkuaiyun.com/detail/u011991249/9677262。
最后,提供几个我认为比较好的链接:
http://blog.youkuaiyun.com/zmx729618/article/details/51907416
http://blog.youkuaiyun.com/qh_java/article/details/44559005
https://my.oschina.net/u/1020238/blog/509159
http://www.2cto.com/database/201403/286289.html
http://m.blog.youkuaiyun.com/article/details?id=50136303