其他分享
首页 > 其他分享> > rust库学习-diesel

rust库学习-diesel

作者:互联网

介绍

diesel 是一个 orm 框架

支持 postgresql,mysql,sqlite

不用的数据库接口可能会不一样

官方例子地址

实践

cargo new --lib diesel_demo
cd diesel_demo
[dependencies]
diesel = { version = "1.4.4", features = ["postgres"] }
默认安装所有数据库的支持,如果数据库没安装和配置环境变量会安装失败
cargo install diesel_cli

根据官方以 postgresql 为例子
cargo install diesel_cli --no-default-features --features postgres

使用postgresql体验

  1. 创建数据库
    diesel setup --database-url=postgres://username:password@localhost/diesel_demo

  2. 生成创建和删除表文件

    diesel migration generate create_posts
    
    2022-07-23-033829_create_posts/up.sql
    2022-07-23-033829_create_posts/down.sql
    
    • up.sql
    CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    title VARCHAR NOT NULL,
    body TEXT NOT NULL,
    published BOOLEAN NOT NULL DEFAULT 'f'
    )
    
    • down.sql
    DROP TABLE posts
    
  3. 生成表
    diesel migration run --database-url=postgres://username:password@localhost/diesel_demo

    测试 down.sql 语法是否正确
    diesel migration redo

打开pgAdmin可以看到库和表都建好了

rust-curd

目录结构

│  .gitignore
│  Cargo.lock
│  Cargo.toml
│  diesel.toml
│
├─migrations
│  │  .gitkeep
│  │
│  ├─00000000000000_diesel_initial_setup
│  │      down.sql
│  │      up.sql
│  │
│  └─2022-07-23-033829_create_posts
│          down.sql
│          up.sql
│
└─src
    │  lib.rs
    │  models.rs
    │  schema.rs
    │
    └─bin
            delete_post.rs
            insert_post.rs
            select_post.rs
            update_post.rs

src/schema.rs diesel创建出来的,表示数据库表的对象

连接

src/lib.rs

#[macro_use]
extern crate diesel; //复用diesel里面的宏

use crate::models::{NewPost, Post};
use diesel::prelude::*;

pub mod models;
pub mod schema;

pub fn create_conn() -> PgConnection {
    let database_url = "postgres://username:password@localhost/diesel_demo";
    PgConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error conn to {}", database_url))
}


查询

src/model.rs

#[derive(Queryable)]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub body: String,
    pub published: bool,
}

src/bin/select_post.rs

use diesel::prelude::*;
use diesel_demo::create_conn;
use diesel_demo::models::Post;
use diesel_demo::schema::posts::dsl::*; //posts对象位置,给表 (posts::table->posts) 和 字段(posts::published->published) 设置别名

fn main() {
    let pattern = format!("%{}%", "book");
    let conn = create_conn();
    let res = posts
        .filter(published.eq(false))
        .filter(title.like(pattern))
        .limit(2)
        .load::<Post>(&conn)
        .expect("Error loading posts");

    println!("Displaying {} posts", res.len());
    for post in res {
        println!("{}", post.title);
        println!("-----------\n");
        println!("{}", post.body);
    }
}

filter() where条件

插入

src/model.rs 添加要插入的字段

#[derive(Insertable)]
#[table_name = "posts"]
pub struct NewPost<'a> {
    pub title: &'a str,
    pub body: &'a str,
}

src/lib.rs 添加插入方法

pub fn insert_post(conn: &PgConnection, title: &str, body: &str) -> Post {
    use schema::posts;
    let new_post = NewPost { title, body };
    //下面代码提示会出现问题
    diesel::insert_into(posts::table)
        .values(&new_post)
        .get_result::<Post>(conn)
        .expect("Error saving new post")
}

src/bin/insert_post.rs

use diesel_demo::{create_conn, insert_post};

fn main() {
    let conn = create_conn();

    let title = "rust book";
    let body = "rust content";

    let post = insert_post(&conn, title, body);
    println!(
        "Insert into posts,id:{},tilte:{},body:{}",
        post.id, post.title, post.body
    );
}

更新

use std::env::args;

use diesel::prelude::*;
use diesel_demo::create_conn;
use diesel_demo::models::Post;
use diesel_demo::schema::posts::dsl::{posts, published, title};

fn main() {
    let id = args()
        .nth(1)
        .expect("输入要更新的数据 id")
        .parse::<i32>()
        .expect("Invalid ID");

    let conn = create_conn();

    let post = diesel::update(posts.find(id))
        .set((title.eq("c++ book"), published.eq(false)))
        .get_result::<Post>(&conn)
        .unwrap_or_else(|_| panic!("Unable to find post {}", id)); //这里代码提示会出不来

    println!("Published post {}", post.title);
}

更新用 eq(val),多个值用()括起来

删除

use std::env::args;

use diesel::prelude::*;
use diesel_demo::{create_conn, schema::posts::dsl::*};

fn main() {
    let target = args().nth(1).expect("输入 title 中的关键字进行删除");
    let pattern = format!("%{}%", target);

    let conn = create_conn();
    let num_deleted = diesel::delete(posts.filter(title.like(pattern)))
        .execute(&conn)
        .expect("error deleting posts");

    println!("Deleted {} posts", num_deleted);
}

总结

在写完官方的demo后,自己再动手实践一下,diesel 用起来挺方便的,缺点是会出现代码提示不出来,不知道代码写的对不对.

标签:use,diesel,posts,学习,let,rust,post,conn
来源: https://www.cnblogs.com/blackTree/p/16512280.html