淺出Spring Boot系列(二)程式碼組織及CRUD
前言
Spring Boot
專案中的程式碼該如何進行有效組織?本文以Bookstore
專案為例,進行一個簡易的CRUD系統開發。
目錄
- Hellowrold及基本概念
- 程式碼組織及CRUD
建模
由於是一個簡易的書店系統,建模如下:
系統中主要存在4個物件,即使用者、訂單、商品、種類。一個使用者對應0個或多個訂單,每個訂單至少包含一件商品。且每個商品都屬於某個種類。
Model
新建model
package,並在其中建立上圖中的4個類,另外額外多一個OrderProduct
類,該類繼承自Product
,增加一個quantity
屬性。
以User
為例:
package com.william.model;
import lombok.Data;
import org.springframework.data.annotation.Id;
import java.util.List;
/**
* Created by william on 17/3/23.
*/
@Data
public class User {
@Id
private String id;
private String username;
private String password;
private String salt;
private String photo;
private List<String> roles;
}
一般POJO中每個屬性會建立額外的Getter
Setter
方法,這裡通過lombok
包,引入@Data
註解,省略了手動寫這些方法,專案編譯時lombok
自動地為我們生成對應方法。
使用時只需在build.gradle
檔案中新增對lombok
的依賴即可:
compile("org.projectlombok:lombok")
Repository
新建repository
package,由於資料我們這裡選用的是mongodb
,所以首先引入mongo
的依賴
compile("org.springframework.boot:spring-boot-starter-data-mongodb")
這裡需要注意的是,我們選擇建立上述POJO對應的repository 的Interface
,而不是Class
。這裡以ProductRepositoy
為例:
package com.william.repository;
import com.william.model.Product;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* Created by william on 17/3/24.
*/
public interface ProductRepository extends MongoRepository<Product,String> {
List<Product> findByCategoryId(@Param("categoryId") String categoryId);
}
這裡我們選擇繼承MongoRepository
,且模版列表中第一個引數為POJO的型別,第二個引數為主鍵的型別
為什麼我們在這裡只寫介面而不做實現呢?歸功於Spring
強大的依賴注入能力,當專案執行時,Spring
會自動為我們注入該介面的實現。如果有使用過Mybatis
,它的Mapper
實際上也是類似的。
注意到上述還包含一個findByCategoryId
的方法,這個也是不需要實現的。
The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.
由於遵循約定大於配置
,Spring
會自動根據方法名轉換成對應SQL語句。
更多的query method
可以檢視官方文件
Service
新建service
、service.impl
package,前者放Interface
檔案,後者為對應的實現。由於專案不包含過多的業務邏輯,所以這一層會顯得略有些淡薄,基本只需要呼叫repostory
中對應方法即可。
以CategoryService
的實現為例:
package com.william.service.impl;
import com.william.model.Category;
import com.william.repository.CategoryRepository;
import com.william.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by william on 17/3/25.
*/
@Service
public class MongoCategoryServiceImpl implements CategoryService {
@Autowired
private CategoryRepository repository;
@Override
public Category create(Category category) {
return repository.insert(category);
}
@Override
public Category show(String id) {
return repository.findOne(id);
}
@Override
public Category update(Category category) {
return repository.save(category);
}
@Override
public List<Category> findAll() {
Sort sort = new Sort(Sort.Direction.ASC,"order");
return repository.findAll(sort);
}
@Override
public Category destroy(String id) {
Category category = repository.findOne(id);
repository.delete(id);
return category;
}
}
實現需要新增@Service
的Annotation
Controller
新建controller
package,我們依然以資源作為分類標準,建立對應controller。以CategoryController
為例:
package com.william.controller;
import com.william.model.Category;
import com.william.model.Product;
import com.william.service.CategoryService;
import com.william.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Created by william on 17/3/24.
*/
@RestController
@RequestMapping("/categories")
public class CategoryController {
@Autowired
private ProductService productService;
@Autowired
private CategoryService service;
@RequestMapping(method = RequestMethod.POST)
public Category create(@RequestBody Category category)
{
return service.create(category);
}
@RequestMapping(method = RequestMethod.GET)
public List<Category> getAllCategories()
{
return service.findAll();
}
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public Category show(@PathVariable String id)
{
return service.show(id);
}
@RequestMapping(value = "/{id}",method = RequestMethod.PUT)
public Category update(@PathVariable String id, @RequestBody Category category)
{
category.setId(id);
return service.create(category);
}
@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
public Category destroy(@PathVariable String id)
{
return service.destroy(id);
}
@RequestMapping("/{id}/products")
public List<Product> findAllProducts(@PathVariable String id)
{
return productService.findAll(service.show(id));
}
}
@RestController
用於標記這是一個基於Restful API
的controller,response將通過response body傳送。
@RequestMapping
用於對映對應URL,並且可顯性指定請求的方法。
關於Restful API
的設計可以參考阮一峰老師的部落格
至此一個經典的分層架構的API後臺就開發完成了。完整目錄結構如圖:
效果
建立一個Category
資源,並新增幾個對應的Product
。
以GET
方式訪問/categories/{category_id}
,即可看到該類別下的所有商品了。
相關文章
- 組織css程式碼CSS
- Spring Boot系列(四):Spring Boot原始碼解析Spring Boot原始碼
- Spring Boot+MiniUI CRUD操作Spring BootUI
- 程式碼模型組織方式模型
- Spring Boot系列(三):Spring Boot整合Mybatis原始碼解析Spring BootMyBatis原始碼
- Spring Boot Crud操作示例 | Java Code GeeksSpring BootJava
- 深入淺出,Spring 框架和 Spring Boot 的故事框架Spring Boot
- Go包-程式碼組織者Go
- 如何組織大型 Rust 程式碼庫Rust
- 深入淺出Spring Boot 起步依賴和自動配置Spring Boot
- Spring Boot系列(一):Spring Boot快速開始Spring Boot
- Spring Boot系列(一):Spring Boot 入門篇Spring Boot
- 【原創】【深入淺出系列】之程式碼可讀性
- Spring框架系列(4) - 深入淺出Spring核心之面向切面程式設計(AOP)Spring框架程式設計
- spring 整合 mybatis 及mybatis 的 crud 操作SpringMyBatis
- Spring Boot 核心(二)Spring Boot
- oracle iot索引組織表(二)Oracle索引
- Spring Boot使用Allatori程式碼混淆Spring Boot
- objective-C 的程式碼檔案組織Object
- 我們正在錯誤的組織程式碼!
- 用BEM命名規範組織CSS程式碼CSS
- Spring Boot系列十九 Spring boot整合 swaggerSpring BootSwagger
- Spring Boot2 系列教程(三)理解 Spring BootSpring Boot
- spring boot(二)整合mybatis plus+ 分頁外掛 + 程式碼生成Spring BootMyBatis
- Spring Boot 系列部落格Spring Boot
- MongoDB 入門教程系列之二:使用 Spring Boot 操作 MongoDBMongoDBSpring Boot
- Spring Boot整合Mybatis完成級聯一對多CRUD操作Spring BootMyBatis
- 二叉排序樹BST及CRUD操作排序
- Spring boot學習(二) Spring boot基礎配置Spring Boot
- 如何組織軟體模組的程式碼結構?
- 公司程式碼與採購組織的關係
- 如何組織大型JavaScript應用中的程式碼?JavaScript
- 如何組織構建多檔案 C 語言程式(二)
- 組織程式和資料
- Spring Boot構造流程淺析Spring Boot
- Nuxt.js 深入淺出:目錄結構與檔案組織詳解UXJS
- 尋找寫程式碼感覺(二)之 Spring Boot 專案屬性配置Spring Boot
- Spring框架系列(3) - 深入淺出Spring核心之控制反轉(IOC)Spring框架