9个版本
0.3.6 | 2024年1月12日 |
---|---|
0.3.5 | 2024年1月9日 |
0.3.4 | 2023年12月28日 |
0.2.0 | 2023年11月29日 |
0.1.0 | 2023年11月29日 |
#460 在 数据库接口
每月 57 次下载
在 2 个Crates中使用(通过 taitan)
2.5MB
2.5K SLoC
⚠️ LUNA-ORM正在快速开发中,API可能会更改,您不应在生产环境中使用它。
目前,只是尝个鲜,等待1.0版本。
那时,API将是稳定的,并保证向后兼容。
LUNA-ORM
LUNA-ORM 是基于SQLx的异步ORM框架。用❤️构建。
- 直观:简单的API,这是世界上最简单的ORM。
- 节省时间:大多数有用的API已默认实现,无需浪费时间。
- 流畅的事务处理:事务几乎与正常操作相同。
- 模板SQL:您可以无痛苦地执行自己的SQL。
- 动态参数:默认处理复杂的动态SQL。
- 真正的异步:基于SQLx,LUNA-ORM完全异步。
- 错误友好:每个错误都有其意义。
安装
luna-orm = { version = "0.3.5" }
直观
一切都应该如您所愿地工作。
创建数据库实例。
use luna_orm::prelude::*;
use luna_orm::LunaOrmResult;
#[tokio::main]
pub async fn main() -> LunaOrmResult<()> {
// 1. example use sqlite with local file mode
let config = SqliteLocalConfig::new("./workspace", "test.db");
// 2. create a DB instance.
let mut db: DB<SqliteDatabase> = SqliteDatabase::build(config).await.unwrap().into();
// optional: you may need to create the table for the first time.
// db.execute_plain(
// "CREATE TABLE IF NOT EXISTS `user`(`id` INT PRIMARY KEY, `age` INT, `name` VARCHAR(64))",
// )
Ok(())
}
插入实体
// 1. Declare an Entity, Derive macro Entity, give a TableName
#[derive(Entity, Clone, Debug)]
#[TableName = "user"]
pub struct HelloEntity {
#[PrimaryKey]
id: i32,
name: String,
age: Option<i32>,
}
// 2. create an entity.
let entity = HelloEntity {
id: 1,
name: "Allen".to_string(),
age: Some(23)
};
// 3. insert it, this is so intuitive, you don't need to warry about anything, it jsut works.
let result = db.insert(&entity).await?;
节省时间
几乎90%的命令已默认实现,这可能为您节省时间。
概念
如果您想插入
// insert an entity if not exists.
async fn insert(&mut self, entity: &dyn Entity) -> LunaOrmResult<bool>;
// insert is not exists, and update if already exists.
async fn upsert(&mut self, entity: &dyn Entity) -> LunaOrmResult<bool>;
// insert an entity if not exists, and return the inserted entity.
async fn create<'a>(&mut self, entity: &'a dyn Entity) -> LunaOrmResult<&'a dyn Entity>;
如果您想更新
// update one record by primary
async fn update(&mut self, mutation: &dyn Mutation, primary: &dyn Primary) -> LunaOrmResult<bool>
// update many records by location
async fn change(&mut self,mutation: &dyn Mutation, location: &dyn Location) -> LunaOrmResult<usize>;
如果您想删除
// delete one record by primary
async fn delete(&mut self, primary: &dyn Primary) -> LunaOrmResult<bool>;
// delete many records by location
async fn purify(&mut self, location: &dyn Location) -> LunaOrmResult<usize>;
如果您想选择
// fetch one entity by primary and select fields by selection
async fn select<SE>(
&mut self,
primary: &dyn Primary,
selection: &dyn Selection
) -> LunaOrmResult<Option<SE>>
where
SE: SelectedEntity + Send + Unpin;
// fetch many entity by location&order and select fields by selection
async fn search<SE>(
&mut self,
location: &dyn Location,
order_by: Option<&dyn OrderBy>,
selection: &dyn Selection,
) -> LunaOrmResult<Vec<SE>>
where
SE: SelectedEntity + Send + Unpin;
// fetch paged entity with pagination
async fn search_paged<SE>(
&mut self,
location: &dyn Location,
order_by: Option<&dyn OrderBy>,
selection: &dyn Selection,
page: &Pagination,
) -> LunaOrmResult<PagedList<SE>>
where
SE: SelectedEntity + Send + Unpin;
流畅的事务处理
let db: DB<SqliteDatabase> = SqliteDatabase::build(config).await.unwrap().into();
// 1. start a transaction by the simple async api.
let mut trx = db.transaction().await.unwrap();
// 2. just do every thing you want,
// every command is just same as normal.
trx.insert(...).await?;
trx.select(...).await?;
trx.delete(...).await?;
// 3. last thing is just commit, if you forget, trx will rollback by default.
trx.commit().await?;
模板SQL
#[derive(TemplateRecord)]
#[TemplateSql = "update article set content = #{content} where id = #{id}"]
pub struct HelloTemplate {
id: i32,
content: String,
}
#[derive(TemplateRecord)]
#[TemplateSql = "select * FROM article where id > #{id}"]
#[TemplateCountSql = "select count(*) as count FROM article where id > #{id}"]
pub struct HelloSelectTemplate {
id: i32,
}
let template = HelloTemplate {
id: 2,
content: "template".to_string(),
};
// template just works as you want, #{} is the variable
db.execute_by_template(&template).await?;
// if you want to execute paged template,
// you should give a TemplateCountSql, the `as count` is important.
let select_template = HelloSelectTemplate { id: 0 };
let page = Pagination {
page_size: 1,
page_num: 1,
};
let result: PagedList<HelloSelectedEntity> =
db.search_paged_by_template(&select_template, &page).await?;
动态参数
真正的异步
错误友好
MSRV:最低支持的Rust版本
1.75.0
LUNA-ORM使用异步特例。
安全性
此库使用 #![forbid(unsafe_code)]
许可证
Apache 2.0
依赖关系
~45MB
~793K SLoC