#mysql #sql-query #sql-database #proc-macro #orm #sql

prkorm

这是一个过程宏,简化了在Rust结构体字段中创建mysql查询的过程。它提供了带有JOIN、子查询和其他复杂查询的SELECT、INSERT、UPDATE、DELETE操作。

9个版本 (4个重大更改)

0.5.4 2024年6月7日
0.5.3 2024年4月12日
0.5.1 2024年1月30日
0.5.0 2023年11月4日
0.1.0 2023年11月4日

#726数据库接口

MIT 许可证

50KB
753

过程宏表格

Table过程宏简化了基于Rust结构体字段创建SQL查询的过程。它提供了带有JOIN、子查询和其他复杂子句的SELECT、INSERT、UPDATE、DELETE操作。使用此宏,您可以自动生成这些方法,减少样板代码并提高代码可读性。

目录

用法

要使用Table过程宏,请按照以下步骤操作

  1. prkormcrate添加到您的Cargo.toml

    [dependencies]
    prkorm = "0.1"
    
  2. Table过程宏导入到您的Rust代码中

    use prkorm::Table;
    
  3. 将#[derive(Table)]属性应用到您的结构体上。这将自动为所有结构体生成select()、insert()、update()和delete()方法,包括但不限于table_primary_key()、table()、select_str()、select_field_name*()。然后您可以根据所需的查询类型链接函数,例如join函数、where、having、limit、order by、group by等。以下是一个宏的快速示例。

    #[derive(Table, Debug)]
    #[table_name("orders")]
    #[primary_key("id")]
    struct OrderModel {
        id: u32,
        customer_id: u32,
        address_id: u32,
        order_status: String,
        order_picture_url: String,
        created_at: String,
    }
    
    #[derive(Table, Debug)]
    #[table_name("customers")]
    struct Customer {
        id: u32,
        first_name: String,
        last_name: String,
    }
    
  4. 如下所示使用生成的函数

        let mut select_query: String = OrderModel::select()
        .select_str("CONCAT_WS(' ', `first_name`, `last_name`) as username ")
        .select_str("address_1")
        .left_join_by_customer_id(Customer::table(), "id")
        .left_join_by_address_id("addresses", "id")
        .order_by_created_at_desc()
        .where_order_status("PENDING")
        .having_order_status("PENDING")
        .build();
    
        println!("{}",select_query);
        //select_query:
        ```sql
        SELECT orders.id, orders.customer_id, 
        orders.address_id, orders.order_status, orders.order_picture_url, orders.created_at, 
        CONCAT_WS(' ', `first_name`, `last_name`) as username , address_1      
        FROM orders
        LEFT JOIN customers ON customers.id = orders.customer_id
        LEFT JOIN addresses ON addresses.id = orders.address_id
        WHERE orders.order_status = 'PENDING'
        HAVING orders.order_status = 'PENDING'
        ORDER BY orders.created_at DESC
        ```
    

示例

以下是如何使用Table过程宏的一些示例

use prkorm::Table;

 #[derive(Table, Debug)]
    #[table_name("orders")]
    struct OrderModel {
        id: u32,
        customer_id: u32,
        address_id: u32,
        order_status: String,
        order_picture_url: String,
        created_at: String,
    }

    #[derive(Table, Debug)]
    #[table_name("customers")]
    struct Customer {
        id: u32,
        mobile_number: u64,
        first_name: String,
        last_name: String,
    }

fn main() {
    // SELECT QUERY
    let mut select_query = OrderModel::select()
                            .where_customer_id_in(
                                Customer::select_id()
                                    .where_mobile_number_condition("!=","NULL")
                                    .build()
                                )
                            .build();

    // Output
    println!("{}", select_query);
    ```sql
    SELECT orders.id, orders.customer_id, orders.address_id, orders.order_status, orders.order_picture_url, orders.created_at
    FROM orders
    WHERE orders.customer_id IN (SELECT customers.id
    FROM customers
    WHERE customers.mobile_number != 'NULL')
    
    ```
    

    // INSERT QUERY
    let insert_query = Customer::insert()
                        .insert_to_first_name("Prakash")
                        // OR "9876543210"
                        .insert_to_mobile_number(9876543210u64) 
                        .build();

    // Output
    println!("{}", insert_query);

    ```sql
    INSERT INTO customers
    (first_name, mobile_number) VALUES  ('Prakash', '9876543210')
    ```

    
    // UPDATE QUERY: Note => No build() in update()
    let update_query =  Customer::update()
                        .update_first_name_with_value("JOHN")
                        .update_last_name_with_value("WICK")
                        .update_where_mobile_number_eq("9876543210");


    // Output
    println!("{}", update_query);

    ```sql
    UPDATE customers SET last_name = 'WICK', first_name = 'JOHN' 
    WHERE mobile_number = '9876543210'


    // DELETE QUERY: Note =>No build() in delete()
    let delete_query =  Customer::delete()
                        .delete_where_mobile_number_eq("9876543210");


    // Output
    println!("{}", update_query);

    ```sql
    DELETE FROM customers WHERE mobile_number = '9876543210'
    ```



}

```rust
#[derive(Table)]
#[table_name("posts")]
#[table_alias("P")]
#[primary_key("id")]
struct Post {
    id: i32,
    title: String,
    user_id: i32,
}

#[derive(Table)]
#[table_name("users")]
#[table_alias("U")]
struct User {
    id: i32,
    username: String,
}

fn main() {
    let query = User::select_str_as(
        &Post::select_function_over_field_name("COUNT", "*")
            .where_user_id(User::id())
            .build(),
        "total_post_count",
    )
    .where_id(1)
    .build();

    println!("{query}");
}

    ```sql
    SELECT 
    (SELECT COUNT(*) FROM posts P WHERE P.user_id = U.id) AS total_post_count  
    FROM users U
    WHERE U.id = '1'
    ```

依赖关系

~260–710KB
~17K SLoC