前置:Jsp視圖
Springboot的預設視圖支援是Thymeleaf,還沒學到,jsp用起來比較熟,先用它過渡一下。
1、在pom.xml中添加對Jsp的支援:
<!-- servlet依賴. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- tomcat的支援.,用于編譯jsp-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
application.properties配置:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
這個是jsp檔案的前置和字尾,在webapp下建立WEB-INF檔案夾,在WEB-INF下建立jsp檔案夾,jsp檔案就放在這,關于jsp的配置就完成了,也可以寫個Controller和jsp來測試一下是否配置成功。
一、整合JPA
我以前是沒見過這玩意的,先了解一下JPA:
JPA全稱Java Persistence API.JPA通過JDK 5.0注解或XML描述對象-關系表的映射關系,并将運作期的實體對象持久化到資料庫中。
JPA 的目标之一是制定一個可以由很多供應商實作的API,并且開發人員可以編碼來實作該API,而不是使用私有供應商特有的API。
JPA是需要Provider來實作其功能的,Hibernate就是JPA Provider中很強的一個,應該說無人能出其右。從功能上來說,JPA就是Hibernate功能的一個子集。
1、在pom.xml中添加相應的依賴添加依賴:
添加spring-boot-starter-jdbc依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa
</artifactId>
</dependency>
添加mysql連接配接類和連接配接池類:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
完整的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.hpu</groupId>
<artifactId>SpringBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot</name>
<!-- Spring Boot 啟動父依賴 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot web依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 添加servlet依賴 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--添加 jstl依賴 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- 用于編譯jsp -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- 熱部署依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 這個需要為 true 熱部署才有效 -->
</dependency>
<!-- 添加對mysql的支援 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- 添加對jpa的支援 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、資料源
JPA是幹什麼的,是搞資料庫持久化的,我們得有資料。這裡資料庫用的是mysql.
建立資料庫:
create database springbootjpa;
建立表:
use springbootjpa;
CREATE TABLE category_ (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(30),
PRIMARY KEY (id)
) DEFAULT CHARSET=UTF8;
添加資料:
這個看着随便添加吧。
3、資料源配置:
在application中配置相應資料源,
spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=xing0515
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
完整的application.properties:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=xing0515
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
4、建立實體類
建立一個包edu.hpu.springboot.pojo,在包下建立實體類Category,代碼如下:
package edu.hpu.springboot.pojo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
//對應category_的實體類
@Entity //表示這是個實體類
@Table(name="category_") //表示對應的表
public class Category {
@Id //表示主鍵
@GeneratedValue(strategy = GenerationType.IDENTITY) //表明自增長方式
@Column(name="id") //表示對應的字段
private int id;
@Column
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Category [id=" + id + ", name=" + name + "]";
}
}
關于相應注解:
注解 | 解釋 |
@Entity | 聲明類為實體或表。 |
@Table | 聲明表名。 |
@Basic | 指定非限制明确的各個字段。 |
@Embedded | 指定類或它的值是一個可嵌入的類的執行個體的實體的屬性。 |
@Id | 指定的類的屬性,用于識别(一個表中的主鍵)。 |
@GeneratedValue | 指定如何辨別屬性可以被初始化,例如自動、手動、或從序清單中獲得的值。 |
@Transient | 指定的屬性,它是不持久的,即:該值永遠不會存儲在資料庫中。 |
@Column | 指定持久屬性欄屬性。 |
@SequenceGenerator | 指定在@GeneratedValue注解中指定的屬性的值。它建立了一個序列。 |
@TableGenerator | 指定在@GeneratedValue批注指定屬性的值發生器。它創造了的值生成的表。 |
@AccessType | 這種類型的注釋用于設定通路類型。如果設定 |
@AccessType(FIELD ) | 則可以直接通路變量并且不需要getter和setter,但必須為public。如果設定@AccessType(PROPERTY),通過getter和setter方法通路Entity的變量。 |
@JoinColumn | 指定一個實體組織或實體的集合。這是用在多對一和一對多關聯。 |
@UniqueConstraint | 指定的字段和用于主要或輔助表的唯一限制。 |
@ColumnResult | 參考使用select子句的SQL查詢中的列名。 |
@ManyToMany | 定義了連接配接表之間的多對多一對多的關系。 |
@ManyToOne | 定義了連接配接表之間的多對一的關系。 |
@OneToMany | 定義了連接配接表之間存在一個一對多的關系。 |
@OneToOne | 定義了連接配接表之間有一個一對一的關系。 |
@NamedQueries | 指定命名查詢的清單。 |
@NamedQuery | 指定使用靜态名稱的查詢 |
5、CategoryDao
建立包edu.hpu.springoot.dao,在包下建立接口CategoryDao,繼承繼承了JpaRepository,并且提供泛型<Category,Integer> 表示這個是針對Category類的DAO,Integer表示主鍵是Integer類型。
package edu.hpu.springboot.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import edu.hpu.springboot.pojo.*;
/*繼承了JpaRepository,并且提供泛型<Category,Integer>
* 表示這個是針對Category類的DAO,Integer表示主鍵是Integer類型
* JpaRepository 這個父接口,就提供了CRUD, 分頁等等一系列的查詢了,直接拿來用
*/
public interface CategoryDao extends JpaRepository<Category, Integer>{
public List<Category> findByName(String name);
public List<Category> findByNameLikeAndIdGreaterThanOrderByNameAsc(String name, int id);
}
JpaRepository提供的一些預先生成方法:

