SpringMVC + Spring + SpringDataJPA 整合
Posted 普通网友
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC + Spring + SpringDataJPA 整合相关的知识,希望对你有一定的参考价值。
涉及技术: –1.SpringMVC、Spring、SpringData\\JPA整合完成CRUD、翻页 –2.基于Restful风格 –3.使用JPA二级缓存 –4.使用@ResponseBody注解完成Ajax.完成分页操作
•Dao 层: –不带查询查询条件的分页,所以可以直接调用 PagingAndSortingRepository# findAll(Pageable pageable) 返回 Page 对象。 •Service 层: –没有业务逻辑 –把 Controller 传入的 pageNo 和pageSize 封装为Pageable 对象。注意:Pageable 的pageNo 是从0 开始的 –调用 Dao层的方法即可。 •Controller 层: –获取 pageNo,并对 pageNo 进行校验 –调用 Service方法返回 Page对象 –把 Page 对象放入到request 中 –转发页面 JSP 页面:使用JSTL 来显示页面
添加操作:显示页面 & 使用 JPA 二级缓存
•Dao 层: –查询所有的 Department –且需要使用JPA 的二级缓存? •Service 层:调用 Dao层的方法,获取所有的 Department,返回即可 •Controller 层: –调用Service 层,获取所有的 Department,并放入到 request 中 –创建一个新的Employee 对象,放入到 request 中。且其键和表单的 modelAttribute 属性值一致。 –转发页面 •JSP 页面: –需要使用 SpringMVC 的表单标签来显示表单页面 –注意:form:form 标签必须设置一个modelAttribute 属性,以从request 中获取对应的 bean,要求该bean 的属性和表单字段是一一对应的。
Ajax 验证用户名可用性 •Dao 层:新建一个方法:根据lastName 查询对应的Employee,若存在返回 Employee 对象,若不存在则返回 null •Service 层:直接调用 Dao 方法返回结果即可。 •Controller 层: –获取请求参数 –调用 Service层验证 lastName 对应的Employee 是否存在 –若存在则返回“1”,若不存在则返回“0”。需要使用 @ResponseBody 注解 •JSP 页面:使用jQuery 完成Ajax 的发送,和结果的响应。
完成添加
•Dao 层:不需要定义任何方法,直接使用JpaRepository 或其父接口提供的save 方法即可 •Service 层:需要调用 Dao 层的方法。注意:需要设置createTime 属性 •Controller 层:调用 Service层的方法,重定向到显示所有员工的页面 •注意:如何把页面上输入的字符串转为Date 类型。使用@DateTimeFormat 注解!
表单回显
•SpringMVC 表单回显的原理: –实际上表单的回显是由 SpringMVC 的form 标签完成的 –在 Handler 方法中,向request 中添加一个属性。键:SpringMVC form:form 标签modelAttribute 属性值,值:包含了回显信息的一个bean 对象 •URL:/emp/id,method:GET •Dao 层:直接调用方法,根据id 来获取对应的bean •Service 层:调用 Dao层的方法,返回 bean 对象 •Controller 层: –获取 id –调用 Service方法,得到 bean 的对象 –获取全部的 Department,并放入到 request 中。 –把 bean 对象放入到request 中,键为:form:form 标签的modelAttribute 属性值 –转发页面
修改状态下 Ajax 验证用户名可用性
•和 添加状态下 Ajax验证的区别:若修改后当前的lastName,则不应该再发送任何Ajax请求,而直接alert:用户名可用。 •JSP 页面:修改JS的Ajax请求逻辑:若修改回之前的lastName则不发送任何请求,直接弹出“用户名可用”
完成修改
•URL:emp/id,method:PUT •Dao 层:继续使用saveAndFlush 方法即可 •Service 层: –不需要设置 createTime 属性 –判定添加和修改的标准:传入的 bean 的id 是否为null •Cotroller 层: –新建 @ModelAttribute 注解修饰的方法,在其中利用id 获取对应的bean,并把该bean 放入到map 中,键为:Employee 类名第一个字母小写 –在 @ModelAttribute 方法中,把关联的department 置为 null –调用 Service 的方法进行更新 –重定向到:/emps •JSP 页面:id 和_method 加入到隐藏域中。
完成删除
•URL:emp/id、method:DELETE •Dao 层:直接使用 SpringData 已经自带的delete 方法即可 •Service层:直接调用 Dao 方法即可 •Controller层: –直接调用 Service 方法 –重定向到 /emps •JSP 页面: –使用 JSconfirm:确定要删除xx 的信息吗 –把超链接的GET 请求转为POST 请求,且携带_method=DELETE 的请求参数
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_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 配置启动 IOC 容器的 Listener -->
<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>
<!-- 配置字符编码过滤器 -->
<!-- 字符编码过滤器必须配置在所有过滤器的最前面! -->
<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>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置可以把 POST 请求转为 PUT、DELETE 请求的 Filter -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置 OpenEntityManagerInViewFilter. 可以解决懒加载异常的问题 -->
<filter>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置 SpringMVC 的 DispatcherServlet -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
springDispatcherServlet-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
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-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.atguigu.sssp" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
index.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 here</title>
</head>
<body>
<a href="emps">List All Employees</a>
<br><br>
<a href="emp">Add New Employee</a>
</body>
</html>
views/emp
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" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!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>
<script type="text/javascript" src="$pageContext.request.contextPath /scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function()
$(".delete").click(function()
var label = $(this).next(":hidden").val();
var flag = confirm("确定要删除" + label + "的信息吗?");
if(flag)
var url = $(this).attr("href");
$("#_form").attr("action", url);
$("#_method").val("DELETE");
$("#_form").submit();
return false;
);
)
</script>
</head>
<body>
<form action="" method="POST" id="_form">
<input type="hidden" id="_method" name="_method"/>
</form>
<c:if test="$page == null || page.numberOfElements == 0 ">
没有任何记录.
</c:if>
<c:if test="$page != null && page.numberOfElements > 0 ">
<table border="1" cellpadding="10" cellspacing="0">
<tr>
<th>ID</th>
<th>LastName</th>
<th>Email</th>
<th>Birth</th>
<th>CreateTime</th>
<th>Department</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<c:forEach items="$page.content " var="emp">
<tr>
<td>$emp.id </td>
<td>$emp.lastName </td>
<td>$emp.email </td>
<td>
<fmt:formatDate value="$emp.birth " pattern="yyyy-MM-dd"/>
</td>
<td>
<fmt:formatDate value="$emp.createTime " pattern="yyyy-MM-dd hh:mm:ss"/>
</td>
<td>$emp.department.departmentName </td>
<td><a href="$pageContext.request.contextPath /emp/$emp.id">Edit</a></td>
<td>
<a href="$pageContext.request.contextPath /emp/$emp.id" class="delete">Delete</a>
<input type="hidden" value="$emp.lastName "/>
</td>
</tr>
</c:forEach>
<tr>
<td colspan="8">
共 $page.totalElements 条记录
共 $page.totalPages 页
当前 $page.number + 1 页
<a href="?pageNo=$page.number + 1 - 1 ">上一页</a>
<a href="?pageNo=$page.number + 1 + 1 ">下一页</a>
</td>
</tr>
</table>
</c:if>
</body>
</html>
input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ 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>
<script type="text/javascript" src="$pageContext.request.contextPath /scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function()
$("#lastName").change(function()
var val = $(this).val();
val = $.trim(val);
$(this).val(val);
//若修改的 lastName 和之前的 lastName 一致, 则不发送 Ajax 请求, 直接 alert:lastName 可用!
var _oldLastName = $("#_oldLastName").val();
_oldLastName = $.trim(_oldLastName);
if(_oldLastName != null && _oldLastName != "" && _oldLastName == val)
alert("lastName 可用!");
return;
var url = "$pageContext.request.contextPath /ajaxValidateLastName";
var args = "lastName":val,"date":new Date();
$.post(url, args, function(data)
if(data == "0")
alert("lastName 可用!");
else if(data == "1")
alert("lastName 不可用!");
else
alert("网络或程序出错. ");
);
);
)
</script>
</head>
<body>
<c:set value="$pageContext.request.contextPath /emp" var="url"></c:set>
<c:if test="$employee.id != null ">
<c:set value="$pageContext.request.contextPath /emp/$employee.id" var="url"></c:set>
</c:if>
<form:form action="$url " method="POST" modelAttribute="employee">
<c:if test="$employee.id != null ">
<input type="hidden" id="_oldLastName" value="$employee.lastName "/>
<form:hidden path="id"/>
<input type="hidden" name="_method" value="PUT"/>
</c:if>
LastName: <form:input path="lastName" id="lastName"/>
<br>
Email: <form:input path="email"/>
<br>
Birth: <form:input path="birth"/>
<br>
Department:
<form:select path="department.id" items="$departments "
itemLabel="departmentName" itemValue="id"></form:select>
<br>
<input type="submit" value="Submit"/>
</form:form>
</body>
</html>
db.properties
jdbc.user=root
jdbc.password=1230
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring
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:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.atguigu.sssp">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 配置数据源 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="$jdbc.user"></property>
<property name="password" value="$jdbc.password"></property>
<property name="driverClass" value="$jdbc.driverClass"></property>
<property name="jdbcUrl" value="$jdbc.jdbcUrl"></property>
<!-- 配置其他属性 -->
</bean>
<!-- 配置 JPA 的 EntityManagerFactory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<property name="packagesToScan" value="com.atguigu.sssp"></property>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<property name="sharedCacheMode" value="ENABLE_SELECTIVE"></property>
</bean>
<!-- 配置事务 -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 配置支持基于注解的事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置 SpringData -->
<jpa:repositories base-package="com.atguigu.sssp"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
</beans>
entity
Department.java
package com.atguigu.sssp.entity;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Cacheable
@Table(name="SSSP_DEPARTMENTS")
@Entity
public class Department
private Integer id;
private String departmentName;
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getDepartmentName()
return departmentName;
public void setDepartmentName(String departmentName)
this.departmentName = departmentName;
Employee.java
package com.atguigu.sssp.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.format.annotation.DateTimeFormat;
@Table(name="SSSP_EMPLOYEES")
@Entity
public class Employee
private Integer id;
private String lastName;
private String email;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
private Date createTime;
private Department department;
@GeneratedValue
@Id
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getLastName()
return lastName;
public void setLastName(String lastName)
this.lastName = lastName;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
@Temporal(TemporalType.DATE)
public Date getBirth()
return birth;
public void setBirth(Date birth)
this.birth = birth;
@Temporal(TemporalType.TIMESTAMP)
public Date getCreateTime()
return createTime;
public void setCreateTime(Date createTime)
this.createTime = createTime;
@JoinColumn(name="DEPARTMENT_ID")
@ManyToOne(fetch=FetchType.LAZY)
public Department getDepartment()
return department;
public void setDepartment(Department department)
this.department = department;
repository
DepartmentRepository.java
package com.atguigu.sssp.repository;
import java.util.List;
import javax.persistence.QueryHint;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import com.atguigu.sssp.entity.Department;
public interface DepartmentRepository extends JpaRepository<Department, Integer>
@QueryHints(@QueryHint(name=org.hibernate.ejb.QueryHints.HINT_CACHEABLE,value="true"))
@Query("FROM Department d")
List<Department> getAll();
EmployeeRepository.java
package com.atguigu.sssp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.atguigu.sssp.entity.Employee;
public interface EmployeeRepository extends JpaRepository<Employee, Integer>
Employee getByLastName(String lastName);
service
DepartmentService.java
package com.atguigu.sssp.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.atguigu.sssp.entity.Department;
import com.atguigu.sssp.repository.DepartmentRepository;
@Service
public class DepartmentService
@Autowired
private DepartmentRepository departmentRepository;
@Transactional(readOnly=true)
public List<Department> getAll()
return departmentRepository.getAll();
EmployeeService.java
package com.atguigu.sssp.service;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.atguigu.sssp.entity.Employee;
import com.atguigu.sssp.repository.EmployeeRepository;
@Service
public class EmployeeService
@Autowired
private EmployeeRepository employeeRepository;
@Transactional
public void delete(Integer id)
employeeRepository.delete(id);
@Transactional(readOnly=true)
public Employee get(Integer id)
return employeeRepository.findOne(id);
@Transactional
public void save(Employee employee)
if(employee.getId() == null)
employee.setCreateTime(new Date());
employeeRepository.saveAndFlush(employee);
@Transactional(readOnly=true)
public Employee getByLastName(String lastName)
return employeeRepository.getByLastName(lastName);
@Transactional(readOnly=true)
public Page<Employee> getPage(int pageNo, int pageSize)
PageRequest pageable = new PageRequest(pageNo - 1, pageSize);
return employeeRepository.findAll(pageable);
handler
EmployeeHandler.java
package com.atguigu.sssp.handler;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
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.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.atguigu.sssp.entity.Employee;
import com.atguigu.sssp.service.DepartmentService;
import com.atguigu.sssp.service.EmployeeService;
@Controller
public class EmployeeHandler
@Autowired
private EmployeeService employeeService;
@Autowired
private DepartmentService departmentService;
@RequestMapping(value="/emp/id",method=RequestMethod.DELETE)
public String delete(@PathVariable("id") Integer id)
employeeService.delete(id);
return "redirect:/emps";
@ModelAttribute
public void getEmployee(@RequestParam(value="id",required=false) Integer id,
Map<String, Object> map)
if(id != null)
Employee employee = employeeService.get(id);
employee.setDepartment(null);
map.put("employee", employee);
@RequestMapping(value="/emp/id",method=RequestMethod.PUT)
public String update(Employee employee)
employeeService.save(employee);
return "redirect:/emps";
@RequestMapping(value="/emp/id", method=RequestMethod.GET)
public String input(@PathVariable("id") Integer id, Map<String, Object> map)
Employee employee = employeeService.get(id);
map.put("employee", employee);
map.put("departments", departmentService.getAll());
return "emp/input";
@RequestMapping(value="/emp",method=RequestMethod.POST)
public String save(Employee employee)
employeeService.save(employee);
return "redirect:/emps";
@ResponseBody
@RequestMapping(value="/ajaxValidateLastName",method=RequestMethod.POST)
public String validateLastName(@RequestParam(value="lastName",required=true) String lastName)
Employee employee = employeeService.getByLastName(lastName);
if(employee == null)
return "0";
else
return "1";
@RequestMapping(value="/emp",method=RequestMethod.GET)
public String input(Map<String,Object> map)
map.put("departments", departmentService.getAll());
map.put("employee", new Employee());
return "emp/input";
@RequestMapping("/emps")
public String list(@RequestParam(value="pageNo", required=false, defaultValue="1") String pageNoStr,
Map<String, Object> map)
int pageNo = 1;
try
//对 pageNo 的校验
pageNo = Integer.parseInt(pageNoStr);
if(pageNo < 1)
pageNo = 1;
catch (Exception e)
Page<Employee> page = employeeService.getPage(pageNo, 5);
map.put("page", page);
return "emp/list";
以上是关于SpringMVC + Spring + SpringDataJPA 整合的主要内容,如果未能解决你的问题,请参考以下文章