基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚

     跟往常一样,本文的事务管理亦会采用注解的方式进行。

     因为要方便将两个以上的dao操作绑定到同一个事务中,这里需要新建一个module来演示:

package com.freestyle.test.hibernate.modules;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.freestyle.common.hibernate.dao.interfaces.IHibernateEntityDao;
import com.freestyle.test.hibernate.entities.TaUser;

@Repository("transactionTestModule")
public class TransactionTestModule {
	@Resource(name = "hibernateUserDao")
	protected IHibernateEntityDao mvDao;
	@Resource(name = "hUserBaseDao")
	protected IHibernateEntityDao mvBaseDao;
	private Log log=LogFactory.getLog(TransactionTestModule.class);
	/***
	 * 演示两个dao在同一个事务下更新数据:用@Transactional将当前方法的dao对象绑定到同一个事务中
	 * @param pvName
	 * @return
	 */
	@Transactional
	public void test1(){
		StringBuilder sb=new StringBuilder();		
		Transaction lvTx1=mvDao.getSession().getTransaction();
		Transaction lvTx2=mvBaseDao.getSession().getTransaction();
		sb.append("两个dao是否处于同一个transaction里面:"+(lvTx1==lvTx2?"Yes":"No")+"
"); TaUser lvUser1=mvDao.get("dgmislrh"); lvUser1.setFaName("change1"); mvDao.save(lvUser1); TaUser lvUser2=mvBaseDao.get("dgmiszws"); lvUser2.setFaName("change2"); mvBaseDao.save(lvUser2); log.info(sb.toString()); } /*** * 设置初值 * @param pvName * @return */ public void initvalues(){ TaUser lvUser1= mvDao.get("dgmislrh"); lvUser1.setFaName("value1"); mvDao.save(lvUser1); lvUser1=mvDao.get("dgmiszws"); lvUser1.setFaName("value2"); mvDao.save(lvUser1); log.info("成功将dgmislrh.fa_name设为value1, dgmiszws.fa_name设为value2"); } /*** * 演示两个dao在同一个事务下更新数据 ,但系统发生错误,两个数据更新均回滚 * @param pvName * @return */ @Transactional public void test2_step2(){ log.info("数据操作后发生错误,全部回滚"); TaUser lvUser1=mvDao.get("dgmislrh"); lvUser1.setFaName("change1"); mvDao.save(lvUser1); TaUser lvUser2=mvBaseDao.get("dgmiszws"); lvUser2.setFaName("change2"); mvBaseDao.save(lvUser2); if (100/(5-5)==1){ //程序发生错误,全部回滚 } } /*** * 重新从table中获取fa_name的值 */ public void fetchvalues(){ TaUser lvUser1= mvDao.get("dgmislrh"); log.info("重新获取数据 ,dgmislrh:"+lvUser1.getFaName()); lvUser1=mvDao.get("dgmiszws"); log.info("重新获取数据 ,dgmiszws:"+lvUser1.getFaName()); } /*** * 手动通过throw exception 回滚 */ @Transactional public void test3(){ log.info("数据操作后业务检查失败,全部回滚"); TaUser lvUser1=mvDao.get("dgmislrh"); lvUser1.setFaName("change1"); mvDao.save(lvUser1); TaUser lvUser2=mvBaseDao.get("dgmiszws"); lvUser2.setFaName("change2"); mvBaseDao.save(lvUser2); if (mvBaseDao!=null){ //演示业务检查失败,用抛出exception的方式回滚 throw new RuntimeException("因为长得太帅,这次不改名了"); } } }

然后在HibernateController里面加入测试代码:

@Controller
@RequestMapping("/hibernate")
@DependsOn({ "hibernateUserDao" ,"transactionTestModule"})
public class HibernateController implements org.springframework.web.servlet.mvc.Controller {
	// @Resource(name="hibernateUserDao")
	// private HibernateUserDao lvDao;
	// @Resource(name="hibernateUserDao")
	@Resource(name = "hibernateUserDao")
	protected IHibernateEntityDao mvDao;
	@Resource(name = "hUserBaseDao")
	protected IHibernateEntityDao mvBaseDao;
	@Resource(name="transactionTestModule")
	protected TransactionTestModule mttMdl;

	@RequestMapping("/htransaction")
	public ModelAndView thtrans(@RequestParam(value = "name", defaultValue = "World") final String name)
			throws SQLException {		
		mttMdl.test1();
		mttMdl.initvalues();
		try{
		mttMdl.test2_step2();
		}
		catch (Exception e){System.out.println(e.getMessage());}
		mttMdl.fetchvalues();
		
		mttMdl.initvalues();
		try{
		mttMdl.test3();
		}catch (Exception e){System.out.println(e.getMessage());}
		mttMdl.fetchvalues();
		
		
		Map lvMap=new HashMap();
		lvMap.put("result", "");
		return new ModelAndView("/result",lvMap);
	}...


在浏览器地址栏输入http://localhost/gpchat/hibernate/htransaction,在控制台上看到运行日志:

12:21:48,175  INFO TransactionTestModule:38 - 两个dao是否处于同一个transaction里面:Yes
12:21:48,251 INFO TransactionTestModule:52 - 成功将dgmislrh.fa_name设为value1, dgmiszws.fa_name设为value2 12:21:48,253 INFO TransactionTestModule:61 - 数据操作后发生错误,全部回滚 / by zero 12:21:48,272 INFO TransactionTestModule:77 - 重新获取数据 ,dgmislrh:value1 12:21:48,280 INFO TransactionTestModule:79 - 重新获取数据 ,dgmiszws:value2 12:21:48,313 INFO TransactionTestModule:52 - 成功将dgmislrh.fa_name设为value1, dgmiszws.fa_name设为value2 12:21:48,315 INFO TransactionTestModule:86 - 数据操作后发生错误,全部回滚 因为长得太帅,这次不改名了 12:21:48,334 INFO TransactionTestModule:77 - 重新获取数据 ,dgmislrh:value1 12:21:48,346 INFO TransactionTestModule:79 - 重新获取数据 ,dgmiszws:value2



----------------------------------找到一篇更系统讲述hibernate事务的文章,如下 ----------------------


Spring MVC事务配置

要了解事务配置的所有方法,请看一下《Spring事务配置的5种方法》

本文介绍两种配置方法:

 

一、      XML,使用tx标签配置拦截器实现事务

一、      Annotation方式

以下所使用环境为Spring4.0.3、Hibernate4.3.5

 

一、      XML,使用tx标签配置拦截器实现事务

Entity类User.java,持久化类,对应数据库表user

复制代码
package com.lei.demo.entity;

import javax.persistence.*;

@Entity(name="users")
public class Users {
    
    public Users(){
        super();
    }
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id")
    private Integer id;
    
    @Column(name="user_name",length=32)
    private String user_name;
    
    @Column(name="age")
    private Integer age;
    
    @Column(name="nice_name",length=32)
    private String nice_name;
    
    //属性实现......

}
复制代码

 

UserDAO.javar,表user的一些操作,其中属性sessionFactory应该由Spring注入,如下:

复制代码
package com.lei.demo.dao;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.lei.demo.entity.Users;

public class UsersDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public List getAllUser(){
        String hsql="from users";
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery(hsql);
        
        return query.list();
    }
}
复制代码

 

UserService.java,业务实现类,如下

复制代码
package com.lei.demo.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.lei.demo.dao.*;

public class UserService {
    private UsersDAO userDao;
    
    public int userCount(){
        return userDao.getAllUser().size();
    }

    public UsersDAO getUserDao() {
        return userDao;
    }

    public void setUserDao(UsersDAO userDao) {
        this.userDao = userDao;
    }

}
复制代码

 

首先看一下xml配置,spring-hibernate.xml如下:

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">

    
    
    <context:property-placeholder location="classpath:persistence-mysql.properties" />
    
    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                
                <value>com.lei.demo.entityvalue>
            list>
        property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}prop>
                <prop key="hibernate.dialect">${hibernate.dialect}prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}prop>
                 
