【Vapor】03 Chapter 5: Fluent Persisting Models
0x00 Chapter 5: Fluent & Persisting Models
1.Fluent
is Vapor’s ORM
or object relational mapping
tool.
It’s an abstraction layer between the Vapor application
and the database
2.Models
are the Swift representation of your data and are used throughout Fluent
3.创建一个使用 Fluent
的新项目
新建一个文件夹,比如 vapor_learn
打开终端 cd
到此文件夹:
打开终端,输入 cd
,按个空格
,把文件夹 vapor_learn
拖入终端,最后按 Enter
创建一个名为:TILApp
的项目,(Today I Learn)
vapor new TILApp
是否使用 Fluent
?
输入:y
数据库使用 Postgres
不使用 Leaf
等待创建完成
以下是日志:
Cloning template...
name: TILApp
Would you like to use Fluent?
y/n> y
fluent: Yes
db: Postgres (Recommended)
Would you like to use Leaf?
y/n> n
leaf: No
Generating project files
+ Package.swift
+ main.swift
+ configure.swift
+ routes.swift
+ Todo.swift
+ CreateTodo.swift
+ .gitkeep
+ TodoController.swift
+ AppTests.swift
+ index.leaf
+ .gitkeep
+ Dockerfile
+ docker-compose.yml
+ .gitignore
+ .dockerignore
Creating git repository
Adding first commit** **~~** **~~~~~~** **~~~~~~~~~~** **~~~~~~~~~~~~~~** **~~~~~~~~~~~~~~~~~~** **~~~~~~~~~~~~~~~~~~~~~~** **~~~~~~~~~~~~~~~~~~~~~~~~** **~~~~~~~~~~~~~~~~~~~~~~~~~~** **~~~~~~~~~~~~~~~~~~~~~~~~~~~~****~~~~~~~~~~~~~~~~~~~~~~~~~~~~****~~~~~~~~~~~~~~~~~~~~~++++~~~****~~~~~~~~~~~~~~~~~~~++++~~~** ***~~~~~~~~~~~~~~~++++~~~*** ****~~~~~~~~~~++++~~**** *****~~~~~~~~~***** ************* _ __ ___ ___ ___ \ \ / / /\ | |_) / / \ | |_) \_\/ /_/--\ |_| \_\_/ |_| \ a web framework for Swift Project TILApp has been created!Use cd 'TILApp' to enter the project directoryUse vapor xcode to open the project in Xcode
看图片更清晰:
使用 cd TILApp
进入项目
使用 vapor xcode
可以在 Xocde
中打开项目
项目结构如下:
TILApp
--- Package.swift
--- Public
--- Resources--- Views--- index.leaf
--- Sources--- App--- Controllers--- TodoController.swift --- Migrations--- CreateTodo.swift--- Models--- Todo.swift--- configure.swift--- routes.swift --- Run--- main.swift
--- Tests--- AppTests--- AppTests.swift--- docker-compose.yml--- Dockerfile
看图片更清晰:
4.删除模板中自动生成的一些文件:
依次输入以下 3
个命令:
rm -rf Sources/App/Models/*
rm -rf Sources/App/Migrations/*
rm -rf Sources/App/Controllers/*
删除 configure.swift
中的代码:
app.migrations.add(CreateTodo())
删除 routes.swift
中的代码:
try app.register(collection: TodoController())
5.在 Models
文件夹内,新建模型文件:
Acronym.swift
,代表要提交的数据
// 1
final class Acronym: Model {// 2 static let schema = "acronyms"// 3 @IDvar id: UUID?// 4 @Field(key: "short")var short: String@Field(key: "long")var long: String// 5 init() {}// 6 init(id: UUID? = nil, short: String, long: String) {self.id = idself.short = shortself.long = long}
}
// 1. Define a class that conforms to Model
.
// 2. Specify the schema
as required by Model
. This is the name of the table
in the database
.
// 3. Define an optional
id property that stores the ID
of the model
, if one has been set. This is annotated with Fluent’s @ID property wrapper
. This tells Fluent what to use to look up the model in the database
// 4. Define two String
properties to hold the acronym
and its definition
. These use the @Field property wrapper
to denote a generic database field. The key parameter is the name of the column in the database
数据库表中的字段,列名称
@ID
marks a property as the ID
for that table
@Field
marks the property of a model
as a generic column in the database
// 5. Provide an empty
initializer as required by Model
. Fluent uses this to initialize models returned from database queries.
// 6. Provide an initializer to create the model as required
.
6.在 Migrations
文件夹内,新建文件:
CreateAcronym.swift
,用于创建对应的数据库表
// 1
struct CreateAcronym: Migration {// 2func prepare(on database: Database) -> EventLoopFuture<Void> {database.schema("acronyms") // 3.id() // 4.field("short", .string, .required) // 5.field("long", .string, .required) // 5.create() // 6}// 7func revert(on database: Database) -> EventLoopFuture<Void> {database.schema("acronyms").delete()}
}
// 1. Define a new type, CreateAcronym
that conforms to Migration
.
// 2. Implement prepare(on:)
as required by Migration
. You call this method when you run your migrations.
// 3. Define the table name
for this model. This must match
schema from the model
.
// 4. Define the ID
column in the database.
// 5. Define columns for short
and long
. Set the column type
to string
and mark the columns as required
. This matches the non-optional
String properties in the model. The field names
must match the key of the property wrapper
, not the name of the property itself.
// 6. Create
the table in the database.
// 7. Implement revert(on:)
as required by Migration
. You call this function when you revert your migrations. This deletes
the table referenced with schema(_:)
.
继承自 Migration
实现方法 prepare(on:)
为模型创建表,表名
必须和 模型
的 schema
一样
定义 id
, short
, long
这几个列,指定类型,required
对应 non-optional
.field
的列名,跟 @Field
的 key
对应
7.配置 configure.swift
在 app.databases.use(_:as:)
方法后添加代码:
app.migrations.add(CreateAcronym())
app.logger.logLevel = .debug
try app.autoMigrate().wait()
8.存储数据模型,需要数据库
测试 PostgreSQL
:在 Docker container
里运行 Postgres server
依次 下载
、安装
、打开
软件: docker
地址:https://www.docker.com/get-docker
使用终端创建数据库:
docker run --name postgres \-e POSTGRES_DB=vapor_database \-e POSTGRES_USER=vapor_username \-e POSTGRES_PASSWORD=vapor_password \-p 5432:5432 -d postgres
运行一个名为 postgres
的容器
指定 数据库名
,用户名
,密码
指定 端口
,默认是 5432
检查数据库是否运行:
docker ps
有以下日志,表示成功:
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES |
---|---|---|---|---|---|---|
53dc8048acaf | postgres | “docker-entrypoint.s…” | 8 months ago | Up 3 seconds | 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp | postgres |
9.最后,提交模型数据到数据库
9.1.让模型 Acronym
遵守 Content
协议
在 Acronym.swift
最后添加:
extension Acronym: Content {}
Since Acronym
already conforms to Codable
via Model
, you don’t have to add anything else.
9.2.定义 路由
:
接收数据,解析 JSON
,转成 Acronym
模型,存入
数据库
在 routes.swift
文件中,在 routes
方法内添加:
// 1app.post("api", "acronyms") { req -> EventLoopFuture<Acronym> in// 2 let acronym = try req.content.decode(Acronym.self)// 3 return acronym.save(on: req.db).map {// 4acronym}}
// 1. Register a new route at /api/acronyms
that accepts a POST
request and returns EventLoopFuture<Acronym>
. It returns the acronym
once it’s saved.
// 2. Decode the request’s JSON
into an Acronym
model using Codable
.
// 3. Save the model using Fluent
and the database
from Request.
// 4. save(on:)
returns EventLoopFuture<Void>
so use map
to return the acronym
when the save completes.
10.使用 Rested
提交数据
把代码 运行
起来后,就可以提交数据了
url: http://127.0.0.1:8080/api/acronyms
method: POST
parameters: {"long": "Tomorrow is a good day", "short": "TGD"}
参数提交格式,选择 JSON 形式: JSON-encoded
点击右下角的 Send Request
发起请求
成功后,会返回对应的模型数据,id
字段被赋值了
如下图所示:
11.运行代码
在终端进入到项目的根目录:TILApp
运行命令:vapor run
或者 swift run
会自动下载所有的依赖文件
依赖文件会有很多很多
这一步耗时会 很长很长很长......
你们可能在这 最后一步
就 放弃了
【Vapor】03 Chapter 5: Fluent Persisting Models相关推荐
- 【Vapor】07 Chapter 9: Parent-Child Relationships
0x00 Chapter 9: Parent-Child Relationships 1.Parent-child relationships describe a relationship wher ...
- 【Vapor】04 Chapter 6:Configuring a Database
0x00 Chapter 6:Configuring a Database 1.Vapor has official, Swift-native drivers for: SQLite MySQL P ...
- 【Vapor】06 Chapter 8: Controllers
0x00 Chapter 8: Controllers 上篇文章 把各种路由都写在了 routes.swift 文件内 如果路由事件太多,routes.swift 文件就会越来越大 慢慢地就会变得难以 ...
- 【Vapor】05 Chapter 7: CRUD Database Operations
0x00 Chapter 7: CRUD Database Operations 在 routes.swift 文件内写各种路由 操作数据库的记录 1.create 创建记录,之前的文章已经写过了 需 ...
- 【OWA】03安装部署:OWA(Office Web Apps)安装和部署
前言 在上一篇咱们把owa服务器加入到了域控中,可参考[OWA]02加入域控:将owa服务器加入域控(把计算机加入到域中), 接下来就在这台服务器上安装和配置OWA相关服务 [OWA]01环境准备:通 ...
- 【PyTorch】03数据处理
3 PyTorch数据处理 3.1 数据读取机制DataLoader与Dataset [PyTorch]2.1 DataLoader与Dataset epoch:对训练集的全部数据进行一次完整的训练, ...
- 【回归分析】03.回归参数的估计(1)
文章目录 [回归分析]3. 回归参数的估计(1) 3.1 最小二乘估计 3.2 最小二乘估计的性质 [回归分析]3. 回归参数的估计(1) 3.1 最小二乘估计 用 yyy 表示因变量,x1,x2,⋯ ...
- 【2021】03 C++
小结 开学第一个月. 上个月的计划完成得比较好,看完了<C++ Primer Plus>,考了二级,感觉可拿良好以上,下一步是拿新安江模型和一维水动力学模型练手. 但是,主要任务仍然是整理 ...
- 【转】03.Dicom 学习笔记-DICOM C-Get 消息服务
转自:https://www.jianshu.com/p/c7f5b9fa597c 引言 前篇介绍了 DICOM C-Find 消息服务,本文结合开源 DICOM 库 fo-dicom 详细介绍一 ...
最新文章
- 深入理解Oracle RAC 12c 笔记
- 【408预推免复习】计算机组成原理之系统总线
- matlab波特图带延迟的传递函数,matlab实现波特图
- U盘制作linux启动盘
- Criteria和DetachedCriteria区别应用
- forge不能用java打开_我玩我的世界把java更新了以后,就再也进不了加了forge的版本了,启动器,游戏,forge都重...
- python+FFmpeg实现对m3u8文件内的ts视频多线程下载、解密、合并成MP4,并输出。
- AutoCAD2019开发配置
- 【屏类型结构体定义PanelType】 文档位置:《apiPNL.h》
- 半胱氨酸蛋白酶Caspase-8 Inhibitor I, 886462-83-5
- 黄金分割搜索法求单峰极小值C++实现
- Lightroom“夏日清凉”调色思路
- Mac 修改开机登陆界面背景图, 替换沙漠背景图
- 数学建模比赛题型划分、常用算法及其适用场景
- 黑客入侵电脑?原来只需要简单几步就可以了
- HTML在网页上不能显示图片问题
- python数据挖掘领域工具包 - wentingtu - 博客园
- 未知参数休哈特matlab,一种确定某类工作的人的极限工作时间的方法
- oracle大于字符串时间,Oracle
- BZOJ1798 【AHOI2009】 seq维护序列 线段树