iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Software Development

我的SpringBoot絕學:7+2個專案,從新手變專家系列 第 7

Day7 第三個Spring Boot專案:書籍管理專案,從MariaDB安裝到RESTful API的完整實作指南

  • 分享至 

  • xImage
  •  

前言

我們上一個專案使用的H2資料庫有個很大的缺點:關閉專案後資料庫的內容會全都消失。

這次我們會使用需要安裝的資料庫,這樣我們的資料就能一直保存下去,關機也不會讓資料消失,如果我們沒有刪除就能一直保存一輩子的資料,是一輩子喔,一輩子。

一談到資料庫,許多人會想到MySQL,因為它和Java是同一家公司(Oracle)的產品,但是在這次的專案不會使用MySQL。

我們來談談Oracle做了什麼事,從前Oracle JDK免費讓所有人和企業使用,突然,Oracle宣佈Oracle JDK要收費了,企業不付錢就律師函警告,Oracle好心提供可以免費商用的Oracle OpenJDK,其他使用Java的企業也開發自己的OpenJDK,現在我們要使用OpenJDK才能免費商用,不小心用到Oracle JDK就只能乖乖付錢。

有了這個前車之鑒,誰能保證MySQL不會突然宣佈要對商業使用付費呢?

MariaDB安裝和建立資料庫

為了避開風險,我們選擇用MariaDB,是一個開源專案也可以免費商用,而且有一部分的開發者也曾開發過MySQL。

MariaDB大部分的設計相容MySQL,對於個人開發者來說MariaDB和MySQL幾乎是一樣的。

來到官網下載並安裝,過程相當的簡單,維持預設就好,記住New root password填入的密碼,我們之後會用到。

安裝完成後開啟HeidiSQL,填入之前設定的密碼,點擊開啟。

進入管理頁面,在中間偏上的地方找到查詢,在底下輸入

CREATE DATABASE book;

按下F9,建立book資料庫。

點擊左邊的Unnamed後按下F5,就能看到book資料庫,關閉HeidiSQL。

Entity格式與專案功能

book entity的格式

欄位名稱 資料形態 說明
id Long 唯一的id,方便資料庫搜尋
name String 書名
page Integer 頁數

專案的功能

路徑 HTTP request method 說明 Request body
/ POST 新增書籍 Book
/all GET 取得全部的書籍
/{id} GET 取得指定id的書籍
/{id} PUT 修改書籍內容 Book
/{id} DELETE 刪除書籍

建立專案與連接資料庫

前往 Spring Initializr 建立專案,可以參考這張圖。

下載並開啟專案。

在上一個專案我們使用的方法需要打重複的部分,舉例來說:spring.datasource的部分,我們重複打了四次,這邊有另外一種寫法可以省略重複的開頭。

用YAML格式設定專案

首先把application.properties改名成application.yaml,以下是它的內容

spring:
  application:
    name: Book-Management-Project
  datasource:

    #我們從H2改成MariaDB,存放資料的地方也不再是記憶體了。
    url: jdbc:mariadb://localhost:3306/book

    #選擇MariaDB的驅動程式
    driver-class-name: org.mariadb.jdbc.Driver

    #MariaDB預設的使用者名稱是root
    username: root

    #MariaDB的密碼,之前進入管理頁面時用的,不是要你填密碼兩個字。
    password: 密碼

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

yaml對中文註解友善,不像properties寫中文註解,儲存後都變成?

不過YAML對排版很嚴格,空格很重要,和python一樣少一個indent都會導致錯誤。

不論是properties還是YAML都能讓專案運作,選擇哪種就看個人的喜好了。

接下來是寫Entity、Repository、Service、Controller的部分,和上一個專案類似。

Entity

//Book.java
@Entity
public class Book {
    @Id//表示這個是id也是主鍵
    @GeneratedValue(strategy = GenerationType.IDENTITY)//會在資料庫添加AUTO_INCREMENT
    private Long id;
    private String name;
    private int page;

    public Book(){

    }

