76个稳定版本 (24个主要版本)

25.0.1 2024年5月21日
25.0.0 2024年3月18日
24.0.0 2023年5月17日
23.0.1 2022年12月10日
0.0.2 2014年11月27日

#204数据库接口

Download history 7353/week @ 2024-04-29 7579/week @ 2024-05-06 6889/week @ 2024-05-13 7713/week @ 2024-05-20 5974/week @ 2024-05-27 6410/week @ 2024-06-03 7596/week @ 2024-06-10 7915/week @ 2024-06-17 6956/week @ 2024-06-24 6152/week @ 2024-07-01 5624/week @ 2024-07-08 7091/week @ 2024-07-15 7218/week @ 2024-07-22 8932/week @ 2024-07-29 6887/week @ 2024-08-05 8619/week @ 2024-08-12

每月下载量32,174
用于 149 个Crate (直接使用110个)

MIT/Apache

400KB
7.5K SLoC

Gitter

Crates.io Build Status

mysql

此crate提供

  • 纯Rust实现的MySQL数据库驱动;
  • 连接池。

特性

  • 支持macOS、Windows和Linux;
  • 通过 nativetlsrustls 支持TLS(见SSL支持部分);
  • 支持MySQL文本协议,即支持简单的文本查询和文本结果集;
  • 支持MySQL二进制协议,即支持预处理语句和二进制结果集;
  • 支持多结果集;
  • 支持预处理语句的命名参数(见命名参数部分);
  • 支持每个连接的预处理语句缓存(见语句缓存部分);
  • 支持缓冲池(见缓冲池部分);
  • 支持大于2^24的MySQL数据包;
  • 支持Unix套接字和Windows命名管道;
  • 支持自定义LOCAL INFILE处理器;
  • 支持MySQL协议压缩;
  • 支持认证插件
    • mysql_native_password - 用于MySQL版本v8之前;
    • caching_sha2_password - 用于MySQL版本v8及以上;
    • mysql_clear_password - 可选(见Opts::get_enable_cleartext_plugin)。

安装

将所需版本的crate放入您的Cargo.toml文件的dependencies部分。

[dependencies]
mysql = "*"

示例

use mysql::*;
use mysql::prelude::*;

#[derive(Debug, PartialEq, Eq)]
struct Payment {
    customer_id: i32,
    amount: i32,
    account_name: Option<String>,
}


fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let url = "mysql://root:password@localhost:3307/db_name";
    # Opts::try_from(url)?;
    # let url = get_opts();
    let pool = Pool::new(url)?;

    let mut conn = pool.get_conn()?;

    // Let's create a table for payments.
    conn.query_drop(
        r"CREATE TEMPORARY TABLE payment (
            customer_id int not null,
            amount int not null,
            account_name text
        )")?;

    let payments = vec![
        Payment { customer_id: 1, amount: 2, account_name: None },
        Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
        Payment { customer_id: 5, amount: 6, account_name: None },
        Payment { customer_id: 7, amount: 8, account_name: None },
        Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
    ];

    // Now let's insert payments to the database
    conn.exec_batch(
        r"INSERT INTO payment (customer_id, amount, account_name)
          VALUES (:customer_id, :amount, :account_name)",
        payments.iter().map(|p| params! {
            "customer_id" => p.customer_id,
            "amount" => p.amount,
            "account_name" => &p.account_name,
        })
    )?;

    // Let's select payments from database. Type inference should do the trick here.
    let selected_payments = conn
        .query_map(
            "SELECT customer_id, amount, account_name from payment",
            |(customer_id, amount, account_name)| {
                Payment { customer_id, amount, account_name }
            },
        )?;

    // Let's make sure, that `payments` equals to `selected_payments`.
    // Mysql gives no guaranties on order of returned rows
    // without `ORDER BY`, so assume we are lucky.
    assert_eq!(payments, selected_payments);
    println!("Yay!");

    Ok(())
}

