天天看點

SpringBoot學習筆記(四、JPA)

前置: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提供的一些預先生成方法:

SpringBoot學習筆記(四、JPA)

還可以自定義一些查詢,後面再看。

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、運作

由于采用的是熱部署,直接通路

SpringBoot學習筆記(四、JPA)
SpringBoot學習筆記(四、JPA)

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