基于注解的Spring MVC+Hiberntae简单入门
文/阿蜜果
日期/2012-11-28
1、概述
本文旨在搭建Spring MVC+Hibernate开发框架,通过一个简单的demo讲解Spring MVC的相关配置文件,以及通过注解方式实现简单功能。
开发框架:Spring + Spring MVC+Hibernate(Spring所用的版本为3.0.5)。
数据库:MySQL(数据库名称test,demo工程所用的表名为user_info)。
2、开发框架搭建
2.1 创建工程
在Eclipse的Java EE版本或MyEclipse中创建一个Dynamic Web Project。并创建如下包:
(1)com.dao:系统的DAO;
(2)com.model:表的实体类(使用Hibernate),在该工程中不配置.hbm.xml映射文件,采取注解的方式;
(3)com.service:业务逻辑接口类和实现类;
(4)com.web:Spring MVC的Controllor类;
(5)com.config:Spring和Spring MVC的配置文件。
创建成功后包结构如下所示:
springmvctest
src
----com
----amigo
----dao
----model
----service
----web
----config
WebContent
----META-INF
----WEB-INF
----lib
----classes
2.2 引入相关包
需要将Spring、Spring MVC、Hibernate、MySQL驱动、log4j、c3p0数据源等的相关包引入。lib目录下的jar包如下:
antlr-2.7.6.jar
aopalliance.jar
asm-attrs.jar
asm.jar
c3p0-0.9.0.jar
cglib-2.1.3.jar
commons-beanutils-1.8.0.jar
commons-beanutils-bean-collections-1.8.0.jar
commons-betwixt-0.8.jar
commons-collections-2.1.1.jar
commons-digester-2.1.jar
commons-discovery-0.2.jar
commons-httpclient.jar
commons-logging.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
ejb3-persistence.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
hibernate-entitymanager.jar
hibernate-validator.jar
hibernate3.jar
jaas.jar
javassist.jar
jaxen-1.1-beta-7.jar
jaxrpc.jar
jboss-archive-browsing.jar
jdbc2_0-stdext.jar
jta.jar
log4j-1.2.11.jar
mysql-connector-java-5.0.4-bin.jar
org.springframework.aop-3.0.5.RELEASE.jar
org.springframework.asm-3.0.5.RELEASE.jar
org.springframework.aspects-3.0.5.RELEASE.jar
org.springframework.beans-3.0.5.RELEASE.jar
org.springframework.context-3.0.5.RELEASE.jar
org.springframework.context.support-3.0.5.RELEASE.jar
org.springframework.core-3.0.5.RELEASE.jar
org.springframework.expression-3.0.5.RELEASE.jar
org.springframework.instrument-3.0.5.RELEASE.jar
org.springframework.instrument.tomcat-3.0.5.RELEASE.jar
org.springframework.jdbc-3.0.5.RELEASE.jar
org.springframework.jms-3.0.5.RELEASE.jar
org.springframework.orm-3.0.5.RELEASE.jar
org.springframework.oxm-3.0.5.RELEASE.jar
org.springframework.test-3.0.5.RELEASE.jar
org.springframework.transaction-3.0.5.RELEASE.jar
org.springframework.web-3.0.5.RELEASE.jar
org.springframework.web.servlet-3.0.5.RELEASE.jar
saaj.jar
wsdl4j.jar
xerces-2.6.2.jar
xml-apis.jar
2.3 配置文件
2.3.1 配置web.xml
在web.xml中需要配置Spring的配置文件(applicationContext.xml)和Spring MVC配置文件(spring-mvc.xml),配置指定所有.do的请求都由Spring的DispatcherServlet类进行处理。
web.xml文件的参考配置如下:
< web - app xmlns:xsi = " http://www.w3.org/2001/XMLSchema-instance " xmlns = " http://java.sun.com/xml/ns/javaee " xmlns:web = " http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd " xsi:schemaLocation = " http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd " id = " WebApp_ID " version = " 2.5 " >
< display - name > springmvctest </ display - name >
< welcome - file - list >
< welcome - file > index.html </ welcome - file >
< welcome - file > index.htm </ welcome - file >
< welcome - file > index.jsp </ welcome - file >
</ welcome - file - list >
< context - param >
< param - name > contextConfigLocation </ param - name >
< param - value > classpath:config / applicationContext.xml </ param - value >
</ context - param >
< listener >
< listener - class > org.springframework.web.context.ContextLoaderListener
</ listener - class >
</ listener >
< servlet >
< servlet - name > spring - mvc </ servlet - name >
< servlet - class > org.springframework.web.servlet.DispatcherServlet </ servlet - class >
< init - param >
< param - name > contextConfigLocation </ param - name >
< param - value > classpath:config / spring - mvc.xml </ param - value >
</ init - param >
< load - on - startup > 1 </ load - on - startup >
</ servlet >
< servlet - mapping >
< servlet - name > spring - mvc </ servlet - name >
< url - pattern >* . do </ url - pattern >
</ servlet - mapping >
< filter >
< filter - name > encodingFilter </ filter - name >
< filter - class > org.springframework.web.filter.CharacterEncodingFilter </ filter - class >
< init - param >
< param - name > encoding </ param - name >
< param - value > UTF - 8 </ param - value >
</ init - param >
< init - param >
< param - name > forceEncoding </ param - name >
< param - value > true </ param - value >
</ init - param >
</ filter >
< filter - mapping >
< filter - name > encodingFilter </ filter - name >
< url - pattern > /**/ /*</url-pattern>
</filter-mapping>
</web-app>
2.3.2 配置 spring 的配置文件
Spring的配置文件applicationContext.xml文件中主要配置对Hibernate的事务的管理,该配置文件的参考配置如下:
< 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:aop = " http://www.springframework.org/schema/aop "
xmlns:task = " http://www.springframework.org/schema/task "
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-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/task
http: // www.springframework.org/schema/task/spring-task-3.0.xsd">
< context:annotation - config />
<!-- 扫描annotation类,过滤Service,Repository -->
< context:component - scan base - package = " com.amigo " >
< context:include - filter type = " annotation " expression = " org.springframework.stereotype.Service " />
< context:include - filter type = " annotation " expression = " org.springframework.stereotype.Repository " />
</ context:component - scan >
< bean id = " dataSource " class = " com.mchange.v2.c3p0.ComboPooledDataSource " destroy - method = " close " >
< property name = " driverClass " >
< value > com.mysql.jdbc.Driver </ value >
</ property >
< property name = " jdbcUrl " >
< value > jdbc:mysql: // localhost/test</value>
</ property >
< property name = " user " >
< value > root </ value >
</ property >
< property name = " password " >
< value > 123456 </ value >
</ property >
< property name = " maxPoolSize " >
< value > 80 </ value >
</ property >
< property name = " minPoolSize " >
< value > 1 </ value >
</ property >
< property name = " initialPoolSize " >
< value > 1 </ value >
</ property >
< property name = " maxIdleTime " >
< value > 20 </ value >
</ property >
</ bean >
< bean id = " sessionFactory " class = " org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean " >
< property name = " dataSource " ref = " dataSource " />
< property name = " packagesToScan " value = " com.amigo.model* " ></ property >
< property name = " hibernateProperties " >
< props >
< prop key = " hibernate.dialect " > org.hibernate.dialect.MySQLDialect </ prop >
< prop key = " show_sql " > true </ prop >
< prop key = " hibernate.jdbc.batch_size " > 20 </ prop >
</ props >
</ property >
</ bean >
<!-- 不破坏数据库,注册SessionFactory -->
< bean id = " transactionManager " class = " org.springframework.orm.hibernate3.HibernateTransactionManager " >
< property name = " sessionFactory " ref = " sessionFactory " ></ property >
</ bean >
< bean id = " transactionInterceptor "
class = " org.springframework.transaction.interceptor.TransactionInterceptor " >
< property name = " transactionManager " ref = " transactionManager " ></ property >
< property name = " transactionAttributes " >
< props >
< prop key = " save* " > PROPAGATION_REQUIRED </ prop >
< prop key = " update* " > PROPAGATION_REQUIRED </ prop >
< prop key = " delete* " > PROPAGATION_REQUIRED </ prop >
< prop key = " find* " > PROPAGATION_REQUIRED </ prop >
< prop key = " get* " > PROPAGATION_REQUIRED </ prop >
< prop key = " execute* " > PROPAGATION_REQUIRED </ prop >
< prop key = " load* " > PROPAGATION_REQUIRED </ prop >
< prop key = " merge* " > PROPAGATION_REQUIRED </ prop >
< prop key = " add* " > PROPAGATION_REQUIRED </ prop >
</ props >
</ property >
</ bean >
< bean
class = " org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator " >
< property name = " beanNames " >
< list >
< value >* Service </ value >
</ list >
</ property >
< property name = " interceptorNames " >
< list >
< value > transactionInterceptor </ value >
</ list >
</ property >
</ bean >
</ beans >
2.3.3 配置 Spring MVC 配置文件
Spring MVC的配置文件spring-mvc.xml中主要是Controller的配置信息,该文件的参考配置如下:
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:p ="http://www.springframework.org/schema/p"
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/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"
default-lazy-init ="true" >
< context:annotation-config />
<!-- 使Spring支持自动检测组件,如注解的Controller -->
< context:component-scan base-package ="com.amigo.web" />
< bean id ="viewResolver" class ="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix ="/WEB-INF"
p:suffix =".jsp" />
< bean class ="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<!-- 启动 Spring MVC 的注解功能,完成请求和注解 POJO 的映射 -->
< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
< property name ="messageConverters" >
< list >
< bean class ="org.springframework.http.converter.StringHttpMessageConverter" >
</ bean >
</ list >
</ property >
</ bean >
</ beans >
2.4 创建数据库和表
创建test数据库和user_info表的SQL语句如下(为了简便,user_info只有一个USER_NAME字段):
USER test;
CREATE TABLE user_info (
USER_NAME varchar ( 32 ) NOT NULL ,
PRIMARY KEY ( USER_NAME )
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
3、实例代码
3.1 DAO层
BaseHibernateDao类的代码如下所示:
import javax.annotation.Resource;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.support.DaoSupport;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
public class BaseHibernateDao extends DaoSupport {
private SessionFactory sessionFactory;
private HibernateTemplate hibernateTemplate;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource(name="sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
this.hibernateTemplate=createHibernateTemplate(sessionFactory);
}
public Session getSession() {
if (this.sessionFactory == null) {
throw new HibernateException("Session Create Fail,SessionFactory is null!");
}
return this.sessionFactory.getCurrentSession();
}
protected HibernateTemplate createHibernateTemplate(
SessionFactory sessionFactory) {
return new HibernateTemplate(sessionFactory);
}
@Override
protected void checkDaoConfig() throws IllegalArgumentException {
if (this.hibernateTemplate == null) {
throw new IllegalArgumentException("'sessionFactory' or 'hibernateTemplate' is required");
}
}
protected final Session getSession(boolean allowCreate)
throws DataAccessResourceFailureException, IllegalStateException {
return (!allowCreate ? SessionFactoryUtils.getSession(
getSessionFactory(), false) : SessionFactoryUtils.getSession(
getSessionFactory(),
this.hibernateTemplate.getEntityInterceptor(), this.hibernateTemplate.getJdbcExceptionTranslator()));
}
protected final DataAccessException convertHibernateAccessException(
HibernateException ex) {
return this.hibernateTemplate.convertHibernateAccessException(ex);
}
protected final void releaseSession(Session session) {
SessionFactoryUtils.releaseSession(session, getSessionFactory());
if(null!=session)session=null;
}
public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public final HibernateTemplate getHibernateTemplate() {
return this.hibernateTemplate;
}
}
USER_INFO表的Dao类UserInfoDao类的代码如下所示:
import org.springframework.stereotype.Repository;
@Repository
public class UserInfoDao extends BaseHibernateDao {
}
3.2 业务逻辑层
接口类IHelloService的代码如下:
public interface IHelloService {
public int addUser(String userName) throws Exception;;
}
实现类HelloService类的代码如下:
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import com.amigo.dao.UserInfoDao;
import com.amigo.model.UserInfo;
@Service( " helloService " )
@Repository
public class HelloService implements IHelloService {
private static final Log log = LogFactory.getLog(HelloService.class);
private UserInfoDao userDao;
public UserInfoDao getUserDao() {
return userDao;
}
@Resource
public void setUserDao(UserInfoDao userDao) {
this.userDao = userDao;
}
@Override
public int addUser(String userName) throws Exception {
log.info("----------------addUser---------------");
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userName);
userDao.getSession().save(userInfo);
return 1;
}
}
3.3 控制层
控制类HelloControllor类接收userName参数,并调用相应的Service类将用户名保存到USER_INFO表中,该类的代码如下:
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.amigo.service.IHelloService;
@Controller
@RequestMapping( " /test " )
public class HelloControllor {
private static final Log log = LogFactory.getLog(HelloControllor.class);
private IHelloService helloService;
public IHelloService getHelloService() {
return helloService;
}
@Resource
public void setHelloService(IHelloService helloService) {
this.helloService = helloService;
}
@RequestMapping("/hello.do")
public @ResponseBody
String sayHello(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
log.info("userName=" + userName);
int resultCode = helloService.addUser(userName);
String rspInfo = "你好!" + userName + ",操作结果码=" + resultCode;
response.setHeader("Content-type","text/html;charset=UTF-8");
response.getOutputStream().write(rspInfo.getBytes("UTF-8"));
return "";
}
}
@Controller注解标识一个控制器,@RequestMapping注解标记一个访问的路径;如果@RequestMapping注解在类级别上,则表示一相对路径,在方法级别上,则标记访问路径;
4、测试
测试时可以通过访问http://localhost:8080/springmvctest/test/hello.do?userName=amigo777,通过userName参数将用户名添加到USER_INFO表中。
从实例代码可以看出,POJO、DAO层、Service层和Controller层都是采用注解的方式将service、dao注入的,减少了配置量,方便了开发工作。
5、参考文档
(1)《基于注解的Spring MVC简单入门》:http://www.oschina.net/question/84460_9608、