``` rust
rbatis = "*" ```
python
//执行到远程mysql 并且获取结果。支持serde_json可序列化的任意类型
let py_sql="
SELECT * FROM biz_activity
if name!=null:
name = #{name}
AND delete_flag1 = #{delete_flag}
if age!=1:
AND age = 2
if age!=1:
AND age = 3
trim 'AND ':
AND delete_flag2 = #{delete_flag}
WHERE id = '2';";
let data: Vec<Activity> = Rbatis::singleton()
.py_sql("", &json!({ "name":"新人专享", "delete_flag": 1, }), py_sql)
.unwrap();
rust
use log4rs::init_file;
//main函数加入
fn main(){
log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
}
yaml
refresh_rate: 1 seconds
appenders:
stdout:
kind: console
requests:
kind: file
path: "requests.log"
encoder:
pattern: "{d} - {m}{n}"
root:
level: info
appenders:
- stdout
- requests
xml
<mapper>
<result_map id="BaseResultMap">
<id column="id" property="id"/>
<result column="name" property="name" lang_type="string"/>
<result column="pc_link" property="pcLink" lang_type="string"/>
<result column="h5_link" property="h5Link" lang_type="string"/>
<result column="remark" property="remark" lang_type="string"/>
<result column="version" property="version" lang_type="number" version_enable="true"/>
<result column="create_time" property="createTime" lang_type="time"/>
<result column="delete_flag" property="deleteFlag" lang_type="number" logic_enable="true" logic_undelete="1" logic_deleted="0"/>
</result_map>
<select id="select_by_condition" result_map="BaseResultMap">
<bind name="pattern" value="'%' + name + '%'"/>
select * from biz_activity
<where>
<if test="name != null">and name like #{pattern}</if>
<if test="startTime != null">and create_time >= #{startTime}</if>
<if test="endTime != null">and create_time <= #{endTime}</if>
</where>
order by create_time desc
<if test="page != null and size != null">limit #{page}, #{size}</if>
</select>
</mapper>
toml
[dependencies]
rbatis = "*"
log = "0.4"
log4rs = "0.8.3"
``` rust use rbatis::rbatis::Rbatis; use rbatis::error::RbatisError;
fn main() {
//first install log
log4rs::initfile("log4rs.yaml", Default::default()).unwrap();
// you may need install your mysql or change database url.
Rbatis::singleton().dbdriver = "mysql://root:123456@127.0.0.1:3306/test".tostring();
let data:Result
``` rust use crate::core::rbatis::Rbatis; use serde_json::{json, Value, Number}; /** * 数据库表模型 */
pub struct Activity {
pub id: Option
fn main() {
log4rs::initfile("log4rs.yaml", Default::default()).unwrap();//1 启用日志(可选,不添加则不加载日志库)
let mut rbatis = Rbatis::new();//2 初始化rbatis,也可以使用全局单例Rbatis::singleton()
rbatis.loaddburl("mysql://root:TEST@localhost:3306/test");//3 加载数据库url
rbatis.loadxml("ExampleActivityMapper.xml".tostring(),fs::readtostring("./src/example/ExampleActivityMapper.xml").unwrap());//4 加载xml配置
let dataresult: Vec
``` rust
//自定义事务
pub fn tx() -> Result<u32,RbatisError>{
let tx_id="1234";//事务id
Rbatis::singleton().begin(tx_id, Propagation::REQUIRED)?;//启动事务,传入事务传播行为
let affected: u32 = Rbatis::singleton()
.raw_sql(tx_id, "UPDATE `biz_activity` SET `name` = '活动1' WHERE `id` = '2'")?;
Rbatis::singleton().commit(tx_id)?;//提交事务
Rbatis::singleton().rollback(tx_id)?;//回滚事务
Ok(affected)
}
//声明式事务
pub trait Service {
fn select_activity(&self) -> Result<Activity, RbatisError>;
fn update_activity(&mut self) -> Result<String, RbatisError>;
}
struct ServiceImpl {
select_activity: fn(s: &ServiceImpl) -> Result<Activity, RbatisError>,
update_activity: fn(s: &mut ServiceImpl) -> Result<String, RbatisError>,
}
impl Service for ServiceImpl {
impl_service! {
REQUIRED, select_activity(&self) -> Result<Activity,RbatisError>
}
impl_service_mut! {
NONE, update_activity(&mut self) -> Result<String, RbatisError>
}
}
#[test]
pub fn test_service() {
let mut s = ServiceImpl {
select_activity: |s: &ServiceImpl| -> Result<Activity, RbatisError>{
let act: Activity = Rbatis::singleton().raw_sql("", "select * from biz_activity where id = '2';").unwrap();
return Result::Ok(act);
},
update_activity: |s: &mut ServiceImpl| -> Result<String, RbatisError>{
return Result::Ok("ok".to_string());
},
};
let act: Activity = s.select_activity().unwrap();
println!("{:?}", serde_json::to_string(&act).unwrap().as_str());
println!("{:?}", s.update_activity().unwrap());
}
```
``` rust //这里举例使用web排行榜屠榜最快的actix-web
use rbatis::rbatis_macro;
async fn index() -> impl Responder {
//写法
let data: Result
async fn main() -> std::io::Result<()> { //1 启用日志(可选,不添加则不加载日志库) log4rs::initfile("log4rs.yaml", Default::default()).unwrap(); //2 加载数据库url name 为空,则默认数据库 Rbatis::singleton().loaddburl(MYSQLURL);//"mysql://root:TEST@localhost:3306/test" //3 加载xml配置 let f = fs::File::open("./src/example/ExampleActivityMapper.xml"); Rbatis::singleton().loadxml("ExampleActivityMapper.xml".tostring(), fs::readtostring("./src/example/Example_ActivityMapper.xml").unwrap());//加载xml数据 //初始化rbatis HttpServer::new(move || { App::new() .route("/", web::get().to(index)) }) .bind("127.0.0.1:8000")? .run() .await } ```
| 数据库 | 已支持 |
| ------ | ------ |
| Mysql | √ |
| Postgres | √ |
| SQLite | √ |
| TiDB | √ |
| CockroachDB | √ |
| 功能 | 已支持 |
| ------ | ------ |
| CRUD(内置CRUD模板(内置CRUD支持乐观锁/逻辑删除)) | √ |
| LogSystem(日志组件) | √ |
| LogicDelPlugin(逻辑删除插件) | √ |
| VersionLockPlugin(乐观锁插件,防止并发修改数据) | √ |
| PagePlugin(分页插件) | √ |
| Tx(事务/事务嵌套/注解声明式事务) | √ |
| Py(在SQL中使用和xml等价的类python语法) | √ |
| SlowSqlCount(内置慢查询日志分析) | √ |
| async/await支持(actix/actix-web,hyper等等兼容Tokio的web框架) | √ |
| DataBaseConvertPlugin(数据库表结构转换为配置插件) | x |
| web(可视化Web UI) | x |
``` //sql构建性能 ExampleActivityMapper.xml -> selectby_condition 操作/纳秒nano/op: 0.202 s,each:2020 nano/op 事务数/秒 TPS: 495049.50495049503 TPS/s
//查询结果解码性能 decode/mysqljsondecoder -> benchdecodemysql_json 操作/纳秒nano/op: 0.24 s,each:2400 nano/op 事务数/秒 TPS: 416666.6666666667 TPS/s
//综合性能约等于 操作/纳秒nano/op: 4420 nano/op 事务数/秒 TPS: 200000 TPS/s ```