Crate特性

  • 特性集

    • 默认 – 包括默认的mysql_common特性,native-tlsbuffer-poolflate2/zlibderive
    • default-rustls - 与 default 相同,但使用 rustls-tls 代替 native-tls,以及使用 flate2/rust_backend 代替 flate2/zlib
    • minimal - 包含 flate2/zlib
  • crate 的功能

    • native-tls(默认启用)- 指定 native-tls 作为 TLS 后端(见 SSL 支持 部分)
    • rustls-tls(默认禁用)- 指定 rustls 作为 TLS 后端(见 SSL 支持 部分)
    • buffer-pool(默认启用)- 启用缓冲池(见 缓冲池 部分)
    • derive(默认启用)- 在 prelude 下重新导出 derive 宏
  • 默认启用的外部功能

    • 对于 flate2 crate(请参阅 flate2 crate 文档以获取可用功能)

      • flate2/zlib(必需)- 默认选择 zlib 后端。
    • 对于 mysql_common crate(请参阅 mysql_common crate 文档以获取可用功能)

      • mysql_common/bigdecimal03 – 默认启用 bigdecimal03
      • mysql_common/rust_decimal – 默认启用 rust_decimal
      • mysql_common/time03 – 默认启用 time03
      • mysql_common/uuid – 默认启用 uuid
      • mysql_common/frunk – 默认启用 frunk

请注意,如果您使用 default-features = false,则需要重新启用所需的功能

[dependencies]
# Lets say that we want to use the `rustls-tls` feature:
mysql = { version = "*", default-features = false, features = ["minimal", "rustls-tls"] }
# Previous line disables default mysql features,
# so now we need to choose desired mysql_common features:
mysql_common = { version = "*", default-features = false, features = ["bigdecimal03", "time03", "uuid"]}

API 文档

请参阅 crate 文档

基本结构

Opts

此结构包含服务器主机名、客户端用户名/密码和其他设置,用于控制客户端行为。

基于 URL 的连接字符串

请注意,您可以使用基于 URL 的连接字符串作为 Opts 实例的来源。URL 方案必须是 mysql。主机、端口、凭证以及查询参数应按照 RFC 3986 给出。

示例

let _ = Opts::from_url("mysql://127.0.0.1/some_db")?;
let _ = Opts::from_url("mysql://[::1]/some_db")?;
let _ = Opts::from_url("mysql://user:pass%[email protected]:3307/some_db?")?;

支持的 URL 参数(有关每个字段的含义,请参阅创建 API 文档中 Opts 结构的文档)

  • user: string – MySql 客户端用户名
  • password: string – MySql 客户端密码;
  • db_name: string – MySql 数据库名;
  • host: Host – MySql 服务器主机名/ip;
  • port: u16 – MySql 服务器端口;
  • pool_min: usize – 见 PoolConstraints::min
  • pool_max: usize – 见 PoolConstraints::max
  • prefer_socket: true | false - 请参阅Opts::get_prefer_socket;
  • tcp_keepalive_time_ms: u32 - 定义了结构体 Optstcp_keepalive_time 字段的值(以毫秒为单位);
  • tcp_keepalive_probe_interval_secs: u32 - 定义了结构体 Optstcp_keepalive_probe_interval_secs 字段的值;
  • tcp_keepalive_probe_count: u32 - 定义了结构体 Optstcp_keepalive_probe_count 字段的值;
  • tcp_connect_timeout_ms: u64 - 定义了结构体 Optstcp_connect_timeout 字段的值(以毫秒为单位);
  • tcp_user_timeout_ms - 定义了结构体 Optstcp_user_timeout 字段的值(以毫秒为单位);
  • stmt_cache_size: u32 - 定义了结构体 Opts 中相同字段的值;
  • enable_cleartext_plugin – 请参阅Opts::get_enable_cleartext_plugin
  • secure_auth – 请参阅Opts::get_secure_auth
  • reset_connection – 请参阅PoolOpts::reset_connection
  • check_health – 请参阅PoolOpts::check_health
  • compress - 定义了结构体 Opts 中相同字段的值。支持值有
    • true - 启用默认压缩级别的压缩;
    • fast - 启用“快速”压缩级别的压缩;
    • best - 启用“最佳”压缩级别的压缩;
    • 1..9 - 启用指定压缩级别的压缩。
  • socket - UNIX上的套接字路径,或在Windows上的管道名称。

