Spring MVC+Hibernate+Spring集成小例子

上次,散仙给了一个关于Sping MVC注解简单的小例子,那么本次呢,给出一个稍微复杂的基于增加改查的小项目,下面先介绍下此项目对应的一些信息。

名称 描述
Web容器 Tomcat6.0
IDE工具 Myeclipse10.1
平台 Windows
语言 JAVA
JDK 1.6
数据库 MySQL5.1
Sping 3.2(非Myeclipse自带,需要下载)
Hibernate 3.3(IDE自带)
Jquery 1.7.1
人力道具 屌丝软件工程师一名

项目背景概况,此项目为了模拟开发中的实际场景,使用了2张表,具有主外键关系,一个是主表Person,另一个从表Country,比上一次的单表的增删改查骚加复杂,实为新手练手的一个好例子。
下面是功能描述:
功能 描述
查询功能 默认情况下显示所有Person信息,需含有外键表的Country的name信息
增加功能 在首页上点击添加信息,跳转页面,Country信息需用下拉框显示,后台添加成功后,需要用以ajax的形式,返回响应,提示添加成功
修改功能 可以对对应的Person信息进行修改,注意下拉框与修改的Person的对应
删除功能 可以在首页上对对应的Person信息进行删除


截图,如下:

Spring MVC+Hibernate+Spring集成小例子_第1张图片


Spring MVC+Hibernate+Spring集成小例子_第2张图片

Spring MVC+Hibernate+Spring集成小例子_第3张图片


Spring MVC+Hibernate+Spring集成小例子_第4张图片

Spring MVC+Hibernate+Spring集成小例子_第5张图片


Spring MVC+Hibernate+Spring集成小例子_第6张图片


Spring MVC+Hibernate+Spring集成小例子_第7张图片



spring的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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:mvc="http://www.springframework.org/schema/mvc"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.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
       
        ">

 <!-- 注解扫描包 -->  
    <context:component-scan base-package="controller" />  
  
    <!-- 开启注解 -->  
    <mvc:annotation-driven />  
   
   
   <!--  
    <bean id="mappingJacksonHttpMessageConverter"
		class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
		<property name="supportedMediaTypes">
			<list>
				<value>application/json;charset=UTF-8</value>
				<value>text/plain;charset=UTF-8</value>
			</list>
		</property>
	</bean>
	<bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<property name="messageConverters">
			<list>
				<ref bean="mappingJacksonHttpMessageConverter" />
			</list>
		</property>
	</bean>
	-->
	 <!-- 
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">  
  <property name="mediaTypes">  
    <map>  
      <entry key="atom" value="application/atom+xml"/>  
      <entry key="html" value="text/html"/>  
      <entry key="json" value="application/json"/>  
    </map>  
  </property>  
  <property name="viewResolvers">  
    <list>  
      <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>  
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/jsp/"/>  
        <property name="suffix" value=".jsp"/>  
      </bean>  
    </list>  
  </property>  
  <property name="defaultViews">  
    <list>  
      <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />  
    </list>  
  </property>  
</bean>  

  -->
  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    
    
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
      <!-- 处理器映射 -->
    <!--   <bean class="com.qin.annocontroller.HelowWorld" ></bean> -->
      <!-- 注解使用的 HandlerMapping -->
      <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
      <!-- 注解使用的 HandlerAdapter -->
      <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
     <!-- 支持json返回   -->
        
      
      </bean>
      
      
   
    <!-- 声明DispatcherServlet不要拦截下面声明的目录 -->  
    <mvc:resources location="/jquery/" mapping="/jquery/**" />  
   <!--   <mvc:resources location="/jsp/" mapping="/jsp/**" />  -->
</beans>


web.xml的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>	
  <!-- 配置上下文参数 -->
   <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:ac*.xml</param-value>
 </context-param>
  <!--  配置监听器 -->
   <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
  <servlet>  
 
  <!-- 第一个首先调用的前端控制器,注意与WEB-INFO下servlet的xml相对应 -->
    <servlet-name>qin</servlet-name>  
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    <load-on-startup>1</load-on-startup>  
</servlet>  
<servlet-mapping>  
    <servlet-name>qin</servlet-name>  
    <url-pattern>/</url-pattern>  
</servlet-mapping> 

<servlet>  
    <servlet-name>forwarding</servlet-name>  
    <servlet-class>com.qin.sanxian.ForwardServlet</servlet-class>  
</servlet>  
<!-- 处理post提交的乱码解决 -->
<filter>  
    <filter-name>CharacterEncodingFilter</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>  
</filter>  
  <!-- 配置Session -->  
  <filter>
  <filter-name>osiv</filter-name>
  <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>osiv</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
<filter-mapping>  
    <filter-name>CharacterEncodingFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping> 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

