From 5c8ac42e8ab5241261a09ca987a16d568f140ef1 Mon Sep 17 00:00:00 2001 From: rsgl Date: Fri, 15 Nov 2024 23:32:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20r2d2=20=E5=92=8C=20r2d2=5F?= =?UTF-8?q?mysql=20=E4=BE=9D=E8=B5=96=EF=BC=8C=E9=87=8D=E6=9E=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E8=BF=9E=E6=8E=A5=E6=B1=A0=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=94=A8=E6=88=B7=E6=9C=8D=E5=8A=A1=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=96=B0=E7=9A=84=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dataSources.xml | 12 ++ .idea/sqldialects.xml | 6 + Cargo.lock | 32 +++++ Cargo.toml | 2 + src/repositories/user_repository.rs | 205 +++++++++++++++------------- src/routes/user_routes.rs | 41 +++--- src/services/user_service.rs | 42 ++++-- src/utils/pool.rs | 28 +++- 8 files changed, 239 insertions(+), 129 deletions(-) create mode 100644 .idea/dataSources.xml create mode 100644 .idea/sqldialects.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..892e055 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://122.152.201.90:9912/test_server + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..56782ca --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index bb0c478..75f3b69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,6 +698,8 @@ dependencies = [ "actix-web", "bcrypt", "mysql", + "r2d2", + "r2d2_mysql", "serde", "serde_derive", "uuid", @@ -1742,6 +1744,27 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_mysql" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93963fe09ca35b0311d089439e944e42a6cb39bf8ea323782ddb31240ba2ae87" +dependencies = [ + "mysql", + "r2d2", +] + [[package]] name = "radium" version = "0.7.0" @@ -1931,6 +1954,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + [[package]] name = "scopeguard" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index 5406498..4682d55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,8 @@ edition = "2021" [dependencies] mysql = "25.0.1" +r2d2 = "0.8.10" +r2d2_mysql = "25.0.0" actix-web = "4" serde = "1.0" serde_derive = "1.0" diff --git a/src/repositories/user_repository.rs b/src/repositories/user_repository.rs index fced02c..3ded52e 100644 --- a/src/repositories/user_repository.rs +++ b/src/repositories/user_repository.rs @@ -1,109 +1,120 @@ use crate::models::user::User; use mysql::params; use mysql::prelude::Queryable; +use r2d2::Pool; +use r2d2_mysql::MySqlConnectionManager; -/** - * 新建用户 - */ -pub fn create_user(conn: &mut mysql::PooledConn, user: &User) -> Result<(), mysql::Error> { - conn.exec_drop( - r"INSERT INTO users (id, name, age, email, password) VALUES (:id, :name, :age, :email, :password)", - params! { - "id" => &user.id, - "name" => &user.name, - "age" => &user.age, - "email" => &user.email, - "password" => &user.password, - }, - ) +pub struct UserRepository<'a> { + pub pool: &'a mut Pool, } -/** - * 删除用户 - */ -pub fn delete_user(conn: &mut mysql::PooledConn, user: &User) -> Result<(), mysql::Error> { - conn.exec_drop( - r"DELETE FROM users WHERE id = :id", - params! { - "id" => &user.id, - }, - ) -} +impl<'a> UserRepository<'a> { + pub fn new(pool: &'a mut Pool) -> UserRepository { + UserRepository { pool } + } -/** - * 更新用户 - */ -pub fn update_user(conn: &mut mysql::PooledConn, user: &User) -> Result<(), mysql::Error> { - conn.exec_drop( - r"UPDATE users SET name = :name, age = :age, email = :email, password = :password WHERE id = :id", - params! { - "id" => &user.id, - "name" => &user.name, - "age" => &user.age, - "email" => &user.email, - "password" => &user.password, - }, - ) -} + /** + * 新建用户 + */ + pub fn create_user(&mut self, user: &User) -> Result<(), mysql::Error> { + let mut conn = self.pool.get().unwrap(); + conn.exec_drop( + r"INSERT INTO users (id, name, age, email, password) VALUES (:id, :name, :age, :email, :password)", + params! { + "id" => &user.id, + "name" => &user.name, + "age" => &user.age, + "email" => &user.email, + "password" => &user.password, + }, + ) + } -/** - * 查询所有用户 - */ -pub fn query_all_user(conn: &mut mysql::PooledConn) -> Result, mysql::Error> { - conn.query_map( - "SELECT id, name, age, email, password FROM users", - |(id, name, age, email, password)| User { - id, - name, - age, - email, - password, - }, - ) -} + /** + * 删除用户 + */ + pub fn delete_user(&mut self, user: &User) -> Result<(), mysql::Error> { + let mut conn = self.pool.get().unwrap(); + conn.exec_drop( + r"DELETE FROM users WHERE id = :id", + params! { + "id" => &user.id, + }, + ) + } -/** - * 根据ID查询用户 - */ -pub fn query_user_by_id( - conn: &mut mysql::PooledConn, - id: i32, -) -> Result, mysql::Error> { - let result: Option = conn.exec_first( - "SELECT id, name, age, email, password FROM users WHERE id = :id", - params! { - "id" => id, - }, - )?; - Ok(result) -} + /** + * 更新用户 + */ + pub fn update_user(&mut self, user: &User) -> Result<(), mysql::Error> { + let mut conn = self.pool.get().unwrap(); + conn.exec_drop( + r"UPDATE users SET name = :name, age = :age, email = :email, password = :password WHERE id = :id", + params! { + "id" => &user.id, + "name" => &user.name, + "age" => &user.age, + "email" => &user.email, + "password" => &user.password, + }, + ) + } -/** - * 根据用户名查询用户 - */ -pub fn query_user_by_name( - conn: &mut mysql::PooledConn, - name: &str, -) -> Result, mysql::Error> { - conn.exec_first( - "SELECT id, name, age, email, password FROM users WHERE name = :name", - params! { - "name" => name, - }, - ) -} + /** + * 查询所有用户 + */ -/** - * 根据邮箱查询用户 - */ -pub fn query_user_by_email( - conn: &mut mysql::PooledConn, - email: &str, -) -> Result, mysql::Error> { - conn.exec_first( - "SELECT id, name, age, email, password FROM users WHERE email = :email", - params! { - "email" => email, - }, - ) + pub fn query_all_user(&mut self) -> Result, mysql::Error> { + let mut conn = self.pool.get().unwrap(); + conn.query_map( + "SELECT id, name, age, email, password FROM users", + |(id, name, age, email, password)| User { + id, + name, + age, + email, + password, + }, + ) + } + + /** + * 根据ID查询用户 + */ + pub fn query_user_by_id(&mut self, id: i32) -> Result, mysql::Error> { + let mut conn = self.pool.get().unwrap(); + let result: Option = conn.exec_first( + "SELECT id, name, age, email, password FROM users WHERE id = :id", + params! { + "id" => id, + }, + )?; + Ok(result) + } + + /** + * 根据用户名查询用户 + */ + pub fn query_user_by_name(&mut self, name: &str) -> Result, mysql::Error> { + let mut conn = self.pool.get().unwrap(); + conn.exec_first( + "SELECT id, name, age, email, password FROM users WHERE name = :name", + params! { + "name" => name, + }, + ) + } + + /** + * 根据邮箱查询用户 + */ + pub fn query_user_by_email(&mut self, email: &str) -> Result, mysql::Error> { + let mut conn = self.pool.get().unwrap(); + conn.exec_first( + "SELECT id, name, age, email, password FROM users WHERE email = :email", + params! { + "email" => email, + }, + ) + } } diff --git a/src/routes/user_routes.rs b/src/routes/user_routes.rs index f844a5a..f73a315 100644 --- a/src/routes/user_routes.rs +++ b/src/routes/user_routes.rs @@ -2,6 +2,7 @@ use crate::models::user::User; use crate::services::user_service; use crate::utils::pool; use actix_web::{get, post, web, HttpResponse, Responder}; +use serde::Deserialize; pub(crate) fn register(config: &mut web::ServiceConfig) { config.service(register_user); @@ -13,10 +14,18 @@ pub(crate) fn register(config: &mut web::ServiceConfig) { config.service(delete_user); } +#[derive(Deserialize)] +struct RegisterUser { + name: String, + age: i32, + email: String, + password: String, +} + #[post("/user/register")] -async fn register_user(user: web::Json) -> impl Responder { - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); +async fn register_user(user: web::Json) -> impl Responder { + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); let mut new_user = User { id: 0, name: user.name.clone(), @@ -25,13 +34,13 @@ async fn register_user(user: web::Json) -> impl Responder { password: user.password.clone(), }; user_service::create_user(&mut conn, &mut new_user).unwrap(); - HttpResponse::Ok().json("User registered successfully") + HttpResponse::Ok().json("SUCCESS") } #[get("/user/query_all_user")] async fn query_all_user() -> impl Responder { - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); let users = user_service::query_all_user(&mut conn).unwrap(); HttpResponse::Ok().json(users) } @@ -39,8 +48,8 @@ async fn query_all_user() -> impl Responder { #[get("/user/{id}")] async fn query_user_by_id(path: web::Path) -> impl Responder { let id = path.into_inner(); - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); match user_service::query_user_by_id(&mut conn, id) { Ok(user) => HttpResponse::Ok().json(user), @@ -50,8 +59,8 @@ async fn query_user_by_id(path: web::Path) -> impl Responder { #[get("/user/{email}")] async fn query_user_by_email(path: web::Path) -> impl Responder { - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); let email = path.into_inner(); match user_service::query_user_by_email(&mut conn, email.as_str()) { Ok(user) => HttpResponse::Ok().json(user), @@ -61,8 +70,8 @@ async fn query_user_by_email(path: web::Path) -> impl Responder { #[get("/user/{name}")] async fn query_user_by_name(path: web::Path) -> impl Responder { - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); let name = path.into_inner(); match user_service::query_user_by_name(&mut conn, name.as_str()) { Ok(user) => HttpResponse::Ok().json(user), @@ -72,16 +81,16 @@ async fn query_user_by_name(path: web::Path) -> impl Responder { #[post("/user/update")] async fn update_user(user: web::Json) -> impl Responder { - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); user_service::update_user(&mut conn, &user).unwrap(); HttpResponse::Ok().json("User updated successfully") } #[post("/user/delete")] async fn delete_user(user: web::Json) -> impl Responder { - let pool = pool::get_db_pool(); - let mut conn = pool.get_conn().unwrap(); + let pool = pool::get_database_pool().unwrap(); + let mut conn = pool.get().unwrap(); user_service::delete_user(&mut conn, &user).unwrap(); HttpResponse::Ok().json("User deleted successfully") } diff --git a/src/services/user_service.rs b/src/services/user_service.rs index 77ac1af..508d671 100644 --- a/src/services/user_service.rs +++ b/src/services/user_service.rs @@ -2,39 +2,58 @@ use crate::models::user::User; use crate::repositories::user_repository; use bcrypt::{hash, DEFAULT_COST}; use mysql; -use mysql::PooledConn; +use r2d2::PooledConnection; +use r2d2_mysql::{MySqlConnectionManager, mysql::PooledConn}; /** * 新建用户 */ -pub fn create_user(conn: &mut PooledConn, user: &mut User) -> Result<(), mysql::Error> { - user.password = hash(&user.password, DEFAULT_COST).unwrap(); - user_repository::create_user(conn, user) +pub fn create_user( + conn: &mut PooledConn, + user: &mut User, +) -> Result<(), mysql::Error> { + let mut new_user = User { + password: hash(&user.password, DEFAULT_COST).unwrap(), + ..user.clone() + }; + + user_repository::create_user(conn, &mut new_user) } /** * 查询所有用户 */ -pub fn query_all_user(conn: &mut PooledConn) -> Result, mysql::Error> { +pub fn query_all_user( + conn: &mut PooledConnection, +) -> Result, mysql::Error> { user_repository::query_all_user(conn) } -pub fn query_user_by_id(conn: &mut PooledConn, id: i32) -> Result, mysql::Error> { +pub fn query_user_by_id( + conn: &mut PooledConnection, + id: i32, +) -> Result, mysql::Error> { user_repository::query_user_by_id(conn, id) } pub fn query_user_by_email( - conn: &mut PooledConn, + conn: &mut PooledConnection, email: &str, ) -> Result, mysql::Error> { user_repository::query_user_by_email(conn, email) } -pub fn query_user_by_name(conn: &mut PooledConn, name: &str) -> Result, mysql::Error> { +pub fn query_user_by_name( + conn: &mut PooledConnection, + name: &str, +) -> Result, mysql::Error> { user_repository::query_user_by_name(conn, name) } -pub fn update_user(conn: &mut PooledConn, user: &User) -> Result<(), mysql::Error> { +pub fn update_user( + conn: &mut PooledConnection, + user: &User, +) -> Result<(), mysql::Error> { if user_repository::query_user_by_id(conn, user.id)?.is_none() { return Err(mysql::Error::MySqlError(mysql::MySqlError { code: 1062, @@ -46,7 +65,10 @@ pub fn update_user(conn: &mut PooledConn, user: &User) -> Result<(), mysql::Erro user_repository::update_user(conn, user) } -pub fn delete_user(conn: &mut PooledConn, user: &User) -> Result<(), mysql::Error> { +pub fn delete_user( + conn: &mut PooledConnection, + user: &User, +) -> Result<(), mysql::Error> { if user_repository::query_user_by_id(conn, user.id)?.is_none() { return Err(mysql::Error::MySqlError(mysql::MySqlError { code: 1062, diff --git a/src/utils/pool.rs b/src/utils/pool.rs index 821f2f4..4098383 100644 --- a/src/utils/pool.rs +++ b/src/utils/pool.rs @@ -1,9 +1,25 @@ -use mysql::*; +// use mysql::*; -/** - * 获取数据库连接池 - */ -pub fn get_db_pool() -> Pool { +// /** +// * 获取数据库连接池 +// */ +// pub fn get_database_pool().unwrap -> Pool { +// let url = "mysql://root:0andrx@122.152.201.90:9912/test_server"; +// Pool::new(url).expect("TODO: panic message") +// } + +use r2d2::Pool; +use r2d2_mysql::MySqlConnectionManager; + +pub fn get_database_pool() -> Result, r2d2::Error> { let url = "mysql://root:0andrx@122.152.201.90:9912/test_server"; - Pool::new(url).expect("TODO: panic message") + let opts = + r2d2_mysql::mysql::OptsBuilder::from_opts(r2d2_mysql::mysql::Opts::from_url(url).unwrap()); + let manager = r2d2_mysql::MySqlConnectionManager::new(opts); + let pool = Pool::builder() + .max_size(10) + .min_idle(Some(5)) + .build(manager) + .unwrap(); + Ok(pool) }