- 實體類
@Cacheable
@Table(name="SSSP_DEPARTMENT")
@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;
}
@Override
public String toString() {
return "Department [id=" + id + ", departmentName=" + departmentName + "]";
}
}
@Table(name="SSSP_EMPLOYEE")
@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)
@JoinColumn(name="DEPARTMENT_ID") //外鍵
@ManyToOne(fetch=FetchType.LAZY)
public Department getDepartment() {
return department;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", birth=" + birth
+ ", creatTime=" + createTime + ", department=" + department + "]";
}
}
- DAO層
public interface EmployeeRepository extends JpaRepository<Employee, Integer>{
Employee getByLastName(String lastName);
}
public interface DepartmentRepository extends JpaRepository<Department, Integer>{
/**
*定義開啓二級緩存的方法
* @return
*/
@QueryHints({@QueryHint(name=org.hibernate.ejb.QueryHints.HINT_CACHEABLE,value="true")})
@Query("FROM Department d")
List<Department>
- service層
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
/**
* 刪除
* @param id
*/
public void delete(Integer id){
employeeRepository.delete(id);
}
/**
* 查詢單獨一條數據 此方法有Spring Data 提供
* @param id
* @return
*/
public Employee get(Integer id){
return employeeRepository.findOne(id);
}
/**
* 測試name的可用性
* @param lastName
* @return
*/
@Transactional(readOnly=true)
public Employee getLastName(String lastName){
return employeeRepository.getByLastName(lastName);
}
@Transactional
public void save(Employee employee){
System.out.println("ID的值爲:"+employee.getId());
// 設置創建時間 createTime 屬性
if(employee.getId() == null){
employee.setCreateTime(new Date());
}
employeeRepository.saveAndFlush(employee);
}
@Transactional(readOnly=true)
public Page<Employee> getPage(int pageNo,int pageSize){
PageRequest pageable = new PageRequest(pageNo - 1, pageSize);
// 該接口無條件查詢需要傳入一個Pageable類型參數 PageRequest 爲該接口的實現類
return employeeRepository.findAll(pageable);
}
}
@Service
public class DepartmentService {
@Autowired
private DepartmentRepository departmentRepository;
@Transactional(readOnly=true)
public List<Department> getAll(){
return departmentRepository.getAll();
}
}
- handler層
@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);
System.out.println("等待跳轉:++++++++++++++");
return "index";
}
/**
* 解決在參數回顯時 時間爲空的問題
* @param id
* @param map
*/
@ModelAttribute
public void getEmployee(@RequestParam(value="id",required=false) Integer id,
Map<String, Object> map){
if(id != null){
Employee employee = employeeService.get(id);
/*
* 在修改時: 若修改了部門的信息 則會產生錯誤
*
* 在執行update之前 系統會將得到的參數賦值給 map中的employee 此時該對象的生命週期還未結束 所以操作的爲同一個對象
*
* 解決方法:在賦值之前將map中的employee制空 則在此時賦值不會發生錯誤
*
*/
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) {
System.out.println("我被調用了-----------------------------");
Employee employee = employeeService.get(id);
// 此處的employee 要與跳轉的界面中 modelAttribute 的值相同 此處採用springMVC 自帶標籤
map.put("employee", employee);
System.out.println("employee的ID:"+employee.getId());
map.put("departments", departmentService.getAll());
return "/emp/input";
}
/**
* 添加
*
* @param employee
* @return
*/
@RequestMapping(value = "/emp", method = RequestMethod.POST)
public String save(Employee employee) {
employeeService.save(employee);
return "redirect:/emps";
}
/**
* 跳轉到添加頁面
*
* @param map
* @return
*/
@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";
}
/**
* 第一次請求時該值爲空 設置爲String 類型:避免傳入的參數爲String而導致程序死掉
*
* @param pageNoStr
* @return
*/
@RequestMapping(value = "emps", method = RequestMethod.GET)
public String list(@RequestParam(value = "pageNo", required = false, defaultValue = "1") String pageNoStr,
Map<String, Object> map) {
int pageNo = 1;
try {
// 如果出錯就用1
if (pageNo < 1) {
pageNo = 1;
}
pageNo = Integer.parseInt(pageNoStr);
} catch (Exception e) {
}
Page<Employee> page = employeeService.getPage(pageNo, 5);
map.put("page", page);
return "emp/list";
}
}
TEST 測試
public class SSSPTest {
private ApplicationContext ctx= null;
private DepartmentRepository dapartmentRepository;
private EntityManagerFactory entityManagerFactory;
{
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
dapartmentRepository = ctx.getBean(DepartmentRepository.class);
entityManagerFactory = ctx.getBean(EntityManagerFactory.class);
}
/**
* jpa 中使用二級緩存的方法
*/
@Test
public void testJpaCashe(){
String jpql="FROM Department d";
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createQuery(jpql);
List<Department> department = query.setHint(QueryHints.HINT_CACHEABLE, true).getResultList();
entityManager.close();
entityManager = entityManagerFactory.createEntityManager();
query = entityManager.createQuery(jpql);
department = query.setHint(QueryHints.HINT_CACHEABLE, true).getResultList();
entityManager.close();
}
@Test
public void testDemo(){
List<Department> departments = dapartmentRepository.getAll();
departments = dapartmentRepository.getAll();
}
@Test
public void testDataSourse() throws SQLException{
DataSource data = ctx.getBean(DataSource.class);
System.out.println(data.getConnection());
}
}
- 視圖展示
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ 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" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首頁</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(); //label 等於我後面的hidden的值
var flag = confirm("確定刪除"+label+"的信息嗎?");
if(flag){
var url = $(this).attr("href"); //獲取當前點擊路徑
$("#_form").attr("action",url);
$("#_method").val("DELETE");
$("#_form").submit();
}
/*
沒寫這句導致 在執行完刪除後 頁面跳轉到回顯界面
*/
return false;
});
})
</script>
</head>
<base href="<%=basePath%>" />
<body>
<!--刪除時所用的表單 -->
<form action="" method="post" id="_form">
<input id="_method" name="_method" type="hidden">
</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>部門</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>
<!--
JPA 默認在獲取關聯屬性時 會一併查出來, 此時將發送N條查詢語句 (不可取)
此時需要添加懶加載方法是來獲取,但如果在關聯關係上 添加懶加載 則會報懶加載異常。
原因:事務的邊緣在service方法結束的時候 當servcie方法執行完畢 事務接受 則session關閉,則他關
聯的對象就是一個代理對象,而頁面上需要使用該代理對象的屬性 則發生異常
解決方法:
在web.xml下配置 OpenEntityManagerInViewFilter 可以解決懶加載異常
-->
<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="emps?pageNo=${page.number+1-1 }">上一頁</a> <a href="emps?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>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//獲取絕對路徑路徑
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!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>首頁</title>
</head>
<base href="<%=basePath %>"/>
<body>
<a href="emps">List ALL</a>
<a href="emp">Add New Employee</a>
</body>
</html>