涉及技术:
–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
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
CharacterEncodingFilter
/*
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
OpenEntityManagerInViewFilter
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
OpenEntityManagerInViewFilter
/*
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
1
springDispatcherServlet
/
springDispatcherServlet-servlet.xml
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" %>
Insert title here
没有任何记录.
ID
LastName
Email
Birth
CreateTime
Department
Edit
Delete
${emp.id }
${emp.lastName }
${emp.email }
${emp.department.departmentName }
Edit
Delete
共 ${page.totalElements } 条记录
共 ${page.totalPages } 页
当前 ${page.number + 1 } 页
上一页
下一页
input.jsp
db.properties
jdbc.user=root
jdbc.password=1230
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring
applicationContext.xml
org.hibernate.cfg.ImprovedNamingStrategy
update
true
true
org.hibernate.dialect.MySQL5InnoDBDialect
true
org.hibernate.cache.ehcache.EhCacheRegionFactory
true
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{
@QueryHints({@QueryHint(name=org.hibernate.ejb.QueryHints.HINT_CACHEABLE,value="true")})
@Query("FROM Department d")
List 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 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 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 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 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 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 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 map){
int pageNo = 1;
try {
//对 pageNo 的校验
pageNo = Integer.parseInt(pageNoStr);
if(pageNo < 1){
pageNo = 1;
}
} catch (Exception e) {}
Page page = employeeService.getPage(pageNo, 5);
map.put("page", page);
return "emp/list";
}
}