            props>
        property>
    bean>
    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}" />
      <property name="url" value="${jdbc.url}" />
      <property name="username" value="${jdbc.user}" />
      <property name="password" value="${jdbc.pass}" />
   bean>
   
    
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   bean>
   
   
   <bean id="persistenceExceptionTranslationPostProcessor" 
       class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
   
   
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="get*" propagation="REQUIRED" />
            <tx:method name="*" read-only="true" />
        tx:attributes>
    tx:advice>
    
    <aop:config expose-proxy="true">
        
        <aop:pointcut id="txPointcut" expression="execution(* com.lei.demo.service..*.*(..))" />
        
        <aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice"/>
    aop:config>
    
beans>
复制代码

 

其中主要配置中是tx:adviceaop:config两个配置节,以Spring AOP的方式实现事务管理。

tx:advice配置了事务的管理者是transactionManager,同时tx:method也规定了如果方法名匹配“add*”和“get*”方法时使用事务,propagation是设定事务的传播级别。除了“add*”和“get*”方法,其他的方法的事务是只读的(典型地,对于只执行查询的事务你会将该属性设为true,如果出现了更新、插入或是删除语句时只读事务就会失败)

aop:config指定了一个aop:pointcut去引用上边的advice。

这样就通过AOP的拦截机制实现了事务,当然你还要用Spring的方式自己配置UserDAO和UserService。

 