ac.xml的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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: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-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">
	

<!-- 配置数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
		<property name="driverClassName" value="com.mysql.jdbc.Driver">
		</property>
		<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
		<property name="username" value="root"></property>
		<property name="password" value="ninemax"></property>
	</bean>
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>
				<value>entity/Country.hbm.xml</value>
				<value>entity/Person.hbm.xml</value></list>
		</property></bean>
		
		
		<!-- 配置hibernate事务管理器 -->
	<bean id="tx"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	 
	</bean>
	
		<!-- 定义事务通知 -->

	<tx:advice id="txAdvice" transaction-manager="tx">
		<tx:attributes>
			<tx:method name="*" propagation="REQUIRED" />
			<tx:method name="get*" propagation="SUPPORTS" />
			<tx:method name="find*" read-only="true" />
		</tx:attributes>
	</tx:advice>
	
	
		<!-- 定义AOP切面 -->
	<aop:config>
		<aop:pointcut expression="execution(* commons.*.*(..))"
			id="pc" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pc" />
	</aop:config>
	
	<!-- 注入父类 -->
	<bean  name="basedao"  class="commons.BaseDao" abstract="true"> </bean>
	
	
	
		
		
		</beans>


ac.Dao的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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: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-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">
	

 
 
        <bean  id="personDao"    class="dap.impl.PersonDaoImpl" parent="basedao"></bean>
   
		   <bean id="countryDao"   class="dap.impl.CountryDaoImpl" parent="basedao"></bean>
   
		
		</beans>

控制器的核心代码:
package controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

 
import org.springframework.stereotype.Controller;
 
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 

import com.google.gson.Gson;

 

import dao.CountryDao;
import dao.PersonDao;
import entity.Country;
import entity.Person;

/**
 * @author 秦东亮
 * 技术群:324714439
 * 
 * 
 * */
@Controller
public class PersonController {
 
	@Resource(name="personDao")
	  private PersonDao personDao;
 
	 public PersonDao getPersonDao() {
		return personDao;
	}
 
	public void setPersonDao(PersonDao personDao) {
		this.personDao = personDao;
	}
	@Resource(name="countryDao")
	private CountryDao countryDao;
	
 
	public CountryDao getCountryDao() {
		return countryDao;
	}

	public void setCountryDao(CountryDao countryDao) {
		this.countryDao = countryDao;
	}

	/**
	 * 输出所有的用户信息
	 * 
	 * **/
	@RequestMapping( value="/showAll")
	public String showAll(HttpServletRequest request)throws Exception{
		 
		 
		request.setAttribute("plist", personDao.find(" from Person "));
		 
		 return "showAll";
	 }
	
	/**
	 * 输出所有的国家信息
	 * 
	 * **/
	@RequestMapping( value="/add")
	public String add(HttpServletRequest request)throws Exception{
		 
		 
		request.setAttribute("clist", countryDao.find(" from Country "));
		 
		 return "adda";
	 }
	
	 /**
	  * 删除的方法
	  * */
	@RequestMapping( value="/delete")
	public String delete(HttpServletRequest request)throws Exception{
		 
		 int id=Integer.parseInt(request.getParameter("id"));
		 personDao.delete(personDao.get(id));
		 
		 return "redirect:/showAll";
	 }
	
	 /**
	  * 删除的方法
	  * request域的写法
	  * */
	@RequestMapping( value="/update")
	public String update(HttpServletRequest request)throws Exception{
		 
		 int id=Integer.parseInt(request.getParameter("id"));
		  
		 request.setAttribute("p", personDao.get(id));
		 request.setAttribute("clist", countryDao.find(" from Country "));
		 
		 return "update";
	 }
	
	
	 /**
	  * 更新的操作
	  * 封装成实体类的写法
	  * */
	@RequestMapping( value="/sup",method=RequestMethod.POST)
	public String sup(Person person,HttpServletRequest request){
		 
		try{
			
			personDao.update(person);
//		 System.out.println("111");
	//	System.out.println(person.getName());
			//System.out.println(person.getCountry().getId());
			//System.out.println(request.getParameter("name"));
		 
		}catch (Exception e) {
			 e.printStackTrace();
		}
		 return "redirect:/showAll";
	 }
	
	/**
	 * 保存一条数据
	 * 没有使用实体类自动封装的功能
	 * 
	 * **/

	@RequestMapping( value="/save",method=RequestMethod.POST)
	 
