简介

Spring、SpringMVC、SpringData、JPA的整合的一个例子
实现:
1. SpringMVC、Spring、SpringData\JPA 整合完成 CRUD、翻页
2. 基于Restful 风格
3. 使用 JPA 二级缓存
4. 使用 @ResponseBody 注解完成 Ajax

整合文件配置

先上一张配好后的截图

1. Web.xml配置

  1. 配置了Spring的核心监听器
  2. 配置字符编码过滤器
  3. 配置 SpringMVCDispatcherServlet
  4. 配置可以把 POST请求转为 DELETEPOST请求的HiddenHttpMethodFilter
  5. 配置 OpenEntityManagerInViewFilter. 解决懒加载异常的问题
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd"><display-name></display-name> <!-- 1. 配置 Spring 的核心监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置spring的applicationContext.xml --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!-- 2. 配置字符编码过滤器,必须在所有的filter最前面 --><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>  <!-- 3. 配置 SpringMVC 的DispatcherServlet --><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/springDispatcherServlet-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 4. 配置可以把 POST 请求转为 DELETE 或 POST 请求 --><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>  <!-- 5. 配置 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><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list>
</web-app>

2.配置数据源jdbc.properties

jdbc.user=root
jdbc.password=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://127.0.0.1\:3306/sssp

3. 配置JPA的二级缓存配置文件ehcache.xml

ehcache.xml:

<ehcache><!-- Sets the path to the directory where cache .data files are created.If the path is a Java System Property it is replaced byits value in the running VM.The following properties are translated:user.home - User's home directoryuser.dir - User's current working directoryjava.io.tmpdir - Default temp file path --><diskStore path="java.io.tmpdir"/><!--Default Cache configuration. These will applied to caches programmatically created throughthe CacheManager.The following attributes are required for defaultCache:maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><defaultCache
        maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"/><!--Predefined caches.  Add your cache configuration settings here.If you do not have a configuration for your cache a WARNING will be issued when theCacheManager startsThe following attributes are required for defaultCache:name              - Sets the name of the cache. This is used to identify the cache. It must be unique.maxInMemory       - Sets the maximum number of objects that will be created in memoryeternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the elementis never expired.timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only usedif the element is not eternal. Idle time is now - last accessed timetimeToLiveSeconds - Sets the time to live for an element before it expires. Is only usedif the element is not eternal. TTL is now - creation timeoverflowToDisk    - Sets whether elements can overflow to disk when the in-memory cachehas reached the maxInMemory limit.--><!-- Sample cache named sampleCache1This cache contains a maximum in memory of 10000 elements, and will expirean element if it is idle for more than 5 minutes and lives for more than10 minutes.If there are more than 10000 elements it will overflow to thedisk cache, which in this configuration will go to wherever java.io.tmp isdefined on your system. On a standard Linux system this will be /tmp"--><cache name="sampleCache1"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="true"/><!-- Sample cache named sampleCache2This cache contains 1000 elements. Elements will always be held in memory.They are not expired. --><cache name="sampleCache2"maxElementsInMemory="1000"eternal="true"timeToIdleSeconds="0"timeToLiveSeconds="0"overflowToDisk="false"/> --><!-- Place configuration for your caches following --></ehcache>

4. 配置Spring的配置文件applicationContext.xml

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.xsdhttp://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- 1. 配置自动扫描的包 --><context:component-scan base-package="com.bart.sssp"><!-- 过滤SpringMVC的注解不扫描 --><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><!-- 2. 配置数据源 --><context:property-placeholder location="classpath:jdbc.properties"/><!-- C3P0连接池 --><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.url}"></property></bean><!-- 3. 配置 JPA 的EntityManagerFactory --><bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 3.1 配置 JPA 提供商的适配器. 可以通过内部 bean 的方式来配置 --><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean></property><!-- 3.2 配置实体类所在的包 --><property name="packagesToScan" value="com.bart.sssp" /><!-- 3.3 配置 JPA 的基本属性 --><property name="jpaProperties"><props><prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop><!-- Hibernate 基本属性 --><prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</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><!-- 4. 配置事务管理 --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory"></property></bean><!-- 5. 配置支持注解的事务 --><tx:annotation-driven transaction-manager="transactionManager"/><!-- 6. 配置 SpringData --><!-- 加入 jpa 的命名空间 --><!-- base-package: 扫描 Repository Bean 所在的 package --> <jpa:repositories base-package="com.bart.sssp"entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
</beans>