二、      Annotation方式

第一步,首先看一下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" 
    xmlns:web="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>Archetype Created Web Applicationdisplay-name>
  <context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:/spring-*.xmlparam-value>
  context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  listener>
  <servlet>
    <servlet-name>lei-dispatcherservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:/lei-dispatcher-servlet.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>
  <servlet-mapping>
    <servlet-name>lei-dispatcherservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>
web-app>
复制代码

 

第二步,spring-hibernate配置,见以下spring-hibernate.xml配置

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">

    
    
    <context:property-placeholder location="classpath:persistence-mysql.properties" />
    
    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                
                <value>com.lei.demo.entityvalue>
            list>
        property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}prop>
                <prop key="hibernate.dialect">${hibernate.dialect}prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}prop>
                 
            props>
        property>
    bean>
    
    
    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}" />
      <property name="url" value="${jdbc.url}" />
      <property name="username" value="${jdbc.user}" />
      <property name="password" value="${jdbc.pass}" />
   bean>
   
    
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   bean>
   
   
   <bean id="persistenceExceptionTranslationPostProcessor" 
       class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

beans>
复制代码

第一节中xml配置事务中需要通过配置tx:advice和aop:config来增加事务的功能。此处采用全注释方法,这两个配置节就不需要了。

 

相应的需要在视图解析配置中启用注释,如下lei-dispatcher-servlet.xml

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">
        
    
    <context:component-scan base-package="com.lei.demo" />
    
    
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/user/value>
        property>
        <property name="suffix">
            <value>.jspvalue>
        property>
    bean>
    
beans>
复制代码

 

UserDAO如下

复制代码
package com.lei.demo.dao;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.lei.demo.entity.Users;

@Repository
public class UsersDAO {
    @Resource(name="sessionFactory")
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public List getAllUser(){
        String hsql="from users";
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery(hsql);
        
        return query.list();
    }
}
复制代码

 

UserService.java如下

复制代码
package com.lei.demo.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.lei.demo.dao.*;

@Service("userService")
public class UserService {
    @Resource
    private UsersDAO userDao;
    
    @Transactional
    public int userCount(){
        return userDao.getAllUser().size();
    }

    public UsersDAO getUserDao() {
        return userDao;
    }

    public void setUserDao(UsersDAO userDao) {
        this.userDao = userDao;
    }

}
复制代码

这里,方法名userCount上加入@Transactional,说明这个方法要启用事务。如果类名UserService上加入@Transactional,则表明这个类中的所有方法都会启用事务。

如果配有多个transactionManager,例如配置有transactionManager1,和transactionManager2,则可以通过@Transactional(“transactionManager1”),的方式指定使用哪个数据源的事务。


Spring4 MVC Hibernate4集成xml版

一、    本文所用环境

Spring4.0.3.RELEASE

Hibernate4.3.5.Final

MySQL

二、    工程目录

 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第1张图片

三、    Maven添加依赖

用Maven创建项目,pom.xml如下:

  View Code

四、    新建数据库表

数据库采用Mysql,新建users表,我们演示操作此表

