#Using Databases
#Diesel
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, Pool, PoolError, PooledConnection};
use once_cell::sync::OnceCell;
use salvo::prelude::*;
const DB_URL: &str = "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world";
type PgPool = Pool<ConnectionManager<PgConnection>>;
static DB_POOL: OnceCell<PgPool> = OnceCell::new();
fn connect() -> Result<PooledConnection<ConnectionManager<PgConnection>>, PoolError> {
DB_POOL.get().unwrap().get()
}
fn build_pool(database_url: &str, size: u32) -> Result<PgPool, PoolError> {
let manager = ConnectionManager::<PgConnection>::new(database_url);
diesel::r2d2::Pool::builder()
.max_size(size)
.min_idle(Some(size))
.test_on_check_out(false)
.idle_timeout(None)
.max_lifetime(None)
.build(manager)
}
fn main() {
DB_POOL
.set(build_pool(&DB_URL, 10).expect(&format!("Error connecting to {}", &DB_URL)))
.ok();
}
#[handler]
async fn show_article(req: &mut Request, res: &mut Response) -> Result<(), Error> {
let id: i64 = req.param::<i64>("id").unwrap_or_default();
let conn = connect()?;
let article = articles::table.find(id).first::<Article>(&conn)?;
res.render(Json(row));
Ok(())
}#Sqlx
use std::sync::OnceLock;
use salvo::prelude::*;
use serde::Serialize;
use sqlx::{FromRow, PgPool};
// Global PostgreSQL connection pool instance
static POSTGRES: OnceLock<PgPool> = OnceLock::new();
// Helper function to get the PostgreSQL connection pool
#[inline]
pub fn get_postgres() -> &'static PgPool {
POSTGRES.get().unwrap()
}
// User model representing the database table structure
// Implements FromRow for SQL query results and Serialize for JSON responses
#[derive(FromRow, Serialize, Debug)]
pub struct User {
pub id: i64,
pub username: String,
pub password: String,
}
// Handler for retrieving a user by ID from the database
#[handler]
pub async fn get_user(req: &mut Request, res: &mut Response) {
// Extract user ID from query parameters
let uid = req.query::<i64>("uid").unwrap();
// Execute SQL query to fetch user by ID
let data = sqlx::query_as::<_, User>("select * from users where id = $1")
.bind(uid)
.fetch_one(get_postgres())
.await
.unwrap();
// Return user data as JSON response
res.render(serde_json::to_string(&data).unwrap());
}
#[tokio::main]
async fn main() {
// Initialize logging system
tracing_subscriber::fmt().init();
// Configure PostgreSQL connection
let postgres_uri = "postgres://postgres:password@localhost/test";
// Create and initialize connection pool
let pool = PgPool::connect(postgres_uri).await.unwrap();
// Store pool in global state
POSTGRES.set(pool).unwrap();
// Configure router with user endpoint:
// - GET /users?uid={id} : Get user by ID
let router = Router::with_path("users").get(get_user);
// Start server on port 8698
let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
Server::new(acceptor).serve(router).await;
}
[package]
name = "example-db-postgres-sqlx"
version.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
[dependencies]
salvo = { workspace = true }
tokio = { workspace = true, features = ["macros"] }
tracing.workspace = true
tracing-subscriber.workspace = true
sqlx = { workspace = true, features = ["runtime-tokio-native-tls", "postgres"] }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
#rbatis
#[macro_use]
extern crate rbatis;
extern crate rbdc;
use std::sync::LazyLock;
use rbatis::RBatis;
use rbdc_mysql::driver::MysqlDriver;
use salvo::prelude::*;
use serde::{Deserialize, Serialize};
// Global RBatis instance for database operations
pub static RB: LazyLock<RBatis> = LazyLock::new(RBatis::new);
// User model representing the database table structure
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct User {
pub id: i64,
pub username: String,
pub password: String,
}
// Implement select query for User model
// Generates SQL: SELECT * FROM user WHERE id = #{id} LIMIT 1
impl_select!(User{select_by_id(id:String) -> Option => "`where id = #{id} limit 1`"});
// Handler for retrieving a user by ID from the database
#[handler]
pub async fn get_user(req: &mut Request, res: &mut Response) {
// Extract user ID from query parameters
let uid = req.query::<i64>("uid").unwrap();
// Execute select query and get user data
let data = User::select_by_id(&*RB, uid.to_string()).await.unwrap();
println!("{data:?}");
// Return user data as JSON response
res.render(serde_json::to_string(&data).unwrap());
}
#[tokio::main]
async fn main() {
// Initialize logging system
tracing_subscriber::fmt().init();
// Configure MySQL connection
let mysql_uri = "mysql://root:123456@localhost/test";
// Initialize RBatis with MySQL driver and connection URI
RB.init(MysqlDriver {}, mysql_uri).unwrap();
// Configure router with user endpoint:
// - GET /users?uid={id} : Get user by ID
let router = Router::with_path("users").get(get_user);
// Start server on port 8698
let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
Server::new(acceptor).serve(router).await;
}
[package]
name = "example-db-mysql-rbatis"
version.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
[dependencies]
async-std = { workspace = true }
rbatis = { workspace = true }
rbdc = { workspace = true }
rbdc-mysql = { workspace = true }
rbs = { workspace = true }
salvo = { workspace = true }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["macros"] }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
serde_json = { workspace = true }
#SeaORM
SeaORM is an asynchronous, dynamic ORM that provides robust relational database support, including entity relationships, a migration system, and a comprehensive type-safe query builder. It is well-suited for medium to large-scale projects requiring a full-featured ORM.
#Tokio ORM (Toasty)
Toasty is an ORM developed by the Tokio team, currently under active development. It focuses on providing a tightly integrated ORM solution for the Tokio ecosystem. It may be suitable for projects that rely on Tokio and are open to adopting emerging technologies.
#SurrealDB Rust SDK
The SurrealDB Rust SDK provides connectivity to this multi-model database, making it suitable for applications that need to handle graph data, document data, and relational data. It is an excellent choice for projects requiring flexible data models.