OptsBuilder

它是 Opts 结构体的便捷构建器。它为 Opts 结构体的字段定义了设置器。

let opts = OptsBuilder::new()
    .user(Some("foo"))
    .db_name(Some("bar"));
let _ = Conn::new(opts)?;

Conn

此结构体代表一个活动的 MySql 连接。它还持有语句缓存和最后结果集的元数据。

Conn 的析构函数将优雅地将其从服务器断开连接。

Transaction

它是围绕一个例程的简单包装,该例程以 START TRANSACTION 开始,并以 COMMITROLLBACK 结束。

use mysql::*;
use mysql::prelude::*;

let pool = Pool::new(get_opts())?;
let mut conn = pool.get_conn()?;

let mut tx = conn.start_transaction(TxOpts::default())?;
tx.query_drop("CREATE TEMPORARY TABLE tmp (TEXT a)")?;
tx.exec_drop("INSERT INTO tmp (a) VALUES (?)", ("foo",))?;
let val: Option<String> = tx.query_first("SELECT a from tmp")?;
assert_eq!(val.unwrap(), "foo");
// Note, that transaction will be rolled back implicitly on Drop, if not committed.
tx.rollback();

let val: Option<String> = conn.query_first("SELECT a from tmp")?;
assert_eq!(val, None);

Pool

它是对连接池的引用,可以被克隆并在线程之间共享。

use mysql::*;
use mysql::prelude::*;

use std::thread::spawn;

let pool = Pool::new(get_opts())?;

let handles = (0..4).map(|i| {
    spawn({
        let pool = pool.clone();
        move || {
            let mut conn = pool.get_conn()?;
            conn.exec_first::<u32, _, _>("SELECT ? * 10", (i,))
                .map(Option::unwrap)
        }
    })
});

let result: Result<Vec<u32>> = handles.map(|handle| handle.join().unwrap()).collect();

assert_eq!(result.unwrap(), vec![0, 10, 20, 30]);

Statement

语句实际上只是一个标识符与语句元数据的组合,即关于其参数和列的信息。在内部,Statement结构还包含支持命名参数所需的其他数据(见下文)。

use mysql::*;
use mysql::prelude::*;

let pool = Pool::new(get_opts())?;
let mut conn = pool.get_conn()?;

let stmt = conn.prep("DO ?")?;

// The prepared statement will return no columns.
assert!(stmt.columns().is_empty());

// The prepared statement have one parameter.
let param = stmt.params().get(0).unwrap();
assert_eq!(param.schema_str(), "");
assert_eq!(param.table_str(), "");
assert_eq!(param.name_str(), "?");

此枚举表示MySQL单元格的原始值。库提供通过以下描述的FromValue特质在Value和不同的Rust类型之间的转换。

FromValue特质

此特质从mysql_common创建中重新导出。请参阅其crate文档以获取支持的转换列表。

特质提供两种转换方式

  • from_value(Value) -> T - 方便,但会抛出恐慌的转换。

    注意,对于Value的任何变体,都存在一个完全涵盖其域的类型,即对于Value的任何变体,都存在T: FromValue,使得from_value永远不会恐慌。这意味着,如果您的数据库模式已知,那么可以编写只使用from_value的应用程序,而无需担心运行时恐慌。

  • from_value_opt(Value) -> Option<T> - 非抛出恐慌,但不太方便的转换。

    此函数在源数据库模式未知的情况下进行转换试探非常有用。

use mysql::*;
use mysql::prelude::*;

let via_test_protocol: u32 = from_value(Value::Bytes(b"65536".to_vec()));
let via_bin_protocol: u32 = from_value(Value::UInt(65536));
assert_eq!(via_test_protocol, via_bin_protocol);