复制代码
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `nice_name` varchar(32) DEFAULT NULL,
  `user_name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码

创建Entity类Users.java见下

复制代码
package com.lei.demo.entity;

import javax.persistence.*;

@Entity(name="users")
public class Users {
    
    public Users(){
        super();
    }
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id")
    private Integer id;
    
    @Column(name="user_name",length=32)
    private String user_name;
    
    @Column(name="age")
    private Integer age;
    
    @Column(name="nice_name",length=32)
    private String nice_name;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUser_name() {
        return user_name;
    }
    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getNice_name() {
        return nice_name;
    }
    public void setNice_name(String nice_name) {
        this.nice_name = nice_name;
    }
}
复制代码

 

五、    配置文件

1.        首先看一下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" 
    xmlns:web="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>Archetype Created Web Applicationdisplay-name>
  <context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:/spring-*.xmlparam-value>
  context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  listener>
  
  <servlet>
    <servlet-name>lei-dispatcherservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:/lei-dispatcher-servlet.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>
  
  <servlet-mapping>
    <servlet-name>lei-dispatcherservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>
web-app>
复制代码

 

2.        lei-dispatcher-servlet.xml

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">
        
    
    <context:component-scan base-package="com.lei.demo" />
    
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/user/value>
        property>
        <property name="suffix">
            <value>.jspvalue>
        property>
    bean>
    
beans>
复制代码

 

3.        Spring-hibernate的整合

spring-hibernate.xml文件

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">

    
    
    <context:property-placeholder location="classpath:persistence-mysql.properties" />
    
    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                
                <value>com.lei.demo.entityvalue>
            list>
        property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}prop>
                <prop key="hibernate.dialect">${hibernate.dialect}prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}prop>
                 
            props>
        property>
    bean>
    
    
    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}" />
      <property name="url" value="${jdbc.url}" />
      <property name="username" value="${jdbc.user}" />
      <property name="password" value="${jdbc.pass}" />
   bean>
   
    
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   bean>
   
   
   <bean id="persistenceExceptionTranslationPostProcessor" 
       class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
   
   
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="get*" propagation="REQUIRED" />
            <tx:method name="*" read-only="true" />
        tx:attributes>
    tx:advice>
    
    <aop:config expose-proxy="true">
        
        <aop:pointcut id="txPointcut" expression="execution(* com.lei.demo.service..*.*(..))" />
        
        <aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice"/>
    aop:config>
    
beans>
复制代码

事务采用tx:advice和aop:config的xml配置方式实现。事务的其他实现方式见《Spring MVC事务配置》

 

资源文件persistence-mysql.properties如下:

复制代码
# jdbc.X
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://yourServerIP:3306/yourDatabase?createDatabaseIfNotExist=true
jdbc.user=user
jdbc.pass=password

# hibernate.X
hibernate.connection.driverClass=org.gjt.mm.mysql.Driver
hibernate.connection.url=jdbc:mysql:// yourServerIP:3306/yourDatabase
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.connection.username=user
hibernate.connection.password=password
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop
复制代码

 

六、    DAO、Service

UsersDAO.java如下:

复制代码
package com.lei.demo.dao;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.lei.demo.entity.Users;

public class UsersDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public List getAllUser(){
        String hsql="from users";
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery(hsql);
        
        return query.list();
    }
}
复制代码

 

UserService.java如下:

复制代码
package com.lei.demo.service;

import com.lei.demo.dao.*;

public class UserService {
    private UsersDAO userDao;
    
    public int userCount(){
        return userDao.getAllUser().size();
    }

    public UsersDAO getUserDao() {
        return userDao;
    }

    public void setUserDao(UsersDAO userDao) {
        this.userDao = userDao;
    }

}
复制代码

 

七、    加载Bean配置文件

这里主要是加载上边的dao、service

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.2.xsd">
      
    <bean id="usersDAO" class="com.lei.demo.dao.UsersDAO">
          <property name="sessionFactory" ref="sessionFactory">property>
    bean>
    <bean id="userService" class="com.lei.demo.service.UserService">
        <property name="userDao" ref="usersDAO">property>
    bean>
beans>
复制代码

 

当然你也可以不采用xml配置bean,采用注释加载bean,见《Spring3系列7- 自动扫描组件或Bean》《Spring 开启Annotation  和 诠释及区别》

 

八、    JSP页面和Controller

WEB-INF/user/users.jsp如下:

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
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 heretitle>
head>
<body>
    <h1>Message : ${message}h1>
body>
html>
复制代码

 

 

写Controller访问上边的jsp

复制代码
package com.lei.demo.controller;

import javax.annotation.Resource;

import com.lei.demo.service.*;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserController {
    
    @Resource(name="userService")
    private UserService service;
    
    @RequestMapping(value="/manager",method=RequestMethod.GET)
    public ModelAndView hello2(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("message", "HelloMVC");
        mv.setViewName("users");
        return mv;
    }
    
    @RequestMapping(value="/count",method=RequestMethod.GET)
    public ModelAndView count(){
        
        int c = service.userCount();
        
        ModelAndView mv = new ModelAndView();
        mv.addObject("message", c);
        mv.setViewName("users");
        return mv;
    }
}
复制代码

 

上边的controller定义了两个路径

http://localhost:8080/spring4-mvc-hibernate4/user/manager

http://localhost:8080/spring4-mvc-hibernate4/user/count

以上两个路径都调用WEB-INF/user/users.jsp

参考资料《Spring3系列13-Controller和@RequestMapping》

 

九、    运行结果

 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第2张图片

基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第3张图片


Spring4 MVC Hibernate4集成 Annotation版

一、本文所用环境

二、工程目录

三、Maven添加依赖

四、新建数据库表

五、配置文件

六、Model层

七、DAO层

 八、Service层

九、JSP页面和Controller

十、运行结果

 

已经充分封装DAO层和Service层

一、    本文所用环境

Spring4.0.3.RELEASE、Hibernate4.3.5.Final、Mysql

二、    工程目录

 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第4张图片

三、    Maven添加依赖

用Maven创建项目,pom.xml如下: 

  View Code

 

四、    新建数据库表

数据库采用Mysql,新建user表,我们演示操作此表对user进行增删改查

复制代码
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `nice_name` varchar(32) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
复制代码

在model层下,创建Entity类Users.java见下

复制代码
package com.lei.demo.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity(name="User")
public class User implements Serializable {
    
    private static final long serialVersionUID = 1L;

    public User(){
        super();
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id")
    private Long id;
    
    @Column(name="name",length=32)
    private String name;
    
    @Column(name="age")
    private Integer age;
    
    @Column(name="nice_name",length=32)
    private String nice_name;

    @Override
    public String toString() {
        return "User [id=" + id + ", user_name=" + name + ", age=" + age
                + ", nice_name=" + nice_name + "]";
    }

    public final Long getId() {
        return id;
    }

    public final void setId(Long id) {
        this.id = id;
    }

    public final String getName() {
        return name;
    }

    public final void setName(String name) {
        this.name = name;
    }

    public final Integer getAge() {
        return age;
    }

    public final void setAge(Integer age) {
        this.age = age;
    }

    public final String getNice_name() {
        return nice_name;
    }

    public final void setNice_name(String nice_name) {
        this.nice_name = nice_name;
    }

}
复制代码

五、    配置文件

1.        首先看一下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" 
    xmlns:web="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>Archetype Created Web Applicationdisplay-name>
  <context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:/spring-*.xmlparam-value>
  context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  listener>
  
  <servlet>
    <servlet-name>mvc-dispatcherservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:/mvc-dispatcher-servlet.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>
  
  <servlet-mapping>
    <servlet-name>mvc-dispatcherservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>
web-app>
复制代码

2.        mvc-dispatcher-servlet.xml

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">
        
    
    <context:component-scan base-package="com.lei.demo" />
    
    
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/jsp/value>
        property>
        <property name="suffix">
            <value>.jspvalue>
        property>
    bean>
   
beans>
复制代码

3.        Spring-hibernate的整合

spring-hibernate.xml文件

复制代码
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        ">

    
    
    <context:property-placeholder location="classpath:persistence-mysql.properties" />
    
    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                
                <value>com.lei.demo.modelvalue>
            list>
        property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}prop>
            props>
        property>
    bean>
    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}" />
      <property name="url" value="${jdbc.url}" />
      <property name="username" value="${jdbc.user}" />
      <property name="password" value="${jdbc.pass}" />
   bean>
   
    
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   bean>
   
   
   <bean id="persistenceExceptionTranslationPostProcessor" 
       class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    
beans>
复制代码

 

资源文件persistence-mysql.properties如下:

复制代码
# jdbc.X
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.150.63:3306/test?createDatabaseIfNotExist=true
jdbc.user=root
jdbc.pass=root111111

# hibernate.X
hibernate.connection.driverClass=org.gjt.mm.mysql.Driver
hibernate.connection.url=jdbc:mysql://192.168.150.63:3306/test
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.connection.username=root
hibernate.connection.password=root111111
hibernate.show_sql=true
复制代码

六、    Model层

此处model层只有一个User类,见前文user.java

七、    DAO层

DAO层包括3个包,各个包中类如下:

com.lei.demo.dao.common: IOperations, AbstractHibernateDao

com.lei.demo.dao: IUserDao

com.lei.demo.dao.impl: UserDao

代码如下:

IOperations.java,通用的操作接口

复制代码
package com.lei.demo.dao.common;

import java.io.Serializable;
import java.util.List;

/*
 * 通用的操作接口
 */
public interface IOperationsextends Serializable> {
     
        T findOne(final long id);

        List findAll();

        void create(final T entity);

        T update(final T entity);

        void delete(final T entity);

        void deleteById(final long entityId);

}
复制代码

 

AbstractHibernateDao.java实现了IOperations接口,所有DAO都需要继承此类,这样就避免重复的写一些CURD。

复制代码
package com.lei.demo.dao.common;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.google.common.base.Preconditions;

@SuppressWarnings("unchecked")
public abstract class AbstractHibernateDaoextends Serializable> implements IOperations {
    
    private Class clazz;
    
    @Resource(name="sessionFactory")
    private SessionFactory sessionFactory;

    protected final void setClazz(final Class clazzToSet) {
        this.clazz = Preconditions.checkNotNull(clazzToSet);
    }
    
    protected final Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public final T findOne(final long id) {
        return (T)getCurrentSession().get(clazz, id);
    }

    @Override
    public final List findAll() {
        return getCurrentSession().createQuery("from " + clazz.getName()).list();
    }

    @Override
    public final void create(final T entity) {
         Preconditions.checkNotNull(entity);
         // getCurrentSession().persist(entity);
         getCurrentSession().saveOrUpdate(entity);
    }

    @Override
    public final T update(final T entity) {
        Preconditions.checkNotNull(entity);
        getCurrentSession().update(entity);
        return entity;
        //return (T)getCurrentSession().merge(entity);
    }

    @Override
    public final void delete(final T entity) {
         Preconditions.checkNotNull(entity);
         getCurrentSession().delete(entity);
    }

    @Override
    public final void deleteById(final long entityId) {
        final T entity = findOne(entityId);
        Preconditions.checkState(entity != null);
        delete(entity);
    }
    
}
复制代码

 

IUserDao.java具体的DAO的接口,继承了IOperations

复制代码
package com.lei.demo.dao;

import com.lei.demo.dao.common.IOperations;
import com.lei.demo.model.User;

public interface IUserDao extends IOperations {
    //让所有的DAO都实现基本的操作接口IOperations
    //除了实现IOperations中的基本操作之外,特定的DAO要实现其他操作可以在对应的接口DAO中定义方法,
    //此处UserDao的接口IUserDao不需要实现其他方法
}
复制代码

 

UserDao.java具体的DAO实现

复制代码
package com.lei.demo.dao.impl;

import org.springframework.stereotype.Repository;

import com.lei.demo.dao.IUserDao;
import com.lei.demo.dao.common.AbstractHibernateDao;
import com.lei.demo.model.User;

@Repository("usersDao")
public class UserDao extends AbstractHibernateDao implements IUserDao {

    public UserDao() {
        super();
        
        setClazz(User.class);
    }
}
复制代码

至此,DAO层已经完成。

八、    Service层

Service层包括3个包,各个包中类如下:

com.lei.demo.service.common: AbstractService

com.lei.demo.service: IUserService

com.lei.demo.service.impl: UserService

 

AbstractService.java,实现了IOperations,所有的Service都要继承此类,这样就避免了重复实现通用的方法,注意类前的注释“@Transactional

”,表示其中所有的方法都需要引入事务,代码如下:

复制代码
package com.lei.demo.service.common;

import java.io.Serializable;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.lei.demo.dao.common.IOperations;

@Transactional
public abstract class AbstractServiceextends Serializable> implements IOperations {
    
    protected abstract IOperations getDao();

    @Override
    public T findOne(final long id) {
        return getDao().findOne(id);
    }

    @Override
    public List findAll() {
        return getDao().findAll();
    }

    @Override
    public void create(final T entity) {
        getDao().create(entity);
    }

    @Override
    public T update(final T entity) {
        return getDao().update(entity);
    }

    @Override
    public void delete(final T entity) {
        getDao().delete(entity);
    }

    @Override
    public void deleteById(long entityId) {
        getDao().deleteById(entityId);
    }

}
复制代码

 

IUserService.java接口

复制代码
package com.lei.demo.service;

import com.lei.demo.dao.common.IOperations;
import com.lei.demo.model.User;

public interface IUserService extends IOperations {

}
复制代码

 

UserService.java,具体的Service实现类就很简单了,因为大部分通用的方法都在其继承的虚类AbstractService中实现了,这里只要注入具体的dao即可:

复制代码
package com.lei.demo.service.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.lei.demo.dao.IUserDao;
import com.lei.demo.dao.common.IOperations;
import com.lei.demo.model.User;
import com.lei.demo.service.IUserService;
import com.lei.demo.service.common.AbstractService;

@Service("userService")
public class UserService extends AbstractService implements IUserService {

    @Resource(name="usersDao")
    private IUserDao dao;
    
    public UserService() {
        super();
    }

    @Override
    protected IOperations getDao() {
        return this.dao;
    }
}
复制代码

九、    JSP页面和Controller

Jsp页面放在WEB-INF/jsp/user/…下,分别是user的增删改查页面,

WEB-INF/jsp/user/add.jsp

WEB-INF/jsp/user/edit.jsp

WEB-INF/jsp/user/list.jsp

WEB-INF/jsp/user/detail.jsp

 

以下是具体页面代码

WEB-INF/jsp/user/add.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>Add Usertitle>
head>
<body>
    <form action="add" method="post">
        
        Name:<input id="name" name="name" type="text" />
        <br>
        Nice Name:<input id="nice_name" name="nice_name" type="text" />
        <br>
        Age:<input id="age" name="age" type="text" />
        <br>
        <input type="submit" value="提交">
    form>
body>
html>
复制代码

 

WEB-INF/jsp/user/edit.jsp

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
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>Edit usertitle>
head>
<body>
    <c:url var="saveUrl" value="/user/save/${userAttribute.id }" />
    <form:form modelAttribute="userAttribute" action="${saveUrl }">
        <table>
            <tr>
                <td>ID:td>
                <td><form:input path="id" readonly="true"/>td>
            tr>
            <tr>
                <td>Name:td>
                <td><form:input path="name"/>td>
            tr>
            <tr>
                <td>Nice name:td>
                <td><form:input path="nice_name"/>td>
            tr>
            <tr>
                <td>Age:td>
                <td><form:input path="age"/>td>
            tr>
        table>
        <input type="submit" value="Save">
    form:form>
body>
html>
复制代码

 

WEB-INF/jsp/user/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>User Listtitle>
head>
<body>
    <a href="add">Adda>
    <table>
        <tr>
            <td>IDtd>
            <td>Nametd>
            <td>NiceNametd>
            <td>Agetd>
        tr>
        <c:forEach var="user" items="${userList }" >
            <tr>
                <td>${user.id }td>
                <td>${user.name }td>
                <td>${user.nice_name }td>
                <td>${user.age }td>
                <td><a href="show/${user.id }">详细a>td>
                <td><a href="edit/${user.id }">编辑a>td>
                <td><a href="del/${user.id }">删除a>td>
            tr>
        c:forEach>
    table>
body>
html>
复制代码

 

WEB-INF/jsp/user/detail.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>Show usertitle>
head>
<body>
    <c:out value="${user.id }">c:out>
    <br>
    <c:out value="${user.name }">c:out>
    <br>
    <c:out value="${user.nice_name }">c:out>
    <br>
    <c:out value="${user.age }">c:out>
body>
html>
复制代码

 

写Controller访问上边的jsp,UserController.java

复制代码
package com.lei.demo.controller;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.lei.demo.model.User;
import com.lei.demo.service.IUserService;

@Controller
@RequestMapping("/user")
public class UserController {

    @Resource(name="userService")
    private IUserService userService;
    
    @RequestMapping(value="/count",method=RequestMethod.GET)
    public ModelAndView userCount() {
        
        int count = userService.findAll().size();
        
        ModelAndView mv = new ModelAndView();
        mv.addObject("userCount", count);
        mv.setViewName("user/userCount");
        return mv;
    }
    
    @RequestMapping(value="/list",method=RequestMethod.GET)
    public ModelAndView getUserlist(Model model){
        
        ModelAndView mv = new ModelAndView();
        List userList = userService.findAll();
        System.out.println("log======table 'user' all records:"+userList.size());
        mv.addObject("userList", userList);
        mv.setViewName("user/list");
        return mv;
    }
    
    @RequestMapping(value="/add",method=RequestMethod.GET)
    public ModelAndView getAdd(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("user/add");
        return mv;
    }
    
    @RequestMapping(value="/add",method=RequestMethod.POST)
    public String add(@ModelAttribute("user") User user){
        userService.create(user);
        return "redirect:/user/list";
    }
    
    @RequestMapping(value="/show/{userid}",method=RequestMethod.GET)
    public ModelAndView show(@PathVariable Long userid){
        User user = userService.findOne(userid);
        
        ModelAndView mv = new ModelAndView();
        mv.addObject("user", user);
        mv.setViewName("user/detail");
        return mv;
    }
    
    @RequestMapping(value="/del/{userid}",method=RequestMethod.GET)
    public String del(@PathVariable Long userid){
        userService.deleteById(userid);
        
        return "redirect:/user/list";
    }
    
    @RequestMapping(value="/edit/{userid}",method=RequestMethod.GET)
    public ModelAndView getEdit(@PathVariable Long userid,Model model){
        User user = userService.findOne(userid);
        model.addAttribute("userAttribute", user);
        ModelAndView mv = new ModelAndView();
        mv.setViewName("user/edit");
        return mv;
    }
    
    @RequestMapping(value="/save/{userid}",method=RequestMethod.POST)
    public String saveEdit(@ModelAttribute("userAttribute") User user,@PathVariable Long userid){
        userService.update(user);
        return "redirect:/user/list";
    }
}
复制代码

十、    运行结果

 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第5张图片

基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第6张图片

基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚_第7张图片


Spring MVC请求参数获取的几种方法


一、      通过@PathVariabl获取路径中的参数

复制代码
    @RequestMapping(value="user/{id}/{name}",method=RequestMethod.GET)
    public String printMessage1(@PathVariable String id,@PathVariable String name, ModelMap model) {
        
        System.out.println(id);
        System.out.println(name);
        model.addAttribute("message", "111111");
        return "users";
    }
复制代码

例如,访问user/123/lei路径时,执行以上方法,其中,参数id=123,name=lei

 

二、      @ModelAttribute获取POST请求的FORM表单数据

JSP表单如下

<form method="post" action="hao.do">
    a: <input id="a" type="text"   name="a"/>
    b: <input id="b" type="text"   name="b"/>
    <input type="submit" value="Submit" />
 form>

 

Java  Pojo如下

    public class Pojo{
        private String a;
        private int b;
    }

 

Java Controller如下

@RequestMapping(method = RequestMethod.POST) 
public String processSubmit(@ModelAttribute("pojo") Pojo pojo) { 
    
    return "helloWorld"; 
}

三、      直接用HttpServletRequest获取

@RequestMapping(method = RequestMethod.GET) 
public String get(HttpServletRequest request, HttpServletResponse response) { 
   System.out.println(request.getParameter("a")); 
    return "helloWorld"; 
}

 

四、      用注解@RequestParam绑定请求参数

用注解@RequestParam绑定请求参数a到变量a

当请求参数a不存在时会有异常发生,可以通过设置属性required=false解决,

例如: @RequestParam(value="a", required=false)

Controller如下

@RequestMapping(value = "/requestParam", method = RequestMethod.GET) 
public String setupForm(@RequestParam("a") String a, ModelMap model) { 
   System.out.println(a); 
return "helloWorld";
}


你可能感兴趣的:(Spring,大杂烩)