因为是复刻Java系的Mybatis,因此框架暂命名 Rbatis。小部分功能还在进行中。github链接https://github.com/rbatis/rbatis


struct Rbatis{pub map:HashMap<String, Data>}pub fn query(&mut self, sql: &str){//......}}lazy_static! {//全局变量static ref RB:Mutex<Rbatis>=Mutex::new(Rbatis::new());}
RB.lock().unwrap().query("select * from table");
use tokio::sync::Mutex;#[derive(Debug)]pub struct SyncMap<T> {pub cell: Mutex<RefCell<HashMap<String, T>>>}impl<T> SyncMap<T> {pub fn new() -> SyncMap<T> {SyncMap {cell: Mutex::new(RefCell::new(HashMap::new()))}}/// put an value,this value will move lifetime into SyncMappub async fn put(&self, key: &str, value: T) {let lock = self.cell.lock().await;let mut b = lock.borrow_mut();b.insert(key.to_string(), value);//函数结尾 lock锁即可释放,因此不管是put还是pop,锁定的时间都是比较小的。而且锁定是依赖tokio运行时调度,而不是线程阻塞}/// pop value,lifetime will move to callerpub async fn pop(&self, key: &str) -> Option<T> {let lock = self.cell.lock().await;let mut b = lock.borrow_mut();return b.remove(key);}}
pub struct Rbatis<'r> { context_tx: SyncMap<Transaction<PoolConnection<MySqlConnection>>>, }impl Rbatis{//这里我们可以看到,使用SyncMap既可以修改context上下文,又不必吧&self改为&mut self。即保证了并发安全和性能pub async fn begin(&self, tx_id: &str) -> Result<u64, rbatis_core::Error> { if tx_id.is_empty() { return Err(rbatis_core::Error::from("[rbatis] tx_id can not be empty")); } let conn = self.get_pool()?.begin().await?; self.context_tx.put(tx_id, conn).await; return Ok(1); }}

fn decode_json<T>(&mut self) -> BoxFuture<Result<T, crate::Error>>where T: DeserializeOwned {Box::pin(async move {let mut arr = vec![];while let Some(row) = self.next().await? as Option<MySqlRow<'_>> {let mut m = serde_json::Map::new();let keys = row.names.keys();for x in keys {let key = x.to_string();let key_str=key.as_str();let v:serde_json::Value = row.json_decode_impl(key_str)?;m.insert(key, v);}arr.push(serde_json::Value::Object(m));}let r = json_decode(arr)?;return Ok(r);})}
let rb = Rbatis::new(MYSQL_URL).await.unwrap();let py = r#"SELECT * FROM biz_activityWHERE delete_flag = #{delete_flag}if name != null:AND name like #{name+'%'}if ids != null:AND id in (trim ',':for item in ids:#{item},)"#;let data: serde_json::Value = rb.py_fetch("", py, &json!({ "delete_flag": 1 })).await.unwrap();println!("{}", data);
- go语言版本(标准库http+GoMybatis) 65 Qps/s- rust语言版本(rbatis+hyper) 132Qps/s
原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。