	public void  save(HttpServletRequest request,HttpServletResponse response)throws Exception{
	 
	 
	//   personDao.save(person);//保存成功
		 
 	 Person person=new Person();
 	 person.setAge(Integer.parseInt(request.getParameter("age")));
 	 person.setName(request.getParameter("name"));
 	 Country c=new Country();
 	 c.setId(Integer.parseInt(request.getParameter("cid")));
 	 person.setCountry(c);
 	 personDao.save(person);
		
 	//System.out.println("cid :  "+request.getParameter("cid"));
    Gson g=new Gson();
//    List<String> list=new ArrayList<String>();
//    list.add("A");
//    list.add("B");
//    list.add("C");
//    list.add("D");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json;charset=utf-8");
    //response.getWriter().write(g.toJson(list)); 
    response.getWriter().write(g.toJson("添加成功!")); 
	//	response.getWriter().write("1");
	 
		   
				
	 }


	/**
	 * 保存一条数据
	 * 基于ajax的json自动封装的
	 * 实体类
	 * 注意有嵌套类时的
	 * 写法"county.id"
	 * 
	 * **/

	@RequestMapping( value="/savetwo",method=RequestMethod.POST)
	 
	public void  savetwo(Person person,HttpServletRequest request,HttpServletResponse response)throws Exception{
	 
	 
	   personDao.save(person);//保存成功
		 
		
	//	System.out.println(person);
 	//System.out.println("cid :  "+request.getParameter("cid"));
    Gson g=new Gson();
//    List<String> list=new ArrayList<String>();
//    list.add("A");
//    list.add("B");
//    list.add("C");
//    list.add("D");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json;charset=utf-8");
    //response.getWriter().write(g.toJson(list)); 
    response.getWriter().write(g.toJson("添加成功!")); 
	//	response.getWriter().write("1");
	 
		   
				
	 }




}

添加的JSP页面的代码 :

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  
    
    <title>My JSP 'add.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

 <script type="text/javascript" src="jquery/jquery-1.7.1.min.js"></script></head>
  
  <script type="text/javascript">
  
  /*
    $(function(){
  
    
   $("#btn").bind('click',function(){
   alert('123');
     var name=$("#name").val();
  var age=$("#age").val();
  var cid=$("#cid").val();
  
    $.ajax({
				type:"post",
				url:"save",
				data:{name:name,age:age,country.id=cid},
				 dataType:"json",
				 success: function(msg) {
                      
                       alert(msg)

				}
			});
			  
	 
   });
  
  });  
*/
 
 function qin(){
  
   var name=$("#name").val();
  var age=$("#age").val();
  var cid=$("#cid").val();
   
    $.ajax({
				type:"post",
			  	url:"savetwo",
				 data:{name:name,age:age,"country.id":cid},
				// data:{name:name,age:age,cid:cid},
				 dataType:"json",
				 success: function(msg) {
                      
                       alert(msg)
   
        location.href = "showAll";
				}
			});
 
 }
 
  </script>
  <body>
    
  
   名字: <input  id="name"  name="name"><br>
   年龄:<input  id="age"  name="age"><br>
   请选择国家:
   <select id="cid" name="cname" >
   <c:forEach   items="${clist }" var="c">
   <option    value="${c.id}" >${c.cname} </option>
   </c:forEach>
   </select>
   
   <button id="btn"   onclick="qin()"  >提交</button>
    
   
  </body>
</html>


最后,散仙先总结下自己写这个小项目的最大的2个收获之处:

1,关于Sping MVC的json问题,因为在项目中使用到了Ajax传参以及返回参数,所以就避免不了与json打交道,所以就需要配置Sping MVC支持json的转换,这个问题比较蛋疼,可能也是散仙还不够熟练吧,Sping MVC内置支持的json需要下载什么jakson的包,但是经过一番折腾,老是启动报错,可能是版本不一致问题,最后弃用Sping MVC的内置json功能,使用流的形式的返回json,然后进行处理,包括在Struts2里面散仙也弃用了其自身携带的json功能,而是结合json工具,比如gson,fastgson,来完成ajax的一些问题,这样以来,就很简单,而且不容易出错的出色的完成某些功能。

2,第二个收获之处,关于Sping MVC提交的数据,怎么跟后台的实体类相绑定的问题,或者实体类里面又嵌套了一个实体类这样应该如何绑定参数?
其实这些问题在struts2里面还是比较好解决的,都以后台的(Action)里面实体类的属性名绑定就OK了,简单类型person.name就在表单的name里写一致就OK了,ajax无表单情况下也是如此,如果含有嵌套类需要类似使用person.country.name这样写即可,ajax无表单提交情况一样。在Spring MVC里如果是表单提交则写name就可以,如果是ajax无表单的异步提交则需要加上双引号"country.name",类似这样,另外一点关于多选框提交时,<option>标签里一定要有值,否则获取select标签时,会出现类似400错误,而Sping后台却无任何异常,所以这一点需要重点注意一下。



你可能感兴趣的:(spring)