    public Book(Long id, String name, int page) {
        this.id = id;
        this.name = name;
        this.page = page;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }
}

Repository

Book是我們的entity,Long是id的資料型態。

//BookRepository.java

public interface BookRepository extends JpaRepository<Book, Long> {
}

Service

這邊和上一個專案有點不同,當我們嘗試去尋找、修改、刪除不存在的id時不會出現錯誤,會回傳空的內容(null)。

//BookService.java

@Service
public class BookService {
    private final BookRepository bookRepository;

    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

將從controller取得的book,儲存到資料庫中,把資料庫儲存後的結果回傳給controller

public Book addBook(Book book) {
        return bookRepository.save(book);
    }

取得資料庫中所有的book,回傳給controller

 public List<Book> getAllBooks() {
        return bookRepository.findAll();
    }

根據提供的id編號在資料庫中尋找book

public Book getBookById(Long id) {
        Optional<Book> opt = bookRepository.findById(id);
        return opt.orElse(null);
    }

根據提供的id編號修改對應的book

public Book updateBook(Book book) {
        Optional<Book> opt = bookRepository.findById(book.getId());
        if (opt.isPresent()) {
            Book updatedBook = opt.get();
            updatedBook.setName(book.getName() == null ? updatedBook.getName() : book.getName());
            updatedBook.setPage(book.getPage());
            return bookRepository.save(updatedBook);
        }
        return null;
    }

根據提供的id編號在資料庫中刪除book

    public void deleteBookById(Long id) {
        Optional<Book> opt = bookRepository.findById(id);
        opt.ifPresent(book -> bookRepository.deleteById(book.getId()));
    }
}

Controller

設定BookController中的所有網址的開頭都是/api/book

//BookController.java

@RestController
@RequestMapping("/api/book")
public class BookController {
    private final BookService bookService;
    public BookController(BookService bookService) {
        this.bookService = bookService;
    }

新增book,並將新增的book資訊回傳

@PostMapping("/")
    public ResponseEntity<Book> addBook(@RequestBody Book book) {
        return new ResponseEntity<>(bookService.addBook(book), HttpStatus.CREATED);
    }

將資料庫中所有的book回傳

@GetMapping("/all")
    public ResponseEntity<List<Book>> getAllBooks() {
        return ResponseEntity.ok(bookService.getAllBooks());
    }

將指定的book內容回傳

@GetMapping("/{id}")
    public ResponseEntity<Book> getBookById(@PathVariable("id") Long id) {
        return ResponseEntity.ok(bookService.getBookById(id));
    }

修改指定的book內容

@PutMapping("/{id}")
    public ResponseEntity<Book> updateBook(@PathVariable("id") Long id, @RequestBody Book book) {
        book.setId(id);
        return ResponseEntity.ok(bookService.updateBook(book));
    }

將指定的book刪除


    @DeleteMapping("/{id}")
    public ResponseEntity<String> deleteBook(@PathVariable("id") Long id) {
        bookService.deleteBookById(id);
        return ResponseEntity.ok("Book deleted successfully");
    }
}

程式碼

這裡面少了application.yaml,需要自己建立,可以參考YAML那段的設定。

https://mega.nz/file/1MV33A6Z#BA1TRcFJRYLBCmiAgmjW0UT1NOxzylZ9ggNkQIMLxgs

使用工具測試專案

這邊提供測試用的範例,可以自行下載,內容我已經設定好了,只需要按下Send,確認結果就好。

我們按照順序測試專案,和上一個專案相同,使用的是Hoppscotch。

  • Create book

建立書籍

  • Get all books

取得全部書籍

  • Get book by id

取得指定id的書

  • Update book

修改指定id書籍資料

  • Delete book by id

刪除指定id的書


上一篇
Day6 第二個Spring Boot專案:待辦事項清單(4)測試
下一篇
Day8 第四個Spring Boot專案:客戶管理系統(1)MongoDB與資料庫設定
系列文
我的SpringBoot絕學:7+2個專案,從新手變專家31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言