hisql ORM 框架研究(国内第一个支持HANA的ORM框架)
HiSql 操作说明文档 V1.0
下一代ORM框架 国内第一个支持HANA的ORM框架 hisql.net 官网(文档编写中) hisql源码下载
git clone https://github.com/tansar/HiSql.git
测试源码地址hisql与sqlsugar freesql测试源码
git clone https://github.com/tansar/HiSqlTestDemo.git
特点
- 支持无实体数据交互,(无需要创建实体类)
- 数据动态检测(类型,长度 与表结构预先匹配)
- 语法更帖近于原生SQL
- 支持超时监控(如监控过5S的执行的SQL语 并记录)
- 支持多种库,可自主选择需要支持的库
- 性能优越(会出一篇与FreeSql,SugarSql 的性能对比文章)
适用于场景
HiSql 适用于开发企业的内部管理系统如OA,工作流平台,ERP系统
项目引用
- 引用HiSql.dll文件
- 根据使用数据库的需要可以引用以下数据库实现的sdk HiSql.SqlServer.dll 已经支持
- HiSql.Hana.dll 已经支持(国内第一个支持HANA的ORM框架)
- HiSql.MySql.dll 已经支持
- HiSql.Oracle.dll 已经支持
- HiSql.PostGreSql 已经支持
- HiSql.SqlLite 即将发布
配置数据库连接
HiSqlClient sqlclient = new HiSqlClient( new ConnectionConfig() { DbType = DBType.SqlServer, DbServer="local-HoneBI", ConnectionString = "server=(local);uid=sa;pwd=H---#$3;database=hisql;",//; Schema = "dbo", IsEncrypt = true, IsAutoClose = false, SqlExecTimeOut=60000, AppEvents = new AopEvent() { OnDbDecryptEvent = (connstr) => { //解密连接字段 //Console.WriteLine($"数据库连接:{connstr}"); return connstr; }, OnLogSqlExecuting = (sql, param) => { //sql执行前 日志记录 (异步) //Console.WriteLine($"sql执行前记录{sql} time:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}"); }, OnLogSqlExecuted = (sql, param) => { //sql执行后 日志记录 (异步) //Console.WriteLine($"sql执行后记录{sql} time:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}"); }, OnSqlError = (sqlEx) => { //sql执行错误后 日志记录 (异步) Console.WriteLine(sqlEx.Message.ToString()); }, OnTimeOut=(int timer)=> { //Console.WriteLine($"执行SQL语句超过[{timer.ToString()}]毫秒..."); } } } );
表数据插入
单表单条数据插入 Insert语法 参1:"Hi_DataElement"
可以是一个物理表也可以是临时表
临时表的写法如 "#Hi_DataElement" 用1个#号表示 本地临时表 两个#号表示是全局临时表 变更表写法如"@Hi_DataElement" 注:仅对sqlserver数据库支持
参2:new
可以是匿名类也可以是实体类,匿名类的属性不区分大小写 如字段写的是[domain] 数据库中的字段为Domain 也默认就是对应的是Domain
注:HiSql将会自动校验插入的值的类型,长度是否与底层目标数据库相匹配如果不匹配将会检测报错
sqlclient.Insert("Hi_DataElement", new { domain = "UTYPE" });
以上语句并不会立即执行插入如要执行插入如下所示
sqlclient.Insert("Hi_DataElement", new { domain = "UTYPE" }).ExecCommand();
如果要监控该语句生成的目标数据库的sql语句可以在连接配置事件 执行前或执行后都可以监控到
OnLogSqlExecuting = (sql, param) => { //sql执行前 日志记录 (异步) //Console.WriteLine($"sql执行前记录{sql} time:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}"); }, OnLogSqlExecuted = (sql, param) => { //sql执行后 日志记录 (异步) //Console.WriteLine($"sql执行后记录{sql} time:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}"); }
也可以直接返回Sql语句如下所示
sqlclient.Insert("Hi_DataElement", new { domain = "UTYPE" }).ToSql();
批量插入数据
对表操作无需像其它框架一样需要体实体,HiSql可以不要实体,当然如果习惯了用实体也可以使用实体插入
int _times = 100000; List<object> lstobj = new List<object>(); for (int i = 0; i < _times; i++) { lstobj.Add(new { Domain = $"{i}", DomainDesc = $"用户类型{i}" }); } sqlclient.Insert("Hi_Domain", new { Domain = "UTYPE", DomainDesc = "用户类型" }).ExecCommand();
表数据查询
单表查询
返回结构可以ToTable ToJson ToList ToDynamic 本例演示ToTable
查询返回一个DataTable 同时这里也用到了排序
DataTable DT_RESULT1= sqlclient.Query("DataDomain").Field("Domain").Sort(new SortBy { { "createtime" } }).ToTable();
对表定义别名
DataTable DT_RESULT2 = sqlclient.Query("DataDomain").As("a").Field("a.Domain").Sort(new SortBy { { "a.createtime" } }).ToTable();
查询返回一个实体 查询该表的所有字段在Field方法中传入"*"
List<Hi_Domain> lstefresult = sqlclient.Query("Hi_Domain").Field("*").Sort("createtime asc", "moditime").ToList<Hi_Domain>();
分页查询
DataTable DT_RESULT3 = sqlclient.Query("DataDomain").As("a").Field("a.Domain").Sort(new SortBy { { "a.createtime" } }).Skip(1).Take(100).ToTable();
多表简单关联查询
多表关联并实现条件过滤且进行分页
DataTable DT_RESULT = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname") .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } }) .Where(new Filter { {"A.TabName", OperType.EQ, "Hi_FieldModel"}, {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} }, }) .Skip(1).Take(10).ToTable();
实现分组查询 group分组
DataTable DT_RESULT = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname") .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } }) .Where(new Filter { {"A.TabName", OperType.EQ, "Hi_FieldModel"}, {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} }, }) .Group(new GroupBy { { "A.FieldName" } }) .ToTable();
带统计函数查询
DataTable dt_resultfun = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname", "count(*) as avgFieldLen") .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } }) .Where(new Filter { {"A.TabName", OperType.EQ, "Hi_FieldModel"}, {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} }, }) .Group(new GroupBy { { "A.FieldName" } }) .ToTable();
支持的函数
-
count 样例 count(*) as scount
多表关联分页查询
可以对组数据数据进行分页查询
DataTable dt_resultfun = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname", "count(*) as avgFieldLen") .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } }) .Where(new Filter { {"A.TabName", OperType.EQ, "Hi_FieldModel"}, {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} }, }) .Group(new GroupBy { { "A.FieldName" } }) .Skip(2).Take(10) .ToTable();
复杂子表关联union all查询
DataTable dt_resultuinon = sqlclient.Query( sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.IN, sqlclient.Query("Hi_TabModel").Field("TabName").Where(new Filter { {"TabName",OperType.IN,new List<string> { "Hone_Test", "H_TEST" } } }) } }), sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "DataDomain" } }), sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "Hi_FieldModel" } }) ) .Field("TabName", "count(*) as CHARG_COUNT") .Group(new GroupBy { { "TabName" } }).ToTable();
复杂子表关联 分组排名
WithRank方法 可以查询结果进行排序排名
DbRank.DENSERANK 不跳号排名
DbRank.RANK 跳号排名
DbRank.ROWNUMBER 按记录行号排名
DataTable dt_resultuinon = sqlclient.Query( sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.IN, sqlclient.Query("Hi_TabModel").Field("TabName").Where(new Filter { {"TabName",OperType.IN,new List<string> { "Hone_Test", "H_TEST" } } }) } }), sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "DataDomain" } }), sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "Hi_FieldModel" } }) ) .Field("TabName", "count(*) as CHARG_COUNT") .WithRank(DbRank.DENSERANK, DbFunction.NONE, "TabName", "rowidx1", SortType.ASC) .WithRank(DbRank.ROWNUMBER, DbFunction.COUNT, "*", "rowidx2", SortType.ASC) .WithRank(DbRank.RANK, DbFunction.COUNT, "*", "rowidx3", SortType.ASC) .Group(new GroupBy { { "TabName" } }).ToTable();
- Eurasia3 支持百万级用户的服务器和框架 - 国内开源项目介绍
- 打造国内第一个支持在线演示的人力资源管理系统--源自偕行软件
- Eurasia3 支持百万级用户的服务器和框架 - 国内开源项目介绍
- 国内第一个支持Spring.NET/NHibernate/Ajax的开源的Framework
- 推荐国内第一个支持多种语言的在线编译器
- 国内第一个支持Spring.NET/NHibernate/Ajax的开源的Framework
- Eurasia3 支持百万级用户的服务器和框架 - 国内开源项目介绍
- 数据库连接池DBCP框架的研究以及源代码分析一:第一个DBCP例子
- 第六十二篇、AFN3.0封装网络请求框架,支持缓存
- 首个完整支持中文文档的深度学习框架——百度PaddlePaddle API文档简介
- 【第一个开源项目】最完整的Andoird联系人操作,完美支持联系人的各种属性操作。
- 写一个通用缓存框架,同时支持ehcache,mecache及spring缓存注解等
- “让CI框架支持service层”的那些问题
- 国内HTML5前端开发框架汇总
- 数据库连接池DBCP框架的研究以及源代码分析三:打开AbandonedObjectPool连接池
- Socket.IO:支持WebSocket协议、用于实时通信和跨平台的框架
- 框架设计--第十四章 JSON数据绑定和RESTful支持--习题答案
- CRL快速开发框架系列教程十二(MongoDB支持)
- 【02】框架学习—Hibernate第一个入门案例详解
- 两种方法在Django框架中支持后台返回包含中文的JSON/数组格式