還可以自定義一些查詢,後面再看。
6、CategoryController
這個省略了Service,一般是不能省略的,建立包edu…hpu.springboot.web,建立類CategoryController
package edu.hpu.springboot.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.how2java.springboot.dao.CategoryDAO;
import com.how2java.springboot.pojo.Category;
@Controller
public class CategoryController {
@Autowired CategoryDAO categoryDAO;
@RequestMapping("/listCategory")
public String listCategory(Model m) throws Exception {
List<Category> cs=categoryDAO.findAll();
m.addAttribute("cs", cs);
return "listCategory";
}
}
7、listCategory.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<table align='center' border='1' cellspacing='0'>
<tr>
<td>id</td>
<td>name</td>
</tr>
<c:forEach items="${cs}" var="c" varStatus="st">
<tr>
<td>${c.id}</td>
<td>${c.name}</td>
</tr>
</c:forEach>
</table>
8、啟動Application,通路網址
http://127.0.0.1:8080/listCategory官方文檔也看了一下,不是想象中的那麼費勁,有空可以仔細看看,提升一下自己的英文文檔閱讀能力。
Accessing Data with JPA二、CRUD+分頁
1、修改CategoryController,增加、删除、擷取、修改映射
package edu.hpu.springboot.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import edu.hpu.springboot.dao.CategoryDao;
import edu.hpu.springboot.pojo.Category;
@Controller
public class CategoryController {
@Autowired
CategoryDao categoryDao;
@RequestMapping("/addCategory")
public String addCategory(Category c) throws Exception{
categoryDao.save(c);
return "redirect:listCategory";
}
@RequestMapping("/deleteCategory")
public String deleteCategory(Category c) throws Exception{
categoryDao.delete(c);
return "redirect:listCategory";
}
@RequestMapping("/editCategory")
public String editCategory(int id,Model m) throws Exception{
Category c=categoryDao.findOne(id);
m.addAttribute("c", c);
return "editCategory";
}
@RequestMapping("/updateCategory")
public String updateCategory(Category c) throws Exception{
categoryDao.save(c);
return "redirect:listCategory";
}
@RequestMapping("/listCategory")
public String listCategory(Model m,@RequestParam(value = "start", defaultValue = "0")
int start,@RequestParam(value="size",defaultValue="5")int size) throws Exception{
start = start<0?0:start;
Sort sort=new Sort(Sort.Direction.DESC, "id");
Pageable pageable=new PageRequest(start, size, sort);
Page<Category> page=categoryDao.findAll(pageable);
System.out.println(page.getNumber());
System.out.println(page.getNumberOfElements());
System.out.println(page.getSize());
System.out.println(page.getTotalElements());
System.out.println(page.getTotalPages());
m.addAttribute("page", page);
return "listCategory";
}
}
查詢映射也做了相應的更改:
(1)、 在參數裡接受目前是第幾頁 start ,以及每頁顯示多少條資料 size。 預設值分别是0和5。
(Model m,@RequestParam(value = "start", defaultValue = "0") int start,@RequestParam(value = "size", defaultValue = "5") int size)
(2)、 如果 start 為負,那麼修改為0. 這個事情會發生在目前是首頁,并點選了上一頁的時候
start = start<0?0:start;
(3)、 設定倒排序
Sort sort = new Sort(Sort.Direction.DESC, "id");
(4)、 根據start,size和sort建立分頁對象
Pageable pageable = new PageRequest(start, size, sort);
(5)、 CategoryDAO根據這個分頁對象擷取結果page.
Page<Category> page =categoryDAO.findAll(pageable);
在這個page對象裡,不僅包含了分頁資訊,還包含了資料資訊,即有哪些分類資料。 這個可以通過getContent()擷取出來。
(6)、把page放在"page"屬性裡,跳轉到listCategory.jsp
m.addAttribute("page", page);
return "listCategory";
2、listCategory.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>
<body>
<div style="width: 500px; margin: 20px auto; text-align: center">
<table align='center' border='1' cellspacing='0'>
<tr>
<td>id</td>
<td>name</td>
<td>編輯</td>
<td>删除</td>
</tr>
<c:forEach items="${page.content}" var="c" varStatus="st">
<tr>
<td>${c.id}</td>
<td>${c.name}</td>
<td><a href="editCategory?id=${c.id}">編輯</a></td>
<td><a href="deleteCategory?id=${c.id}">删除</a></td>
</tr>
</c:forEach>
</table>
<br>
<div>
<a href="?start=0">[首 頁]</a> <a href="?start=${page.number-1}">[上一頁]</a>
<a href="?start=${page.number+1}">[下一頁]</a> <a
href="?start=${page.totalPages-1}">[末 頁]</a>
</div>
<br>
<form action="addCategory" method="post">
name: <input name="name"> <br>
<button type="submit">送出</button>
</form>
</body>
</html>
3、editCategory.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>修改</title>
</head>
<body>
<div style="margin: 0px auto; width: 500px">
<form action="updateCategory" method="post">
name: <input name="name" value="${c.name}"> <br> <input
name="id" type="hidden" value="${c.id}">
<button type="submit">送出</button>
</form>
</div>
</body>
</html>
4、運作
由于采用的是熱部署,直接通路
5、最後再加一點JPA的拓展:自定義簡單查詢
自定義的簡單查詢就是根據方法名來自動生成 SQL,主要的文法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy後面跟屬性名稱:
Category findByCategoryName(String name);
也使用一些加一些關鍵字And 、 Or
Category findByCategoryNameOrId(String name,int id);
JPA同樣可以實作複雜查詢——分頁查詢、限制查詢,
自定義SQL查詢
多表查詢
直接參考,用時再查:
Spring Boot(五):Spring Boot Jpa 的使用 Spring Data JPA - Reference Documentation