let unknown_val = // ...

// Maybe it is a float?
let unknown_val = match from_value_opt::<f64>(unknown_val) {
    Ok(float) => {
        println!("A float value: {}", float);
        return Ok(());
    }
    Err(FromValueError(unknown_val)) => unknown_val,
};

// Or a string?
let unknown_val = match from_value_opt::<String>(unknown_val) {
    Ok(string) => {
        println!("A string value: {}", string);
        return Ok(());
    }
    Err(FromValueError(unknown_val)) => unknown_val,
};

// Screw this, I'll simply match on it
match unknown_val {
    val @ Value::NULL => {
        println!("An empty value: {:?}", from_value::<Option<u8>>(val))
    },
    val @ Value::Bytes(..) => {
        // It's non-utf8 bytes, since we already tried to convert it to String
        println!("Bytes: {:?}", from_value::<Vec<u8>>(val))
    }
    val @ Value::Int(..) => {
        println!("A signed integer: {}", from_value::<i64>(val))
    }
    val @ Value::UInt(..) => {
        println!("An unsigned integer: {}", from_value::<u64>(val))
    }
    Value::Float(..) => unreachable!("already tried"),
    val @ Value::Double(..) => {
        println!("A double precision float value: {}", from_value::<f64>(val))
    }
    val @ Value::Date(..) => {
        use time::PrimitiveDateTime;
        println!("A date value: {}", from_value::<PrimitiveDateTime>(val))
    }
    val @ Value::Time(..) => {
        use std::time::Duration;
        println!("A time value: {:?}", from_value::<Duration>(val))
    }
}

内部,RowValue的向量,它还允许通过列名/偏移量进行索引,并存储行元数据。库提供通过以下描述的FromRow特质在Row和Rust类型序列之间的转换。

FromRow特质

此特质从mysql_common创建中重新导出。请参阅其crate文档以获取支持的转换列表。

这种转换基于FromValue,因此有两种类似的口味

  • from_row(Row) -> T - 与from_value相同,但用于行;
  • from_row_opt(Row) -> Option<T> - 与from_value_opt相同,但用于行。

Queryable特质提供基于此特质的查询结果行的隐式转换。

use mysql::*;
use mysql::prelude::*;

let mut conn = Conn::new(get_opts())?;

// Single-column row can be converted to a singular value:
let val: Option<String> = conn.query_first("SELECT 'foo'")?;
assert_eq!(val.unwrap(), "foo");

// Example of a mutli-column row conversion to an inferred type:
let row = conn.query_first("SELECT 255, 256")?;
assert_eq!(row, Some((255u8, 256u16)));

// The FromRow trait does not support to-tuple conversion for rows with more than 12 columns,
// but you can do this by hand using row indexing or `Row::take` method:
let row: Row = conn.exec_first("select 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12", ())?.unwrap();
for i in 0..row.len() {
    assert_eq!(row[i], Value::Int(i as i64));
}

