Giter VIP home page Giter VIP logo

sqlx-model's Introduction

基于 sqlx 轻量级orm实现

注意:当前仅供学习或测试使用,后面版本会有比较大变动.

引入

使用 default-features = false 禁用默认使用的tokio,自行选择运行时跟数据库类型

[dependencies]
sqlx-model = { version = "~0.2.1", path = "../../",default-features = false,features = ["sqlx-mysql"] }
sqlx = {version = "~0.6",features = [ "mysql","offline","runtime-async-std-native-tls"] }
async-std={version = "1.10.0", features = [ "attributes" ]}
常用增删改查示例

使用前准备,结构体增加derive宏

使用 sqlx_model::SqlxModel 宏 自动增加辅助方法 同时会创建 UserModelRef 的结构,用于辅助增删改查操作

如果已有表结构,可以通过表结构生成对应的rsmodel文件,以下工具可用:

https://crates.io/crates/sqlx-model-tools 具体使用方式参考该create文档

#[derive(sqlx::FromRow,Clone,Debug)]
#[sqlx_model(db_type="MySql",table_pk="id",table_name="users")]
pub struct UserModel {
    #[sqlx(default)]
    pub id: u32,
    #[sqlx(default)]
    pub nickname: String,
    #[sqlx(default)]
    pub gender: u8,
    #[sqlx(default)]
    pub headimg: Option<String>,
    #[sqlx(default)]
    #[sqlx(rename="password_id")]//自定义字段名
    pub password_id: u32,
}
  1. 新增:

更多使用方法参考 tests 目录

    let nike_name="new insert".to_string();
    let gender=1;
    let userinsert=sqlx_model::model_option_set!(UserModelRef,{
        nickname:nike_name,
        gender:gender,
        //不需要全部字段赋值,没赋值生成SQL会少对应字段,等于用表中默认值
    });
    let i1=Insert::<sqlx::MySql,UserModel,_>::new(userinsert).execute(&db).await.unwrap();
    assert!(i1.last_insert_id()>0);
  1. 删除:

更多使用方法参考 tests 目录

    let select=Select::type_new::<UserModel>();
    let user=select.fetch_one_by_where::<UserModel>(&WhereOption::Where(format!("id=1")), &db).await.unwrap();
    let detete=Delete::<sqlx::MySql>::new(UserModel::table_name())
        .execute_by_pk(&user, &db)
        .await.unwrap();
    assert_eq!(detete.rows_affected(),1);
  1. 修改:

更多使用方法参考 tests 目录

    let nike_name="change to 1".to_string();
    let userchange=sqlx_model::model_option_set!(UserModelRef,{
    nickname:nike_name,
    });
    let update=Update::<sqlx::MySql,UserModel,_,_>::new(userchange);
    let update=update.execute_by_scalar_pk(1,&db).await.unwrap();
    assert_eq!(update.rows_affected(),1);
  1. 查询:

更多使用方法参考 tests 目录

    let iid=1;
    let select=Select::type_new::<UserModel>();
    let user=select.fetch_one_by_scalar_pk::<UserModel,_,_>(iid, &db).await.unwrap();
    assert_eq!(user.id as u64,iid);
  1. 事务:

更多使用方法参考 tests 目录

    let mut ta=db.begin().await.unwrap();
    let nike_name="new tran".to_string();
    let userinsert=sqlx_model::model_option_set!(UserModelRef,{
        nickname:nike_name,
        gender:11,
    });
    Insert::<sqlx::MySql,UserModel,_>::new(userinsert).execute(&mut ta).await.unwrap();
    //其他 查删改操作...
    ta.commit().await.unwrap();
  1. 事务跟Poll选择执行
fn my_exec(transaction:Option<&mut Transaction<'t,sqlx::MySql>>){
    let pool=get_db_pool();
    let res=executor_option!({
        //  transaction 为 None 用 &pool 代替 db 如果 [因为execute为泛型且为&mut,多次时需要手动调用as_copy]
        //  否则为 transaction 里的值代替 db
        Insert::<sqlx::MySql, UserEmailModel, _>::new(idata).execute(db.as_copy()).await?
    },transaction,&pool,db);
}
  1. 日期及其他自定义字段类型支持示例
use chrono::{DateTime, Datelike, TimeZone, Timelike, Utc};
use sqlx::FromRow;
use sqlx_model::{SqlQuote, SqlxModel};
use std::ops::Deref;
#[derive(sqlx::Type, Clone, Debug, PartialEq, Eq)]
#[sqlx(transparent)]
pub struct MyTime<Tz: TimeZone>(DateTime<Tz>);
impl<Tz: TimeZone> Deref for MyTime<Tz> {
    type Target = DateTime<Tz>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
 //其他自定义结构需实现 SqlQuote<T> 
 //其中 T 为sqlx支持类型[如String,i32,i64...等]
impl<Tz: TimeZone> SqlQuote<String> for MyTime<Tz> {
    fn sql_quote(&self) -> String {
        format!(
            "{}-{}-{} {}:{}:{}",
            self.0.year(),
            self.0.month(),
            self.0.day(),
            self.0.hour(),
            self.0.minute(),
            self.0.second()
        )
    }
}

#[derive(FromRow, Clone, Debug, SqlxModel)]
pub struct UserModel {
    #[sqlx(default)]
    pub id: u64,
    pub id1: MyTime<Utc>,
}
辅助SQL生成操作
     let data=["dd","b'bb"];
     let password_id=Some(1);
     let sql=sql_format!(
            "select * from yaf_users where id>{id} {in_grade} and password_id {password_where} ",
            id=1,
            in_grade=sql_array_str!("and grade in ({})",data),
            password_where=sql_option_str!("= {}","is {}",password_id)
        );
     println!("{sql}");//select * from yaf_users where id>1 and grade in ('dd','b\'bb') and password_id = 1
    //会转义'防止sql注入

sqlx-model's People

Contributors

shanliu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

qibinlin

sqlx-model's Issues

根据结构体生成表的SQL

实现从 定义的结构体 上生成SQL DML的工具
预计要支持:
自定义字段类型,当未指定根据类型做映射
指定索引字段

关系配置实现

包含:

1对1
1对多
多对1
多对多

以上4种关系配置
以公开暂定想法是通过宏方式做配置后生成一些方法
通过生成的方法来获取对应关系的数据

About the SqlQuote for DateTime<Utc> not implemented

image

image

对于实现 SqlQuote trait 是否有例子? 以及对于使用了sqlx:Type 宏的自定义类型 如何实现 SqlQuote trait

error[E0599]: no method named `sql_quote` found for reference `&chrono::DateTime<Utc>` in the current scope
  --> src/entity/sys_config.rs:15:39
   |
15 | #[derive(PartialEq, Debug, Clone, Eq, sqlx_model::SqlxModel)]
   |                                       ^^^^^^^^^^^^^^^^^^^^^ method not found in `&chrono::DateTime<Utc>`
   |
   = note: this error originates in the macro `$crate::model_table_ref_define` which comes from the expansion of the derive macro `sqlx_model::SqlxModel` (in Nightly builds, run with -Z macro-backtrace for more info)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.