Back

rust - diesel 1 的安装与使用 (连接数据库,读取)

发布时间: 2020-05-18 09:03:00

diesel 是 rust世界的 持久层框架。 官方网址  diesel.rs  (域名很有意思)

截止 2020-5-18 , 5500关注, 支持的数据库是  postgres, mysql , sqlite 

一 创建数据库,表,映射,并查询数据

1. cargo new --lib test_diesel

会创建一个新文件夹: test_diesel

2. 修改Cargo.toml

[dependencies]
diesel = { version = "1.0.0", features = ["postgres"] }
dotenv = "0.9.0"

3. cargo install diesel_cli

4. 增加新文件: .env  , 内容如下:

DATABASE_URL=mysql://root:666666@localhost/diesel_demo

5. $ diesel setup  , 会分别创建一个文件夹和一个数据库

Creating migrations directory at: /workspace/test_rust/test_diesel2/migrations
Creating database: diesel_demo

6. 运行migration 

diesel migration generate create_posts

分别增加对应的up/down.sql

up.sql:  ( 这里是mysql的语句, 跟官方自带的postgres语句不太一样,稍有修改)

create table posts (
  id int(11) not null auto_increment,
  title varchar(255) not null,
  body text,
  published boolean not null default false,
  primary key (`id`)
)

down.sql:

drop database posts

7. 运行:

diesel migration run  ( 回退的话,就用redo)

这个操作会自动的更新 src/schema.rs 的内容:

table! {
    posts (id) {
        id -> Integer,
        title -> Varchar,
        body -> Nullable<Text>,
        published -> Bool,
    }
}

8. 连接数据库:

src/lib.rs

#[macro_use]
extern crate diesel;
extern crate dotenv;

pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

pub fn establish_connection() -> MysqlConnection {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL")
        .expect("DATABASE_URL must be set");
    MysqlConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("error connecting to {}", database_url));

}

9. 增加: src/models.rs 作为 持久层的映射。

// 这里的 order struct中的属性的顺序一定要跟 schema.rs 中的order表中的列的顺序一致。
#[derive(Queryable)]
pub struct Order {
    pub id: i32,
    pub title: String,
    pub body: Option,
    pub published: bool,
}

10.  src/bin/show_posts.rs

 src/bin/show_posts.rs 
// 声明需要用到的外部模块
extern crate test_diesel2;
extern crate diesel;

use self::test_diesel2::*;
use self::models::*;
use self::diesel::prelude::*;

fn main(){
    use test_diesel2::schema::posts::dsl::*;

    let connection = establish_connection();
    let results = posts.filter(published.eq(true))
        .limit(5)
        .load::(&connection)
        .expect("Error loading posts");
    println!("Displaying {} posts", results.len());
    for post in results {
        println!("======");
        println!("{:?}", post.title);
        println!("{:?}", post.body);
    }
}

11. 运行: cargo run ,就可以看到,读取数据库的内容了:

cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/show_posts`
Displaying 0 posts

二. 我们开始创建新记录

修改 models.rs 增加以下内容:

use super::schema::posts;

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

创建src/bin/write_post.rs , 增加以下内容:

extern crate test_diesel2;
extern crate diesel;

use self::test_diesel2::*;
use std::io::{stdin, Read};

fn main() {
    let connection = establish_connection();

    let post = create_post(&connection, "lalala", "I am the body");
    println!(" saved title : lalaal with ");
}

为 src/lib.rs 增加以下内容:

use self::models::{Post, NewPost};

pub fn create_post<'a>(conn: &MysqlConnection, title: &'a str, body: &'a str)  {
    use schema::posts;
    let new_post = NewPost{
        title: title,
        body: body,
    };

    diesel::insert_into(posts::table)
        .values(&new_post)
        .execute(conn)
        .expect("Error saving new post");

}

运行:cargo run --bin write_post

就可以看到,内容被保存了。 ( 这里id 不会返回, 需要调用 select last_insert_id() 来 获得最新的id )

Back