// Another way to handle wide rows is to use HList (requires `mysql_common/frunk` feature)
use frunk::{HList, hlist, hlist_pat};
let query = "select 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15";
type RowType = HList!(u8, u16, u32, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
let first_three_columns = conn.query_map(query, |row: RowType| {
    // do something with the row (see the `frunk` crate documentation)
    let hlist_pat![c1, c2, c3, ...] = row;
    (c1, c2, c3)
});
assert_eq!(first_three_columns.unwrap(), vec![(0_u8, 1_u16, 2_u32)]);

// Some unknown row
let row: Row = conn.query_first(
    // ...
    # "SELECT 255, Null",
)?.unwrap();

for column in row.columns_ref() {
    // Cells in a row can be indexed by numeric index or by column name
    let column_value = &row[column.name_str().as_ref()];

    println!(
        "Column {} of type {:?} with value {:?}",
        column.name_str(),
        column.column_type(),
        column_value,
    );
}

参数

表示预编译语句的参数,但此类型不会直接出现在您的代码中,因为二进制协议API将请求T: Into<Params>,其中实现了Into<Params>

  • 对于Into<Value>类型的元组,最多可到12个参数;

    注意:单个元组需要一个额外的逗号,例如 ("foo",);

  • 对于当你的语句包含超过12个参数的情况,使用IntoIterator<Item: Into<Value>>

  • 对于命名参数的表示(下面将描述的params!宏的值)。

use mysql::*;
use mysql::prelude::*;

let mut conn = Conn::new(get_opts())?;

// Singular tuple requires extra comma:
let row: Option<u8> = conn.exec_first("SELECT ?", (0,))?;
assert_eq!(row.unwrap(), 0);

// More than 12 parameters:
let row: Option<u8> = conn.exec_first(
    "SELECT CONVERT(? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ?, UNSIGNED)",
    (0..16).collect::<Vec<_>>(),
)?;
assert_eq!(row.unwrap(), 120);

注意:请参考mysql_common crate文档以获取实现Into<Value>的类型列表。

SerializedDeserialized

用于当你需要为JSON单元格提供一个值,或者当你需要将JSON单元格解析为结构体的情况的包装结构。

use mysql::*;
use mysql::prelude::*;

/// Serializable structure.
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Example {
    foo: u32,
}

// Value::from for Serialized will emit json string.
let value = Value::from(Serialized(Example { foo: 42 }));
assert_eq!(value, Value::Bytes(br#"{"foo":42}"#.to_vec()));

// from_value for Deserialized will parse json string.
let structure: Deserialized<Example> = from_value(value);
assert_eq!(structure, Deserialized(Example { foo: 42 }));

QueryResult

它是查询结果行的迭代器,支持多结果集。它适用于需要在整个结果集迭代过程中进行完全控制的场景。对于其他情况,Queryable提供了一系列方法,这些方法将立即消耗第一个结果集并丢弃其他所有内容。

此迭代器是惰性的,因此它不会在迭代之前从服务器读取结果。MySql协议是严格顺序的,所以Conn将可变借用直到结果完全消耗完毕(请参阅QueryResult::iter文档)。

use mysql::*;
use mysql::prelude::*;

let mut conn = Conn::new(get_opts())?;

// This query will emit two result sets.
let mut result = conn.query_iter("SELECT 1, 2; SELECT 3, 3.14;")?;

let mut sets = 0;
while let Some(result_set) = result.iter() {
    sets += 1;

    println!("Result set columns: {:?}", result_set.columns());
    println!(
        "Result set meta: {}, {:?}, {} {}",
        result_set.affected_rows(),
        result_set.last_insert_id(),
        result_set.warnings(),
        result_set.info_str(),
    );

    for row in result_set {
        match sets {
            1 => {
                // First result set will contain two numbers.
                assert_eq!((1_u8, 2_u8), from_row(row?));
            }
            2 => {
                // Second result set will contain a number and a float.
                assert_eq!((3_u8, 3.14), from_row(row?));
            }
            _ => unreachable!(),
        }
    }
}

assert_eq!(sets, 2);

文本协议

MySql文本协议在Queryable::query*方法集中实现。当你查询没有参数时,它非常有用。

注意:服务器将文本协议结果集中的所有值都编码为字符串,因此from_value转换可能会导致额外的解析成本。

示例

let pool = Pool::new(get_opts())?;
let val = pool.get_conn()?.query_first("SELECT POW(2, 16)")?;

// Text protocol returns bytes even though the result of POW
// is actually a floating point number.
assert_eq!(val, Some(Value::Bytes("65536".as_bytes().to_vec())));

TextQuery特质。

TextQuery特质涵盖了从查询的角度看Queryable::query*方法集,即TextQuery是在给定了适当的连接后可以执行的操作。合适的连接包括

  • &Pool
  • Conn
  • PooledConn
  • &mutConn
  • &mutPooledConn
  • &mutTransaction

此特质的独特之处在于,你可以放弃连接,从而产生满足'staticQueryResult

use mysql::*;
use mysql::prelude::*;

fn iter(pool: &Pool) -> Result<impl Iterator<Item=Result<u32>>> {
    let result = "SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3".run(pool)?;
    Ok(result.map(|row| row.map(from_row)))
}

let pool = Pool::new(get_opts())?;

let it = iter(&pool)?;

assert_eq!(it.collect::<Result<Vec<u32>>>()?, vec![1, 2, 3]);

二进制协议和预编译语句。

MySql二进制协议在prepclose和定义在Queryable特质上的exec*方法集中实现。预编译语句是将Rust值传递给MySql服务器的唯一方式。MySql使用?符号作为参数占位符,并且只能在期望单个MySql值的位置使用参数。例如

let pool = Pool::new(get_opts())?;
let val = pool.get_conn()?.exec_first("SELECT POW(?, ?)", (2, 16))?;

assert_eq!(val, Some(Value::Double(65536.0)));

语句

在MySql中,每个预编译语句都属于特定的连接,并且不能在另一个连接上执行。尝试这样做会导致错误。驱动程序不会以任何方式将语句与其连接绑定,但可以查看包含在Statement结构中的连接ID。

let pool = Pool::new(get_opts())?;

let mut conn_1 = pool.get_conn()?;
let mut conn_2 = pool.get_conn()?;

let stmt_1 = conn_1.prep("SELECT ?")?;

// stmt_1 is for the conn_1, ..
assert!(stmt_1.connection_id() == conn_1.connection_id());
assert!(stmt_1.connection_id() != conn_2.connection_id());

// .. so stmt_1 will execute only on conn_1
assert!(conn_1.exec_drop(&stmt_1, ("foo",)).is_ok());
assert!(conn_2.exec_drop(&stmt_1, ("foo",)).is_err());

语句缓存

注意

语句缓存仅适用于

  1. 原始Conn
  2. 对于 PooledConn
描述

Conn 将在客户端管理预编译语句的缓存,因此使用相同语句的后续调用不会导致客户端-服务器往返。每个连接的缓存大小由 Opts 结构中的 stmt_cache_size 字段确定。超出此边界的语句将按 LRU 顺序关闭。

如果 stmt_cache_size 为零,则完全禁用语句缓存。

注意事项

  • 禁用语句缓存意味着您必须自己使用 Conn::close 关闭语句,否则它们会耗尽服务器限制/资源;

  • 您应该注意 MySql 服务器的 max_prepared_stmt_count 选项。如果活动连接数乘以 stmt_cache_size 的值大于该值,则在准备另一个语句时可能会收到错误。

命名参数

MySql 本身不支持命名参数,因此在客户端实现。应使用 :name 作为命名参数的占位符语法。命名参数使用以下命名约定

  • 参数名称必须以 _a..z 开头
  • 参数名称可以继续使用 _a..z0..9

命名参数可以在语句中重复,例如 SELECT :foo, :foo 需要一个名为 foo 的命名参数,该参数将在语句执行期间在相应位置重复。

应使用 params! 宏来构建执行参数。

注意:在单个语句中不能混合使用位置参数和命名参数。

示例

let pool = Pool::new(get_opts())?;

let mut conn = pool.get_conn()?;
let stmt = conn.prep("SELECT :foo, :bar, :foo")?;

let foo = 42;

let val_13 = conn.exec_first(&stmt, params! { "foo" => 13, "bar" => foo })?.unwrap();
// Short syntax is available when param name is the same as variable name:
let val_42 = conn.exec_first(&stmt, params! { foo, "bar" => 13 })?.unwrap();

assert_eq!((foo, 13, foo), val_42);
assert_eq!((13, foo, 13), val_13);

缓冲池

该框架使用全局无锁缓冲池用于 I/O 和数据序列化/反序列化,有助于避免基本场景下的分配。您可以使用以下环境变量来控制其特征

  • RUST_MYSQL_BUFFER_POOL_CAP(默认为 128)- 控制池容量。如果池已满,则丢弃的缓冲区将被立即分配。将其设置为 0 以在运行时禁用池。

  • RUST_MYSQL_BUFFER_SIZE_CAP(默认为 4MiB)- 控制存储在池中的缓冲区的最大容量。当缓冲区返回池时,丢弃的缓冲区容量将缩小到此值。

要完全禁用池(例如您正在使用jemalloc),请从默认crate功能集中移除buffer-pool功能(请参阅Crate Features部分)。

BinQueryBatchQuery特质。

BinQueryBatchQuery特质涵盖了从查询的角度来看的Queryable::exec*方法集合,即BinQuery是某种在给定合适的连接时可以执行的操作(请参阅TextQuery部分以获取合适连接的列表)。

TextQuery类似,您可以提供连接并获取满足'staticQueryResult

BinQuery用于预编译语句,而预编译语句需要一组参数,因此BinQuery是为QueryWithParams结构实现的,该结构可以通过使用WithParams特质来获取。

示例

use mysql::*;
use mysql::prelude::*;

let pool = Pool::new(get_opts())?;

let result: Option<(u8, u8, u8)> = "SELECT ?, ?, ?"
    .with((1, 2, 3)) // <- WithParams::with will construct an instance of QueryWithParams
    .first(&pool)?;  // <- QueryWithParams is executed on the given pool

assert_eq!(result.unwrap(), (1, 2, 3));

BatchQuery特质是批量语句执行的辅助工具。它在QueryWithParams上实现,其中参数是参数的迭代器。

use mysql::*;
use mysql::prelude::*;

let pool = Pool::new(get_opts())?;
let mut conn = pool.get_conn()?;

"CREATE TEMPORARY TABLE batch (x INT)".run(&mut conn)?;
"INSERT INTO batch (x) VALUES (?)"
    .with((0..3).map(|x| (x,))) // <- QueryWithParams constructed with an iterator
    .batch(&mut conn)?;         // <- batch execution is preformed here

let result: Vec<u8> = "SELECT x FROM batch".fetch(conn)?;

assert_eq!(result, vec![0, 1, 2]);

Queryable

Queryable特质定义了ConnPooledConnTransaction的共同方法。基本方法集合包括:

  • query_iter - 执行文本查询并获取QueryResult的基本方法;
  • prep - 预编译语句的基本方法;
  • exec_iter - 执行语句并获取QueryResult的基本方法;
  • close - 关闭语句的基本方法;

该特质还定义了一系列基于基本方法的辅助方法。这些方法将仅消耗第一个结果集,其他结果集将被丢弃

  • {query|exec} - 将结果收集到Vec<T: FromRow>中;
  • {query|exec}_first - 获取第一个T: FromRow,如果有的话;
  • {query|exec}_map - 将每个T: FromRow映射到某个U
  • {query|exec}_fold - 将T: FromRow的集合折叠为单个值;
  • {query|exec}_drop - 立即丢弃结果。

该特质还定义了exec_batch函数,它是批量语句执行的辅助工具。

SSL支持

SSL支持有两种形式

  1. 基于 native-tls – 这是默认选项,通常无需担心问题(参见 native-tls 仓库特性)。

  2. 基于 rustls – 使用 Rust 编写的 TLS 后端。请使用 rustls-tls 仓库特性来启用它(参见仓库特性部分)。

    请注意关于 rustls 的几点

    • 如果您尝试通过 IP 地址连接到服务器,它将失败;需要主机名;
    • 它很可能在 Windows 上无法正常工作,至少在使用默认服务器证书的情况下,这些证书是由 MySQL 安装程序生成的。

更新日志

在此可找到

许可证

许可协议为以下之一

任选其一。

贡献

除非您明确声明,否则您提交的任何贡献,只要它有意提交以包含在作品中,根据 Apache-2.0 许可证定义,都应按上述方式双许可,无需任何额外条款或条件。

依赖关系

~13–29MB
~491K SLoC