Crate akita

source · []
Expand description

This create offers:

  • MySql/SQLite database’s helper in pure rust;
  • A mini orm framework (Just MySQL/SQLite)。


  • Other Database support, i.e. support Oracle, MSSQL…;
  • support of named parameters for custom condition;


Put the desired version of the crate into the dependencies section of your Cargo.toml:

akita = "0.3.0"


  • akita-mysql - to use mysql
  • akita-sqlite - to use sqlite


  • 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


use akita::*;
use chrono::{NaiveDateTime, NaiveDate};
/// 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 db_url = String::from("mysql://root:password@localhost:3306/akita");
    let cfg = AkitaConfig::new(db_url).set_connection_timeout(Duration::from_secs(6))
    let mut pool = Pool::new(cfg).expect("must be ok");
    let mut entity_manager = pool.entity_manager().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')
    // CRUD with EntityManager
   let insert_id: Option<i32> =;
   let insert_ids: Vec<Option<i32>>= entity_manager.save_batch(&[&User::default()]).unwrap();
   // Update with wrapper
   let res = entity_manager.update(&User::default(), Wrapper::new().eq("name", "Jack")).unwrap();
   // Update with primary id
   let res = entity_manager.update_by_id(&User::default());
   // Query return List
   let list: Vec<User> = entity_manager.list(Wrapper::new().eq("name", "Jack")).unwrap();
   // Query return Page
   let pageNo = 1;
   let pageSize = 10;
   let page: IPage<User> =, pageSize, Wrapper::new().eq("name", "Jack")).unwrap();
   // Remove with wrapper
   let res = entity_manager.remove::<User>(Wrapper::new().eq("name", "Jack")).unwrap();
   // Remove with primary id
   let res = entity_manager.remove_by_id::<User,_>(0).unwrap();
   // Get the record count
   let count = entity_manager.count::<User>(Wrapper::new().eq("name", "Jack")).unwrap();
   // Query with original sql
   let user: User = entity_manager.execute_first("select * from t_system_user where name = ? and id = ?", ("Jack", 1)).unwrap();
   // Or
   let user: User = entity_manager.execute_first("select * from t_system_user where name = :name and id = :id", params! {
       "name" => "Jack",
       "id" => 1
   let res = entity_manager.execute_drop("select now()", ()).unwrap();

    // CRUD with Entity
   let model = User::default();
   // insert
   let insert_id = model.insert::<Option<i32>, _>(&mut entity_manager).unwrap();
   // update
   let res = model.update_by_id::<_>(&mut entity_manager).unwrap();
   // delete
   let res = model.delete_by_id::<i32,_>(&mut entity_manager, 1).unwrap();
   // list
   let list = User::list::<_>(Wrapper::new().eq("name", "Jack"), &mut entity_manager).unwrap();
   // page
   let page = User::page::<_>(pageNo, pageSize, Wrapper::new().eq("name", "Jack"), &mut entity_manager).unwrap();

    // Fast with Akita
   let list: Vec<User> = Akita::new().conn(pool.database().unwrap())
   .wrapper(Wrapper::new().eq("name", "Jack"))

   let page: IPage<User> = Akita::new().conn(pool.database().unwrap())
   .wrapper(Wrapper::new().eq("name", "Jack"))
   .page::<User>(1, 10).unwrap();

    // Transaction
    let result = entity_manager.start_transaction().and_then(|mut transaction| {
        let list: Vec<User> = transaction.list(Wrapper::new().eq("name", "Jack"))?;
        let insert_id: Option<i32> =;


API Documentation


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


pub use akita_core as core;


Common Params



This macro is a convenient way to pass named parameters to a statement.


an interface executing sql statement and getting the results as generic Akita values without any further conversion.


An iterator over Rows.

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 when serialized


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.


A trait to allow passing of parameters ergonomically in em.execute_sql_with_return