搜尋
首頁Javajava教程詳解在TodoController中引用TodoRepository

詳解在TodoController中引用TodoRepository

May 09, 2017 pm 01:18 PM
bootservicespring

這篇文章主要介紹了Spring Boot(三)之找回熟悉的Controller,Service,需要的朋友可以參考下

找回熟悉的Controller,Service Controller哪裡去了?

對於許多習慣了Spring開發的同學來講,Controller,Service,DAO 這些套路突然間都沒了會有不適感。其實呢,這些東西還在,只不過對於較簡單的情境下,這些都變成了系統背後幫你做的事情。這一小節我們就先來看看如何將Controller再召喚回來。召喚回來的好處有哪些呢?首先我們可以自訂API URL的路徑,其次可以對參數和傳回的json結構做一定的處理。

如果要讓 TodoController 可以和 TodoRepository 配合工作的話,我們當然需要在 TodoController 中需要引用 TodoRepository。

public class TodoController {
 @Autowired
 private TodoRepository repository;
 //省略其它部分
}

@Autowired 這個修飾符是用來做依賴性注入的,上面的用法叫做 field injection,直接做類別成員的注入。但Spring現在鼓勵用建構函數來做注入,所以,我們來看看建構子的注入方法:

public class TodoController {
 private TodoRepository repository;
 @Autowired
 public TodoController(TodoRepository repository){
  this.repository = repository;
 }
 //省略其它部分
}

當然我們為了可以讓Spring知道這是一個支援REST API的Controller ,還是需要標記其為@RestController。由於預設的路徑映射會在資源根用複數形式,由於todo是輔音後的o結尾,按英語習慣,會映射成 todoes。但這裡用 todos 比 todoes 舒服一些,所以我們再用另一個 @RequestMapping("/todos") 來自定義路徑。這個 Controller 中的其它方法比較簡單,就是利用repository中的方法去增刪改查即可。

package dev.local.todo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/todos")
public class TodoController {
 private TodoRepository repository;
 @Autowired
 public TodoController(TodoRepository repository){
  this.repository = repository;
 }
 @RequestMapping(method = RequestMethod.GET)
 public List<Todo> getAllTodos(@RequestHeader(value = "userId") String userId) {
  return repository.findByUserId(new ObjectId(userId));
 }
 @RequestMapping(method = RequestMethod.POST)
 Todo addTodo(@RequestBody Todo addedTodo) {
  return repository.insert(addedTodo);
 }
 @RequestMapping(value = "/{id}", method = RequestMethod.GET)
 public Todo getTodo(@PathVariable String id) {
  return repository.findOne(id);
 }
 @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
 Todo updateTodo(@PathVariable String id, @RequestBody Todo updatedTodo) {
  updatedTodo.setId(id);
  return repository.save(updatedTodo);
 }
 @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
 Todo removeTodo(@PathVariable String id) {
  Todo deletedTodo = repository.findOne(id);
  repository.delete(id);
  return deletedTodo;
 }
}

上面的程式碼中需要再說明幾個要點:

為什麼在類別上標記@RequestMapping("/todos") 之後在每個方法上還需要加入@RequestMapping?類別上面定義的 @RequestMapping 的參數會預設套用到所有方法,但如果我們發現某個方法需要有自己的特殊值時,就需要定義這個方法的映射參數。例如上面例子中 addTodo,路徑也是 todos,但要求 Request的方法是 POST,所以我們給了 @RequestMapping(method = RequestMethod.POST)。但getTodo 方法的路徑應該是todos/:id,這時我們要給出@RequestMapping(value = "/{id}", method = RequestMethod.GET)
這些方法接受的參數也使用了各種修飾符,@PathVariable 表示參數是從路徑中得來的,而@RequestBody 表示參數應該從Http Request的body 中解析,類似的@RequestHeader 表示參數是Http Request的Header中定義的。
在可以測試之前,我們還需要使用 @Repository 來標記 TodoRepository,以便於Spring可以在依賴注入時可以找到這個類別。

package dev.local.todo;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
 * Created by wangpeng on 2017/1/26.
 */
@Repository
public interface TodoRepository extends MongoRepository<Todo, String>{
 List<Todo> findByUserId(ObjectId userId);
}

接下來就可以用PostMan

來做測試:

#測試

Controller Service呢?在哪裡?

熟悉Spring的童鞋一定會問,我們剛才的做法等於直接是Controller訪問Data了,隔離不夠啊。其實我覺得有很多時候,這種簡單設計是挺好的,因為業務還沒到那步,過於複雜的設計其實沒啥太大意義。但這裡我們還是一步步實踐一下,找回大家熟悉的感覺。

回到原來的熟悉模式再簡單不過的,新建一個TodoService 介面,定義一下目前的增刪改查幾個操作:

public interface TodoService {
 Todo addTodo(Todo todo);
 Todo deleteTodo(String id);
 List<Todo> findAll(String userId);
 Todo findById(String id);
 Todo update(Todo todo);
}

為預防我們以後使用MySQL 等潛在的“可擴展性”,我們將這個介面的實作命名為MongoTodoServiceImpl,然後把Controller 中的大部分程式碼拿過來改改就行了。當然為了系統可以找到這個依賴並註入需要的類別中,我們標記它為 @Service

@Service
public class MongoTodoServiceImpl implements TodoService{
 private final TodoRepository repository;
 @Autowired
 MongoTodoServiceImpl(TodoRepository repository) {
  this.repository = repository;
 }
 @Override
 public Todo addTodo(Todo todo) {
  return repository.insert(todo);
 }
 @Override
 public Todo deleteTodo(String id) {
  Todo deletedTodo = repository.findOne(id);
  repository.delete(id);
  return deletedTodo;
 }
 @Override
 public List<Todo> findAll(String userId) {
  return repository.findByUserId(new ObjectId(userId));
 }
 @Override
 public Todo findById(String id) {
  return repository.findOne(id);
 }
 @Override
 public Todo update(Todo todo) {
  repository.save(todo);
  return todo;
 }
}

最後把Controller中的所有方法改為使用Service的簡單呼叫就大功告成了。

public class TodoController {
 private TodoService service;
 @Autowired
 public TodoController(TodoService service){
  this.service = service;
 }
 @RequestMapping(method = RequestMethod.GET)
 public List<Todo> getAllTodos(@RequestHeader(value = "userId") String userId) {
  return service.findAll(userId);
 }
 @RequestMapping(method = RequestMethod.POST)
 Todo addTodo(@RequestBody Todo addedTodo) {
  return service.addTodo(addedTodo);
 }
 @RequestMapping(value = "/{id}", method = RequestMethod.GET)
 public Todo getTodo(@PathVariable String id) {
  return service.findById(id);
 }
 @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
 Todo updateTodo(@PathVariable String id, @RequestBody Todo updatedTodo) {
  updatedTodo.setId(id);
  return service.update(updatedTodo);
 }
 @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
 Todo removeTodo(@PathVariable String id) {
  return service.deleteTodo(id);
 }
}

說實話如果每個簡單類別都這麼寫,我深深地趕腳背離了Spring Boot的意圖,雖然你能舉出1000個理由這麼做有好處。類似的,DAO或DTO要寫起來也很簡單,但我還是建議在業務沒有複雜之前還是享受Spring Boot帶給我們的便利吧。

【相關推薦】

1. Java免費影片教學

#2. 極客學院Java影片教學

#3. JAVA教學手冊

以上是詳解在TodoController中引用TodoRepository的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具