一些例子

未匹配的标注

简单的查询

简单的查询是轻而易举的事。从数据库加载所有用户:

users::table.load(&mut connection)

会执行的 SQL

SELECT * FROM users;

加载一个用户的所有内容:

Post::belonging_to(user).load(&mut connection)

会执行的 SQL

SELECT * FROM posts WHERE user_id = 1;

复杂的查询

Diesel强大的查询生成器可帮助您以零成本构建所需的简单或复杂查询

let versions = Version::belonging_to(krate)
  .select(id)
  .order(num.desc())
  .limit(5);
let downloads = version_downloads
  .filter(date.gt(now - 90.days()))
  .filter(version_id.eq(any(versions)))
  .order(date)
  .load::<Download>(&mut conn)?;

会执行的 SQL

SELECT version_downloads.*
  WHERE date > (NOW() - '90 days')
    AND version_id = ANY(
      SELECT id FROM versions
        WHERE crate_id = 1
        ORDER BY num DESC
        LIMIT 5
    )
  ORDER BY date

较少的样板代码

Diesel 代码生成为你生成样板。它使你能够更专注于业务逻辑,而不是映射到原始 SQL 和从原始 SQL映射。

这意味着你可以写这个:

#[derive(Queryable)]
pub struct Download {
    id: i32,
    version_id: i32,
    downloads: i32,
    counted: i32,
    date: SystemTime,
}

而不是这样:

pub struct Download {
    id: i32,
    version_id: i32,
    downloads: i32,
    counted: i32,
    date: SystemTime,
}

impl Download {
    fn from_row(row: &Row) -> Download {
        Download {
            id: row.get("id"),
            version_id: row.get("version_id"),
            downloads: row.get("downloads"),
            counted: row.get("counted"),
            date: row.get("date"),
        }
    }
}

插入

这不仅仅是阅读数据。Diesel 使结构更容易用于新记录

#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
    name: &'a str,
    hair_color: Option<&'a str>,
}

let new_users = vec![
    NewUser { name: "Sean", hair_color: Some("Black") },
    NewUser { name: "Gordon", hair_color: None },
];

insert_into(users)
    .values(&new_users)
    .execute(&mut connection);

会执行的 SQL

INSERT INTO users (name, hair_color) VALUES
  ('Sean', 'Black'),
  ('Gordon', DEFAULT)

如果你需要插入的行中的数据, 仅改变 executeget_resultget_results 即可。 Diesel 会处理剩下的工作。

let new_users = vec![
    NewUser { name: "Sean", hair_color: Some("Black") },
    NewUser { name: "Gordon", hair_color: None },
];

let inserted_users = insert_into(users)
    .values(&new_users)
    .get_results::<User>(&mut connection);

会执行的 SQL

INSERT INTO users (name, hair_color) VALUES
  ('Sean', 'Black'),
  ('Gordon', DEFAULT)
  RETURNING *

更新

Diesel 的代码生成器可以生成几种更新记录的方法,使您能够以对应用程序有意义的方式封装逻辑。

修饰一个 struct

post.published = true;
post.save_changes(&mut connection);

一次性批量变更

update(users.filter(email.like("%@spammer.com")))
    .set(banned.eq(true))
    .execute(&mut connection)

使用 struct 封装

update(Settings::belonging_to(current_user))
    .set(&settings_form)
    .execute(&mut connection)

人体工程学的原始 SQL

总会有一些查询使用原始 SQL 编写会更容易,或者无法用查询生成器表达。即使在这些情况下,Diesel 也提供了一个易于使用的 API 来编写原始 SQL。

#[derive(QueryableByName)]
#[diesel(table_name = users)]
struct User {
    id: i32,
    name: String,
    organization_id: i32,
}

// Using `include_str!` allows us to keep the SQL in a
// separate file, where our editor can give us SQL specific
// syntax highlighting.
sql_query(include_str!("complex_users_by_organization.sql"))
    .bind::<Integer, _>(organization_id)
    .bind::<BigInt, _>(offset)
    .bind::<BigInt, _>(limit)
    .load::<User>(&mut conn)?;

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~