Rust:连接MySQL
安装MySQL
mysql
此crate提供:
- 纯 rust 中的 MySql 数据库驱动程序
- 连接池
特征:
- macOS、Windows 和 Linux 支持;
- 通过nativetls或rustls支持 TLS (请参阅SSL 支持部分);
- MySql文本协议支持,即支持简单的文本查询和文本结果集;
- MySql二进制协议支持,即支持prepared statements和二进制结果集;
- 支持多结果集;
- 支持准备好的语句的命名参数(参见命名参数部分);
- 准备好的语句的可选每个连接缓存(请参阅语句缓存部分);
- 缓冲池(参见缓冲池部分);
- 支持大于 2^24 的 MySql 数据包;
- 支持 Unix 套接字和 Windows 命名管道;
- 支持自定义 LOCAL INFILE 处理程序;
- 支持MySql协议压缩;
- 支持身份验证插件:
- mysql_native_password - 用于 v8 之前的 MySql;
- cache_sha2_password - 适用于 MySql v8 及更高版本。
添加依赖
将所需版本的crate 放入 Cargo.toml 的依赖项部分,该库托管在crates.io上:
[dependencies]
mysql = "*"
例子
这是crates.io上的一个例子:
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";
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(())
}
部分代码解析
-
Pool::new(url)
:创建并返回一个min = 10
和max = 100
的新连接池 -
pool.get_conn()
:Pool 将通过 Conn::ping 检查连接是否处于活动状态,并在必要时调用 Conn::reset,这个方法在调用成功时将返回一个PooledConn -
conn.query_drop()
:执行文本查询并删除查询结果 -
conn.exec_batch()
:准备给定语句,并使用给定参数迭代器中的每个项目执行它 -
conn.query_map()
:执行文本查询并映射第一个结果集的每一行。