# NoORM **Repository Path**: zhang_xiangm/no-orm ## Basic Information - **Project Name**: NoORM - **Description**: 厌倦了铺天盖地的ORM框架,从数据库查询出数据,然后组装成html,真的是非常简单的事情。NoORM提供前端到数据库的直通车。部署一个服务即可通过restfull风格的API查询数据,是前端工程师的福音。 - **Primary Language**: C# - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2021-07-24 - **Last Updated**: 2024-07-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NoORM ### 介绍 从数据库查询出数据,然后组装成html,如此简单的事情,为什么要那么多的约定和配置,为什么要造那么多轮子。数据库里存放的二维表格,到web服务器经过多次转换变成了对象集合,到api层变成json,到浏览器再变成html,这就是热衷于ORM技术的架构师干的糊涂事。如果你厌倦了这种翻手为云,覆手为雨的套路,请静下心来思考编程的真正目的是什么。NoORM提供前端到数据库的直通车。部署一个服务即可通过restful风格的API查询数据,是前后端分离型项目的福音。NoORM的宗旨是使查询数据变得简单,并未提供数据安全方面的机制,如果您的项目对安全性有苛刻的要求,请下载源代码,在合适的位置注入您的安全插件,这对熟悉.net5的工程师来说,并不是什么难事。 ### 开发环境 - Visual Studio 2019 - c# - .net 5 ### 平台兼容性 - windows - linux - macos ### 数据库兼容性 - mysql - sqlserver - oracle - posgresql - sqlite ### 数据库连接字符串 - 配置文件:appsettings.json - 配置项: ``` "ConnectionStringConfigs": { "test": //数据库配置名称,未必是真实的数据库名 { "ConnectionString": "server=.;database=test;uid=sa;pwd=123456;", //ado.net标准数据库连接字符串,具体参考各数据库驱动程序集的相关说明 "ConnectionClassName": "System.Data.SqlClient.SqlConnection" //IDbConnection接口的实现类的类全名,具体参考各数据库驱动程序集的相关说明 }, ... } ``` ### url占位符说明
占位符名称 说明
{数据库名} 数据库配置名称,忽略大小写
{表名} 要操作的数据表名,大小写是否敏感取决于具体的数据库产品及其配置
### 服务端变量说明
变量名称 变量说明
$GUID 服务端会将其替换成一个guid值,常常在inser时使用该变量来生成主键
$NOW 服务端会将其替换成服务器的当前时间
$TICKS 服务端会将其替换成服务器的当前时间的长整型时间戳,注意该时间戳在高并发场景中并不具备唯一性
### 请求字段说明
字段名称 数据类型 字段说明
fields array<string> 查询字段,如果为null,服务端默认为*
data object 要新增或修改的数据,key为字段名称,value为字段值
orderBy string 排序字段
pageSize int 分页大小
pageIndex int 第几页,从0开始
queries array<object> 查询表达式
--field string 查询字段
--operator string 只能是如下值之一:< , <=,==,>= , <> , like,in,not in
--value object 查询值
--prefix string 连接词,可选值:and , or
--leftBrackets string 表达式左边的括号,可以是多个,如:(
--rightBrackets string 表达式左右边的括号,可以是多个,如:)
groupFields array<string> 分组字段,用于统计查询
functions array<object> 统计函数
--functionName string 函数名称
--field string 函数包裹的字段
--resultName string 给函数表达式取一个名字
### 响应字段说明
字段名称 数据类型 字段说明
success boolean 操作结果
message string 错误信息
rowCount int 分页查询时,表示在未分页前,满足查询条件的数据总行数
data object 当对数据库进行insert、update、delete操作时,其值为受影响的数据行数;
当对数据库进行read操作时,其值为一个json键值对;
当对数据库进行select、group、page时,其值为数组,数组的每个元素表示一行数据。
serverReceiveTime string 服务器接收到请求的时间
serverSendTime string 服务器开始向客户端发送数据的时间
### 添加数据 - url:/{数据库名}/{表名}.create - method:post - contentType:application/json - body: ``` { data:{ "Field1":"$GUID", //服务端变量,服务端会用Guid.NewGuid().ToString()替换,常用于生成主键 "Field2":123, //数值字段的值不加引号 "Field3":true, //布尔字段的值不加引号 "Field4":"字符串", //字符串字段值加引号 "Field5":"2021-01-01 13:01:01", //时间字段的值加引号,格式:yyyy-MM-dd HH:mm:ss "Field6":"$NOW", //服务端变量,服务端会用DataTime.Now替换 ... } } ``` - response: ``` { "success": true, //操作结果 "message": null, //错误消息 "serverReceiveTime": "2021-04-21 08:39:57", //服务器接收到请求的时间 "serverSendTime": "2021-04-21 08:39:57", //服务器开始向客户端发送数据的时间 "data": 1 //新增的数据行 } ``` ### 删除数据 - url:/{数据库名}/{表名}.delete - method:delete - contentType:application/json - body: ``` { queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 } ... ] } ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "data": 1 //删除的行数 } ``` ### 修改数据 - url:/{数据库名}/{表名}.update - method:post - contentType:application/json - body: ``` { //更新的字段及其值 data:{ "Field1":"$GUID", //服务端变量,服务端会用Guid.NewGuid().ToString()替换,常用于生成主键 "Field2":123, //数值字段的值不加引号 "Field3":true, //布尔字段的值不加引号 "Field4":"字符串", //字符串字段值加引号 "Field5":"2021-01-01 13:01:01", //时间字段的值加引号,格式:yyyy-MM-dd HH:mm:ss "Field6":"$NOW", //服务端变量,服务端会用DataTime.Now替换 ... }, //where条件 queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 } ... ] } ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "data": 1 } ``` ### 查询一条数据 - url:/{数据库名}/{表名}.read - method:post - contentType:application/json - body ``` { //要查询的字段 fields:["字段1","字段2", ... ], //where条件 queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 } ... ] } ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "data": { Field1:"", Field2:"", ... } } ``` ### 查询多条数据 - url:/{数据库名}/{表名}.select - method:post - contentType:application/json - body: ``` { //要查询的字段 fields:["字段1","字段2", ... ], //where条件 queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 }, ... ] } ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "data": [ { Field1:"", Field2:"", ... }, ... ] } ``` ### 分页查询 - url:/{数据库名}/{表名}.page - method:post - contentType:application/json - body: ``` { orderBy:"排序字段", pageSize:"10", pageIndex:"0", //查询表达式 queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 }, ... ] } ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "rowCount":10000, "data": [ { Field1:"", Field2:"", ... }, ... ] } ``` ### 分组统计 - url:/{数据库名}/{表名}.group - method:post - contentType:application/json - body: ``` { //分组字段 groupFields:["分组字段名1","分组字段名2",...], //统计字段 functions:[{ functionName:"函数名称", field:"字段名称", resultName:"计算后的字段名" }, ... ], //where条件 queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 }, ... ] } ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "data": [ { GroupField1:"", GroupField2:"", ... FunctionField1:"", FunctionField2:"", ... }, ... ] } ``` ### 事务提交 url:/{数据库名}.transaction method:post contentType:application/json body: ``` [ { table:"表名", operator:"insert", //可选值:insert,delete,update data:{ "Field1":"$GUID", //服务端变量,服务端会用Guid.NewGuid().ToString()替换,常用于生成主键 "Field2":123, //数值字段的值不加引号 "Field3":true, //布尔字段的值不加引号 "Field4":"字符串", //字符串字段值加引号 "Field5":"2021-01-01 13:01:01", //时间字段的值加引号,格式:yyyy-MM-dd HH:mm:ss "Field6":"$NOW", //服务端变量,服务端会用DataTime.Now替换 ... } },{ table:"表名", operator:"delete", queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 }, ... ] },{ table:"表名", operator:"update", //要修改的数据 data:{ "Field1":"$GUID", //服务端变量,服务端会用Guid.NewGuid().ToString()替换,常用于生成主键 "Field2":123, //数值字段的值不加引号 "Field3":true, //布尔字段的值不加引号 "Field4":"字符串", //字符串字段值加引号 "Field5":"2021-01-01 13:01:01", //时间字段的值加引号,格式:yyyy-MM-dd HH:mm:ss "Field6":"$NOW", //服务端变量,服务端会用DataTime.Now替换 ... }, //where条件 queries:[ { field:"字段名", value:"字段值" },{ prefix:"and", //连接词 field:"字段称", operator:">", //操作符号,默认为= value:1 //数值型值不加引号 },{ prefix:"and", field:"字段称", operator:"in", value:[1,2,3] //in查询的value是一个数组 }, ... ] }, ... ] ``` - response: ``` { "success": true, "message": null, "serverReceiveTime": "2021-04-21 08:39:57", "serverSendTime": "2021-04-21 08:39:57", "data": true } ```