SSSP整合&&分页&&CRUD
来源:互联网 发布:top域名有价值吗 编辑:程序博客网 时间:2024/06/01 12:53
简介
Spring、SpringMVC、SpringData、JPA的整合的一个例子
实现:
1. SpringMVC、Spring、SpringData\JPA 整合完成 CRUD、翻页
2. 基于Restful 风格
3. 使用 JPA 二级缓存
4. 使用 @ResponseBody 注解完成 Ajax
整合文件配置
先上一张配好后的截图
1. Web.xml配置
- 配置了
Spring
的核心监听器 - 配置字符编码过滤器
- 配置
SpringMVC
的DispatcherServlet
- 配置可以把
POST
请求转为DELETE
或POST
请求的HiddenHttpMethodFilter
- 配置
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=rootjdbc.password=123456jdbc.driverClass=com.mysql.jdbc.Driverjdbc.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 by its value in the running VM. The following properties are translated: user.home - User's home directory user.dir - User's current working directory java.io.tmpdir - Default temp file path --> <diskStore path="java.io.tmpdir"/> <!--Default Cache configuration. These will applied to caches programmatically created through the CacheManager. The following attributes are required for defaultCache: maxInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has 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 the CacheManager starts The 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 memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. --> <!-- Sample cache named sampleCache1 This cache contains a maximum in memory of 10000 elements, and will expire an element if it is idle for more than 5 minutes and lives for more than 10 minutes. If there are more than 10000 elements it will overflow to the disk cache, which in this configuration will go to wherever java.io.tmp is defined 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 sampleCache2 This 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.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"> <!-- 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.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"> <!-- 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")@Entitypublic 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; }}
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")@Entitypublic 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; }}
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;@Servicepublic class EmployeeService { @Autowired private EmployeeRepository employeeRepository; @Transactional public void delete(Integer id){ employeeRepository.delete(id); } @Transactional public Employee getById(Integer id){ return employeeRepository.findOne(id); } @Transactional public Employee getByName(String lastName) { return employeeRepository.getByName(lastName); } //保存 @Transactional public 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;@Servicepublic class DepartmentService { @Autowired private 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;@Controllerpublic class EmployeeHandler { @Autowired private EmployeeService employeeService; @Autowired private 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之前应该先置空 */ @ModelAttribute public 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查询 @Test public void testGetByName(){ System.out.println(employeeRepository.getByName("aa").getLastName()); } //测试二级缓存Jpa @Test public 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(); } //测试插入数据 @Test public 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); } //测试数据库连接池 @Test public 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}条记录  总共${page.totalPages}页  当前为第${page.number+1}页  <c:if test="${(page.number+1) != 1}"> <a href="<%=request.getContextPath()%>/emps?pageNo=1">首 页</a>  <a href="<%=request.getContextPath()%>/emps?pageNo=${page.number+1-1}">上一页</a>  </c:if> <c:if test="${(page.number+1) != (page.totalPages)}"> <a href="<%=request.getContextPath()%>/emps?pageNo=${page.number+1+1}">下一页</a>  <a href="<%=request.getContextPath()%>/emps?pageNo=${page.totalPages}">尾 页</a>  </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; } //Ajax if(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>
效果
- 浏览器输入http://localhost:8088/A02-SSSP/
- 测试add emp
- 测试Ajax的查询功能,当用户名存在提示“用户名不可用”否则提示“用户名可用”
- 点击提交保存,并且重定向到emps的list
- 测试Ajax的查询功能,当用户名存在提示“用户名不可用”否则提示“用户名可用”
- 测试edit
在/emps界面选择一个employee点击edit,这里以LastName为”bb”为例:
可以看到有回显,并且在修改如果修改的用户名和之前的一样不用再进行Ajax请求了 - 测试delete
还是以用户”bb”为例,当点击delete的时候提示是否删除用户,并提示该用户的用户名
如果点击“是”,则删除“否”不作任何操作
1 0
- SSSP整合&&分页&&CRUD
- SSSP-CRUD-查询-分页
- sssp整合&分页之分页操作
- sssp整合&分页之完成添加
- sssp整合分页之完成删除操作
- SSSP-CRUD-简介
- SSSP-CRUD-删除
- SSSP-CRUD-添加
- SSSP-CRUD-修改
- sssp整合分页之完成修改操作(三)【具体操作】
- sssp整合&分页之完成添加操作之显示页面&使用JPA二级缓存
- sssp整合&分页之完成添加操作之Ajax 验证用户名可用性
- sssp整合分页之完成修改操作(一)【表单回显】
- sssp整合分页之完成修改操作(二)【修改状态下Ajax验证用户名可用性】
- SSSP整合:Context initialization failed
- SSSP框架整合之路
- SSM框架整合(基本CRUD+分页+Excel导入导出)
- 拿走即用的spring mvc整合mybatis(crud+分页插件)操作mysql
- MaxCompute的分区配置和使用
- SqlServer:死锁查询及进程信息查询
- HongKong二日初体验?
- 关于Hadoop安全集群和非安全集群间Distcp的使用
- Linux无损扩展分区
- SSSP整合&&分页&&CRUD
- 重建二叉树
- SpringBoot微服务 +tomcat集群+Ngnix负载均衡+Mysql主从复制,读写分离(2)
- window下es的head插件安装
- 阿里云SLB HTTPS证书配置
- java 整合redis缓存 springmvc SSM后台框架源码 rest接口 shiro
- idea 下载 git插件
- 我的maven配置/
- Linux——iscsiadm基本用法