两三年前,当我开始熟悉.Net Core和基于ASP.NET Core的OData API时,曾经通过实现一个项目的方式来锻炼自己,而且写过一系列文档来详细讲述自己的实现步骤:
- 第一篇 Part I: 业务场景和存储层设计
- 第二篇 Part II: 开发环境及项目设置
- 第三篇 Part III: Model类
- 第四篇 Part IV: Data Context
- 第五篇 Part V: Controller
- 第六篇 Part VI: 为Controller添加CRUD
- 第七篇 Part VII: 用Postman测试
- 第八篇 Part VIII: Unit Test准备
- 第九篇 Part IX: Angular程序环境准备
- 第十篇 Part X: 完善Angular程序
- 第十一篇 Part XI: 为API添加CORS支持
- 第十二篇 Part XII, Angular程序的List和Detail页面
这次,开始学习Spring Boot,打算效仿一下当年的自己,也准备通过实现一个项目加一系列文档的方式来记录下进程。
业务场景 Business Scenario
书中只有颜如玉,书中只有黄金屋。
读书,是一个爱好,变成了我们人生的一份,也变成了一种生活态度。看电影,也是一样。
一个系统来保存当前的藏书,也是必须的。如果能保存读书笔记或观影记录,那是更好的了。当然,虽然冠以Library的标题,并非做一个图书馆系统,只是一个简单的家用的藏书记录。
所以,从业务场景来看,或者直接了当地从我们买书、藏书的过程来看,以下功能点是必须的:
- 图书。分门别类、结构化的图书记录;
- 影视作品。结构化的影视作品记录;
- 人物。这里的人物是指:图书的作者、译者;影视作品中的各类司职。
Library Builder,就是符合上述业务场景的。它是一个用来创建、维护、浏览、测试和巩固各种图书和影视作品的Web App。而Library Builder API是服务于其需求的API。
它包含这么几种类型的对象:
- Book。图书。
- Person。人物。
- Organization。组织。
存储层设计 Database table design
图书 Book
CREATE TABLE [Book] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[native_name] NVARCHAR(200) NOT NULL,
[chinese_name] NVARCHAR(200) NULL,
[Detail] NVARCHAR(200) NULL,
[CreatedAt] DATETIME DEFAULT (getdate()) NULL,
[ModifiedAt] DATETIME DEFAULT (getdate()) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC)
);
人物 Person
CREATE TABLE [Person] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[native_name] NVARCHAR(200) NOT NULL,
[chinese_name] NVARCHAR(200) NULL,
[Detail] NVARCHAR(200) NULL,
[CreatedAt] DATETIME DEFAULT (getdate()) NULL,
[ModifiedAt] DATETIME DEFAULT (getdate()) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC)
);
开发环境 Development Environment
开发环境基于Spring Boot:
POM文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.alvachien</groupId>
<artifactId>library</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Library</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<olingo.version>4.9.0</olingo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>10.2.1.jre11</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-commons-api</artifactId>
<version>${olingo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-commons-core</artifactId>
<version>${olingo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-server-api</artifactId>
<version>${olingo.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-server-core</artifactId>
<version>${olingo.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
源代码 Source Repo
源代码的Repository:https://github.com/alvachien/libraryapi