rust 使用 actix-web、diesel、mysql 的 demo。
-
创建工程
cargo new rust_diesel_mysql_demo -
添加 diesel 依赖
diesel = { version = "2.0.0", features = ["mysql"] } dotenvy = "0.15" -
mysql 连接信息写入到 env 文件
echo DATABASE_URL=mysql://root:123456@localhost:3306/diesel_demo >.env -
cargo install diesel_cli --no-default-features --features mysql -
diesel setup- 生成 migrations 存放初始化 sql 文件的目录。
- 生成 diesel.toml,存放生成文件的目录
[print_schema] file = "src/schema.rs" [migrations_directory] dir = "migrations"
-
diesel migration generate create_posts
生成初始化 sql 文件。Creating migrations/2022-11-22-085601_create_posts/up.sql Creating migrations/2022-11-22-085601_create_posts/down.sql将初始化 sql 写到 up.sql 中。
CREATE TABLE `posts` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID', `title` varchar(256) NOT NULL COMMENT '标题', `body` text NOT NULL COMMENT '内容', `published` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否发布', PRIMARY KEY (`id`) ) ; -
diesel migration run
- 读取上一步生成的 migrations 文件夹的 up.sql,生成对应的实体,生成到 print_schema 指定的文件
- 如果上一步没有执行,migrations 里是空的,默认会生成数据库里所有表的实体
以上就是使用 diesel 的准备工作,接下来就是编码工作
-
在 src 目录下创建文件夹 api、database、models、service
├── src │ ├── api │ │ ├── mod.rs │ │ └── test_api.rs │ ├── database │ │ ├── mod.rs │ │ ├── mysql.rs │ │ └── schema.rs │ ├── main.rs │ ├── models │ │ ├── mod.rs │ │ └── models.rs │ ├── service │ │ ├── mod.rs │ │ └── test_service.rs │ └── settings.rs- rust 的目录结构还在摸索中,这里还是 mvc 的方式
- api 提供服务的接口,类似于 controller
- database 数据库相关,初始化数据库连接以及存放生成的 schema
- models 代码运行过程中的 struct
- service 服务逻辑处理
每个文件夹里都有个 mod.rs,里边有声明 mod 的语句,而声明的 mod 在同级别的目录下有对应名字的文件存在。
例如 database 文件夹里的 mod.rs:
pub mod mysql;
pub mod schema;
database 文件夹里还有 mysql.rs、schema.rs 两个文件。
这个好像是 rust 的一个规则。当一个目录下有一个名为 mod.rs 的源文件时,模块的文件名也可以和这个目录互相映射。
不过这个 mod.rs 文件有点太多了。。。
diesel crud
https://docs.diesel.rs/diesel/query_dsl/trait.QueryDsl.html
insert
diesel::insert_into(posts::table)
.values(&new_post)
.execute(connection)
.expect("Error saving new post");
select
一个 selectById 都能有好几中写法
posts::table.filter(posts::id.eq(id)).first(connection).unwrap()
posts::dsl::posts.find(id).first(connection).unwrap()
posts::table.find(id).first(connection).unwrap()
delete
diesel::delete(posts::table).filter(posts::id.eq(id))
.execute(connection).unwrap();
update
diesel::update(posts::table).filter(posts::id.eq(id))
.set(posts::published.eq(true))
.execute(connection).unwrap();
github 地址:
https://github.com/hitolz/rust_actix_diesel_mysql_demo
https://diesel.rs/guides/getting-started
https://www.rectcircle.cn/posts/rust-diesel/