5. 配置SpringMVC的配置文件springDispatcherServlet-servlet.xml

注意,该配置文件必须放在/WEB-INF/目录下,web.xml在加载的时候会主动加载该配置文件
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.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- 1. 配置自动扫描的包 --><context:component-scan base-package="com.bart.sssp" use-default-filters="false"><!-- 这两个注解交给SpringMVC管理,其他的交给 IOC 容器 --><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><!-- 2. 配置视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"/><property name="suffix" value=".jsp"/></bean><mvc:default-servlet-handler/><mvc:annotation-driven></mvc:annotation-driven>
</beans>

6. 创建entity

6.1 Employee.java

package com.bart.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@Idpublic 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;}
}

6.2Department.java

package com.bart.sssp.entity;import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;@Cacheable(true)//设置二级缓存
@Table(name="SSSP_DEPARTMENTS")
@Entity
public class Department {private Integer id;private String departmentName;@GeneratedValue@Idpublic 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;}}

7. Repository配置

7.1 EmployeeRepository

package com.bart.sssp.repository;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;import com.bart.sssp.entity.Employee;public interface EmployeeRepository extends JpaRepository<Employee,Integer>{//自定义查询方法@Query("from Employee e where e.lastName=:lastName")public Employee getByName(@Param("lastName")String lastName);}

7.2 DepartmentRepository

package com.bart.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.bart.sssp.entity.Department;public interface DepartmentRepository extends JpaRepository<Department,Integer>{//配置二级缓存@QueryHints(value={@QueryHint(name=org.hibernate.ejb.QueryHints.HINT_CACHEABLE,value="true")})@Query("from Department d")public List<Department> getAll();
}

8. Service

8.1 EmployeeService

package com.bart.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.bart.sssp.entity.Employee;
import com.bart.sssp.repository.EmployeeRepository;@Service
public class EmployeeService {@Autowiredprivate EmployeeRepository employeeRepository;@Transactionalpublic void delete(Integer id){employeeRepository.delete(id);}@Transactionalpublic Employee getById(Integer id){return employeeRepository.findOne(id);}@Transactionalpublic Employee getByName(String lastName) {return employeeRepository.getByName(lastName);}//保存@Transactionalpublic void save(Employee employee){//当id为空表示新添加的,set创建时间if(employee.getId() == null){employee.setCreateTime(new Date());}employeeRepository.saveAndFlush(employee);}@Transactional(readOnly=true)public Page<Employee> getPage(Integer pageNo,Integer pageSize){PageRequest pageRequest= new PageRequest(pageNo-1,pageSize);Page<Employee>page = employeeRepository.findAll(pageRequest);return page;}}

8.2 DepartmentService

package com.bart.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.bart.sssp.entity.Department;
import com.bart.sssp.repository.DepartmentRepository;
@Service
public class DepartmentService {@Autowiredprivate DepartmentRepository departmentRepository;@Transactional(readOnly=true)public List<Department> getAll(){return departmentRepository.getAll();}}

9. Handler

package com.bart.sssp.handler;import java.util.Map;import javax.persistence.Id;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.bart.sssp.entity.Employee;
import com.bart.sssp.service.DepartmentService;
import com.bart.sssp.service.EmployeeService;@Controller
public class EmployeeHandler {@Autowiredprivate EmployeeService employeeService;@Autowiredprivate DepartmentService departmentService;@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)public String delete(@PathVariable(value="id")Integer id){employeeService.delete(id);return "redirect:/emps";}/**  @ModelAttribute *  当传进来的有id的时候表示是编辑操作,提前把employee放到值栈(Map)中*  修改department之后,因为在Map中的employee中的departmentId还指向*  旧的departmentId,的那是hibernate是不允许直接修改主键id的*  所以在放入Map之前应该先置空*/@ModelAttributepublic void getEmployee(@RequestParam(value="id",required=false) Integer id,Map<String, Object> map){if(id!=null){Employee employee = employeeService.getById(id);employee.setDepartment(null);map.put("employee",employee);}}/*** 保存编辑* @param employee* @return*/@RequestMapping(value="/emp/{id}",method=RequestMethod.PUT)public String update(Employee employee){employeeService.save(employee);return "redirect:/emps";}/*** 进入编辑界面* @param id* @param map* @return*/@RequestMapping(value="/emp/{id}",method=RequestMethod.GET)public String input(@PathVariable("id")Integer id,Map<String,Object>map){map.put("employee", employeeService.getById(id));map.put("departments", departmentService.getAll());return "input";}/*** Ajax验证用户名是否已使用* @param lastName* @return*/@ResponseBody//内容或对象作为 HTTP 响应正文返回 @RequestMapping(value="ajaxValidateLastName",method=RequestMethod.POST)public String ajaxValidateLastName(@RequestParam(value="lastName",required=true)String lastName){if(employeeService.getByName(lastName)!=null){return "1";}else {return "0";}}/*** 添加新员工保存* @param employee* @return*/@RequestMapping(value="/emp",method=RequestMethod.POST)public String save(Employee employee){employeeService.save(employee);return "redirect:/emps";}/*** input.jsp 添加* @param map* @return*/@RequestMapping(value="/emp",method=RequestMethod.GET)public String input(Map<String , Object>map){//用于回显,相当于struts2的prepare方法,在值栈放入Employee对象 map.put("departments", departmentService.getAll());map.put("employee", new Employee());return "input";}/*** 分页列出所有的employee* @param pageStr* @param map* @return*/@RequestMapping("/emps")public String list(@RequestParam(value="pageNo",required=false,defaultValue="1")String pageNoStr,Map<String, Object>map){int pageNo = 1;try {//对传进来的pageNoStr 进行校验pageNo=Integer.parseInt(pageNoStr);if(pageNo<1)pageNo=1;} catch (Exception e) {}Page<Employee>page = employeeService.getPage(pageNo,5);map.put("page", page);return "list";}}

10.测试类

package com.bart.sssp.test;import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.sql.DataSource;import org.hibernate.ejb.QueryHints;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.bart.sssp.entity.Department;
import com.bart.sssp.entity.Employee;
import com.bart.sssp.repository.EmployeeRepository;public class TestSSSP {private ApplicationContext context = null;private EmployeeRepository employeeRepository=null;private EntityManagerFactory entityManagerFactory;{context = new ClassPathXmlApplicationContext("applicationContext.xml");employeeRepository = context.getBean(EmployeeRepository.class);entityManagerFactory = context.getBean(EntityManagerFactory.class);}//测试getByName查询@Testpublic void testGetByName(){System.out.println(employeeRepository.getByName("aa").getLastName());}//测试二级缓存Jpa@Testpublic void testJpaSecondLevelCache(){String jpql = "from Department d";EntityManager entityManager = entityManagerFactory.createEntityManager();Query query = entityManager.createQuery(jpql);List<Department> departments = query.setHint(QueryHints.HINT_CACHEABLE, true).getResultList();entityManager.close();entityManager = entityManagerFactory.createEntityManager();query = entityManager.createQuery(jpql);departments = query.setHint(QueryHints.HINT_CACHEABLE, true).getResultList();entityManager.close();}//测试插入数据@Testpublic void testInsert(){List<Employee>list = new ArrayList<Employee>();for(int i='a';i<='z';i++){Employee employee = new Employee();employee.setLastName((char)i+""+(char)i);employee.setEmail((char)i+""+(char)i+"@163.com");employee.setBirth(new Date());employee.setCreateTime(new Date());list.add(employee);}employeeRepository.save(list);}//测试数据库连接池@Testpublic void testDataSource() throws SQLException{DataSource dataSource = context.getBean(DataSource.class);System.out.println(dataSource.getConnection());}}

11. jsp页面

11.1 list.jsp

<%@ page language="java" import="java.util.*" 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" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><base href="<%=basePath%>"><title>My JSP 'index.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"><script type="text/javascript" src="<%=request.getContextPath()%>/scripts/jquery-1.9.1.min.js"></script><script type="text/javascript" >$(function(){$(".delete").click(function(){var lsatName = $(this).next(":hidden").val();var flg = confirm("确定要删除"+lsatName+"吗?");if(flg){var url = $(this).attr("href");$("#form").attr("action",url);$("#form").submit();}return false;})})</script></head><body><!-- 放置一个隐藏的form用来把delete请求发送过去 --><form:form action="" method="POST" id="form"><input type="hidden" name="_method" value="DELETE"/></form: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>Delete</th><th>Edit</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}" class="delete">Delete</a><input type="hidden" id="lastName" value="${emp.lastName}"/></td><td><a href="${pageContext.request.contextPath}/emp/${emp.id}">Edit</a></td><tr></c:forEach><tr><td colspan="8">总共${page.totalElements}条记录&nbsp总共${page.totalPages}页&nbsp当前为第${page.number+1}页&nbsp<c:if test="${(page.number+1) != 1}"><a href="<%=request.getContextPath()%>/emps?pageNo=1">首&nbsp页</a>&nbsp      <a href="<%=request.getContextPath()%>/emps?pageNo=${page.number+1-1}">上一页</a>&nbsp      </c:if><c:if test="${(page.number+1) != (page.totalPages)}"><a href="<%=request.getContextPath()%>/emps?pageNo=${page.number+1+1}">下一页</a>&nbsp      <a href="<%=request.getContextPath()%>/emps?pageNo=${page.totalPages}">尾&nbsp页</a>&nbsp      </c:if></td></tr></table></c:if></body>
</html>

11.2 input.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><base href="<%=basePath%>"><title>My JSP 'index.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"><script type="text/javascript" src="<%=request.getContextPath()%>/scripts/jquery-1.9.1.min.js"></script><script type="text/javascript" >$(function(){$("#lastName").change(function(){var lastName = $(this).val();lastName = $.trim(lastName);$(this).val(lastName);var $this = $(this);$this.nextAll("font").remove();//如果修改的后的lastName和之前的一样就不发送Ajax请求var oldLastName = $("#_oldLastName").val();oldLastName = $.trim(oldLastName);if(oldLastName !="" && oldLastName != "" && oldLastName == lastName){$this.after("<font color='green'>名字可用</font>");return;}//Ajaxif(lastName!=""){var url = "${pageContext.request.contextPath}/ajaxValidateLastName";var args = {"lastName":lastName,"time":new Date()};$.post(url,args,function(data){if(data == "1"){$this.after("<font color='red'>名字不可用</font>");}else if(data == "0"){$this.after("<font color='green'>名字可用</font>");}else{alert("系统错误,请刷新,重试!");}      });}else {alert("lastName 不能为空");$(this).val("");$this.focus();     }});})</script></head><body><c:set value="${pageContext.request.contextPath }/emp" var="url"/><!-- 当id不为空表示是在编辑 提交的action必须改变为 PUT 请求 --><c:if test="${employee.id != null }"><c:set value="${pageContext.request.contextPath }/emp/${employee.id}" var="url"/></c:if><form:form action="${url}" methd="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"/><br>   <input type="submit" value="提交"/>   </form:form></body>
</html>

11.3 index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><body><a href="<%=request.getContextPath()%>/emps">lis all</a><br><br><a href="<%=request.getContextPath()%>/emp">add emp</a><br><br></body>
</html>

效果

  1. 浏览器输入http://localhost:8088/A02-SSSP/
  2. 测试add emp
    • 测试Ajax的查询功能,当用户名存在提示“用户名不可用”否则提示“用户名可用”
    • 点击提交保存,并且重定向到emps的list
  3. 测试edit
    在/emps界面选择一个employee点击edit,这里以LastName为”bb”为例:

    可以看到有回显,并且在修改如果修改的用户名和之前的一样不用再进行Ajax请求了
  4. 测试delete
    还是以用户”bb”为例,当点击delete的时候提示是否删除用户,并提示该用户的用户名
    如果点击“是”,则删除“否”不作任何操作

SSSP整合分页CRUD相关推荐

  1. SSM整合+分页+Druid+CRU+log4J+junit+事务+Json+Bootstrap入门教程总览目录

    总目录 1.快速入门SSM整合配置建立第一个SSM项目模板 https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/85052628 2.实 ...

  2. 整合分页pageHelper||整合分页pageHelper-starter不用做任何分页相关的配置

    修改pom.xml引入pageHelper的依赖 <dependency><groupId>com.github.pagehelper</groupId><a ...

  3. Struts2.1.6+Spring2.5.6+Hibernate3.3.2+mysql整合+分页模板

    Struts2.1.6+Spring2.5.6+Hibernate3.3.2+mysql整合+分页模板 博客分类: Java MySQLHibernateAOPSpringStruts  1.导入29 ...

  4. SSM框架整合之CRUD操作

    SSM框架整合之CRUD操作 说明: 主要将SSM框架整合,做简单的业务逻辑操作CRUD,所以前端并不怎么好看,但是业务逻辑更集中SSM整合和CRUD操作,非常适合刚学过Sping + SpringM ...

  5. 结合Layui框架,实现SpringMVC+Spring+Mybatis,SSM整合案例CRUD(超详细代码,外加说明)

    首先: 你需要去Layui官网下载UI框架.你可能会问,为什么用Layui实现页面效果?简单来说就是:简单.好用.上手快,作为JAVA后端开发人员,Layui无疑是非常友好的,拿来即用. 页面效果图: ...

  6. Spring+SpringMVC+Hibernate整合(封装CRUD操作)

    前言:当前Web项目开发的框架主流应该非Spring+SpringMVC+Hibernate莫属,不管是工作还是学习中涉及框架技术,首先是要搭建一套运行环境,虽然网上框架整合的教程很多,但我还是输出此 ...

  7. ssm框架整合的crud项目详细步骤

    文章目录 由于很多图片加载不出来,点击这,看完整版 ssm_crud项目 一.项目说明 1.项目预览 2.项目的功能点 3.项目技术点 二.基础环境的搭建 1.创建maven工程 2.引入项目依赖的j ...

  8. SSM整合及CRUD实现

    文章目录 1. 基本环境搭建 2. Mybaitis层 3. Spring层 4. SpringMVC 5. CRUD业务测试 1. 基本环境搭建 数据库 CREATE DATABASE `ssmbu ...

  9. springboot整合分页插件PageHelper

    一. 概述 后端开发80%都是查询操作, 而查询经常涉及到数据分页, 分页工具有很多, 本文介绍的是分页插件PageHelper, 工程基于springboot 参考文章: springBoot my ...

最新文章

  1. Php的if自动转换类型,php之数据类型自动转换,php之数据类型转换_PHP教程
  2. What you need to know about AllowUnsafeUpdates (Part 1) [转载]
  3. 拉格朗日插值--等距节点Python实现并计算误差
  4. 打印二叉树的边界节点
  5. “烟花”来势汹汹!用数据可视化告诉你:台风最爱在哪登陆?
  6. get_free_page 和其友
  7. Irrlicht例002--Quake3Map
  8. 生活随笔:怀念大学时代
  9. Java学习之道:jdk环境变量配置方法
  10. 拓端tecdat|R语言社区检测算法可视化网络图:ggplot2绘制igraph对象分析物种相对丰度
  11. 通达信的指标公式改为条件选股公式,进行预警
  12. C++银行账户管理程序2
  13. 99乘法表儿歌_乘法口诀表儿歌
  14. 以大数据架构电商2.0的新时代
  15. 保险精算--第13周作业
  16. 迅雷该怎么把区块链这件事做好?
  17. KVM 虚拟化技术性能调优实战
  18. 微信小程序图片(头像)裁剪工具we-cropper含2d版-完整版
  19. 这9个程序员岗位最牛!AI百万年薪夺冠
  20. 转载-大数据管理神器:Ambari自定义stack和服务二次开发详细教程

热门文章

  1. 原来卡布奇诺信息安全协会是干这个的呀,一起来看看吧。
  2. SpringBoot里参数校验/参数验证
  3. 数学之美-读书笔记11-15章
  4. ACM中的整数K拆分 (有条件限制 无条件限制 插板法 URAL-1036 HDU-6397)
  5. 2021级程序设计ICODING答案分享
  6. cesium实现鹰眼地图(三维)效果
  7. 解决vue项目中@mousemove 事件 子元素触发了父元素事件
  8. 复杂SQL语句练习【III】
  9. 已知三角形三边长求面积java_已知三角形三点坐标求三角形面积.java
  10. paper 94:视觉领域博客资源1之中国部分