Expand description
This create offers:
- MySql/SQLite database’s helper in pure rust;
- A mini orm framework (Just MySQL/SQLite)。
Features:
- Other Database support, i.e. support Oracle, MSSQL…;
- support of named parameters for custom condition;
Installation
Put the desired version of the crate into the dependencies
section of your Cargo.toml
:
[dependencies]
akita = "0.4.0"
Feature.
akita-mysql
- to use mysqlakita-sqlite
- to use sqlite
Annotions.
- Table - to make Akita work with structs
- column - to make struct field with own database.
- name - work with column, make the table’s field name. default struct’ field name.
- exist - ignore struct’s field with table. default true.
Support Field Types.
Option<T>
u8, u32, u64
i32, i64
usize
f32, f64
bool
serde_json::Value
str, String
NaiveDate, NaiveDateTime
Example
/// Annotion Support: AkitaTable、table_id、field (name, exist)
#[derive(AkitaTable, Clone, Default)]
#[table(name = "t_system_user")]
pub struct User {
#[table_id(name = "id")]
pub pk: i64,
pub id: String,
pub headline: Option<NaiveDateTime>,
/// 状态
pub status: u8,
/// 用户等级 0.普通会员 1.VIP会员
pub level: u8,
/// 生日
pub birthday: Option<NaiveDate>,
/// 性别
pub gender: u8,
#[field(exist = "false")]
pub is_org: bool,
#[field(name = "token")]
pub url_token: String,
}
fn main() {
let cfg = AkitaConfig::new(String::from("mysql://root:password@localhost:3306/akita"))
.set_connection_timeout(Duration::from_secs(6))
.set_log_level(LogLevel::Info).set_max_size(6);
let akita = Akita::new(cfg).expect("must be ok");
// The Wrapper to build query condition
let wrapper = Wrapper::new()
.eq("username", "ussd") // username = 'ussd'
.gt("age", 1) //! age > 1
.lt("age", 10) // age < 10
.inside("user_type", vec!["admin", "super"]) // user_type in ('admin', 'super')
.and(|wrapper| { // or
wrapper.like("username", &name)
.or_direct().like("username", &name)
});
// CRUD with Akita
let insert_id: Option<i32> = akita.save(&User::default()).unwrap();
let _ = akita.save_batch(&[&User::default()]).unwrap();
// Update with wrapper
let res = akita.update(&User::default(), Wrapper::new().eq("name", "Jack")).unwrap();
// Update with primary id
let res = akita.update_by_id(&User::default());
// Query return List
let list: Vec<User> = akita.list(Wrapper::new().eq("name", "Jack")).unwrap();
// Query return Page
let pageNo = 1;
let pageSize = 10;
let page: IPage<User> = akita.page(pageNo, pageSize, Wrapper::new().eq("name", "Jack")).unwrap();
// Remove with wrapper
let res = akita.remove::<User>(Wrapper::new().eq("name", "Jack")).unwrap();
// Remove with primary id
let res = akita.remove_by_id::<User,_>(0).unwrap();
// Get the record count
let count = akita.count::<User>(Wrapper::new().eq("name", "Jack")).unwrap();
// Query with original sql
let user: User = akita.exec_first("select * from t_system_user where name = ? and id = ?", ("Jack", 1)).unwrap();
// Or
let user: User = akita.exec_first("select * from t_system_user where name = :name and id = :id", params! {
"name" => "Jack",
"id" => 1
}).unwrap();
let res = akita.exec_drop("select now()", ()).unwrap();
// Transaction
akita.start_transaction().and_then(|mut transaction| {
let list: Vec<User> = transaction.list(Wrapper::new().eq("name", "Jack"))?;
let insert_id: Option<i32> = transaction.save(&User::default())?;
transaction.commit()
}).unwrap();
// CRUD with Entity
let model = User::default();
// insert
let insert_id = model.insert::<Option<i32>, _>(&akita).unwrap();
// update
let res = model.update_by_id::<_>(&akita).unwrap();
// delete
let res = model.delete_by_id::<i32,_>(&akita, 1).unwrap();
// list
let list = User::list::<_>(Wrapper::new().eq("name", "Jack"), &akita).unwrap();
// page
let page = User::page::<_>(pageNo, pageSize, Wrapper::new().eq("name", "Jack"), &akita).unwrap();
// Fast with sql
pub static AK: Lazy<Akita> = Lazy::new(|| {
let mut cfg = AkitaConfig::new("xxxx".to_string()).set_max_size(5).set_connection_timeout(Duration::from_secs(5)).set_log_level(LogLevel::Info);
Akita::new(cfg).unwrap()
});
#[sql(AK,"select * from user where id = ?")]
fn select_example(id: &str) -> Vec<User> { todo!() }
// or:
#[sql(AK,"select * from user where mch_no = ?")]
fn select_example2(ak: &AKita, id: &str) -> Vec<User> { todo!() }
}
API Documentation
Wrapper
let mut wrapper = Wrapper::new().like(true, "column1", "ffff")
.eq(true, "column2", 12)
.eq(true, "column3", "3333")
.inside(true, "column4", vec![1,44,3])
.not_between(true, "column5", 2, 8)
.set(true, "column1", 4);
Update At 2021.12.08 10:21 By Mr.Pan
Re-exports
pub use akita_core as core;
Modules
Macros
Structs
an interface executing sql statement and getting the results as generic Akita values without any further conversion.
Field
An iterator over Row
s.
The local timescale. This is implemented via the standard time
crate.
ISO 8601 calendar date without timezone. Allows for every proleptic Gregorian date from Jan 1, 262145 BCE to Dec 31, 262143 CE. Also supports the conversion from ISO 8601 ordinal and week date.
ISO 8601 combined date and time without timezone.
use this to store data retrieved from the database
This is also slimmer than Vec
Enums
AkitaKeyword is mainly used to distinguish whether it is the type of database function or other keywords If you need to use some system functions or keywords, you can distinguish them from ordinary strings
Segment are generally not used directly unless you are using the
more low level functionality in the library. For the most part
this is hidden with the help of the ToSegment
trait.
Traits
Things that may be used as an index of a row column.
Table
A trait to allow passing of parameters ergonomically in em.execute_sql_with_return
Functions
Will panic if could not convert v
to T
Will return Err(FromValueError(v))
if could not convert v
to T