4个版本 (2个重大更新)
0.3.0 | 2024年5月8日 |
---|---|
0.2.1 | 2024年3月25日 |
0.2.0 | 2024年3月25日 |
0.1.0 | 2023年10月7日 |
#266 in #orm
用于 njord
27KB
212 行
Njord
一个轻量级且可扩展的Rust ORM库。
目录
支持的数据库
数据库 | 支持 | 状态 |
---|---|---|
SQLite | ✅ | 目前支持。 |
PostgreSQL | ❌ | 不支持,能帮助我们实现它吗? |
MySQL | ❌ | 不支持,能帮助我们实现它吗? |
MariaDB | ❌ | 不支持,能帮助我们实现它吗? |
Oracle | ❌ | 不支持,能帮助我们实现它吗? |
MSSQL | ❌ | 不支持,能帮助我们实现它吗? |
入门指南
初始化新项目
首先我们需要生成我们的项目。
cargo new --bin njord_demo
现在,让我们将Njord添加到我们的依赖项中。我们还将使用一个名为.env的工具来管理我们的环境变量。我们也会将它添加到依赖项中。
[dependencies]
# The core APIs, including the Table trait.
# using #[derive(Table)] to make njord work with structs
# and enums defined in your crate.
njord = { version = "<version>", features = ["sqlite"] }
njord_derive = { version = "<version>" }
添加模式文件
现在我们已经准备好了,我们需要定义我们的模式文件,我们将创建在 src/schema.rs
下。我们将存储基本的结构体,这些结构体将映射到数据库。
#[derive(Table)]
#[table_name = "users"]
pub struct User {
id: usize,
username: String,
email: String,
address: String,
}
#[derive(Table)]
#[table_name = "categories"]
pub struct Category {
id: usize,
name: String,
}
#[derive(Table)]
#[table_name = "products"]
pub struct Product {
id: usize,
name: String,
description: String,
price: f64,
stock_quantity: usize,
category: Category, // one-to-one relationship
discount: Option<f64>, // allow for null
}
#[derive(Table)]
#[table_name = "orders"]
pub struct Order {
id: usize,
user: User, // one-to-one relationship
products: Vec<Product>, // one-to-many relationship - populates from based on junction table (gets from macro attribute "table_name" and combines them for example, orders_products)
total_cost: f64,
}
现在我们已经设置好了,我们需要创建设置数据库的SQL语句并执行它。
-- users table
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
email TEXT NOT NULL,
address TEXT NOT NULL
);
-- products table
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL,
price REAL NOT NULL,
stock_quantity INTEGER NOT NULL,
category INTEGER REFERENCES categories(id),
discount: REAL NULL
);
-- orders table
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
total_cost REAL NOT NULL
);
-- order_products table
CREATE TABLE order_products (
order_id INTEGER REFERENCES orders(id),
product_id INTEGER REFERENCES products(id),
PRIMARY KEY (order_id, product_id)
);
用法
那么我们如何建立连接并实际选择或插入数据库中的数据呢?让我们来了解一下。请注意,这些示例可能已经过时,所以不要将其作为真实来源。
SQlite
建立连接
要建立连接,我们首先需要调用 sqlite::open()
函数,并使用它与一个match语句。
let db_name = "njord.db";
let db_path = Path::new(&db_name);
match sqlite::open(db_path) {
Ok(c) => {
println!("Database opened successfully!");
// Additional logic when we are connected.
// We need to open a connection and pass it
// to the corresponding sqlite function.
}
Err(err) => eprintln!("Error opening the database: {}", err),
}
插入数据
let user = User {
username: String::from("john_doe"),
email: String::from("[email protected]"),
address: String::from("123 Main St"),
};
let result = sqlite::insert(c, vec![user]);
assert!(result.is_ok());
生成的SQL
INSERT INTO users (
username,
email,
address
) VALUES (
'john_doe',
'[email protected]',
'123 Main St'
)
更新数据
let columns = vec!["username".to_string(), "address".to_string()];
let where_condition = Condition::Eq("username".to_string(), "john_doe".to_string());
let user = User {
username: String::from("john_doe_2"),
email: String::from("[email protected]"),
address: String::from("1234 Main St"),
};
let mut order = HashMap::new();
order.insert(vec!["id".to_string()], "DESC".to_string());
let result = sqlite::update(c, user)
.set(columns)
.where_clause(where_condition)
.order_by(order)
.limit(4)
.offset(0)
.build();
assert!(result.is_ok());
生成的SQL
UPDATE users
SET
username
WHERE
username = 'john_doe'
ORDER BY
id DESC
LIMIT 4
OFFSET 0
删除数据
let where_condition = Condition::Eq("username".to_string(), "john_doe".to_string());
let mut order = HashMap::new();
order.insert(vec!["id".to_string()], "DESC".to_string());
let result = sqlite::delete(c)
.from(User::default())
.where_clause(where_condition)
.order_by(order)
.limit(20)
.offset(0)
.build();
assert!(result.is_ok());
生成的SQL
DELETE FROM users
WHERE
username = 'john_doe'
ORDER BY
id DESC
LIMIT 20
OFFSET 0
选择数据
let columns = vec!["id".to_string(), "username".to_string(), "email".to_string(), "address".to_string()];
let where_condition = Condition::Eq("username".to_string(), "john_doe".to_string());
let group_by = vec!["username".to_string(), "address".to_string()];
let mut order_by = HashMap::new();
order_by.insert(vec!["id".to_string()], "ASC".to_string());
let having_condition = Condition::Gt("id".to_string(), "1".to_string());
// Build the query
// We need to pass the struct User with the Default trait in .from()
let result: Result<Vec<User>> = sqlite::select(c, columns)
.from(User::default())
.where_clause(where_condition)
.order_by(order_by)
.group_by(group_by)
.having(having_condition)
.build();
match result {
Ok(result) => {
assert_eq!(result.len(), 1);
}
Err(error) => panic!("Failed to SELECT: {:?}", error),
};
生成的SQL
SELECT
id,
username,
email,
address
FROM
users
WHERE
username = 'mjovanc'
GROUP BY
username,
email
HAVING
id > 1
ORDER BY
email DESC
获取帮助
你在使用Njord时遇到麻烦吗?我们想帮忙!
-
阅读我们文档上的说明。
-
如果你正在升级,请阅读发布说明以获取升级说明和“新功能和亮点”。
-
提出问题,我们监视 stackoverflow.com 上标记为Njord的问题。
-
在https://github.com/mjovanc/njord/issues上报告Njord的bug。
报告问题
Njord使用GitHub的集成问题跟踪系统来记录bug和功能请求。如果你要提出问题,请遵循以下建议
-
在提交bug之前,请先在问题跟踪器中搜索,看看是否有人已经报告了该问题。
-
如果问题尚未存在,请创建一个新的问题。
-
请在问题报告中提供尽可能多的信息。我们希望了解您使用的Njord版本、操作系统和Rust版本。
-
如果您需要粘贴代码或包含堆栈跟踪,请使用Markdown。```可以用来在文本前后进行转义。
-
如果可能的话,尝试创建一个重现问题的测试用例或项目,并将其附加到问题中。
贡献
在贡献之前,请阅读贡献指南,了解如何开始使用Njord以及提交贡献时应包含的内容。
行为准则
任何与Njord在任何空间(包括但不限于本GitHub仓库)互动的人必须遵守我们的行为准则。
贡献者
以下贡献者要么帮助启动了此项目,要么贡献了代码,要么正在积极维护它(包括文档),或者以其他方式成为本项目的杰出贡献者。我们想花点时间来表彰他们。
许可证
BSD 3-Clause许可证。
依赖项
~23MB
~437K SLoC