HiSql 提供一个可以适合多种数据库的中间查询语法,不需要关注各个数据库的语法特性,通过HiSql写语句可以在常用的不同类型数据库中执行,且语法与Sql语境类似一看就懂一学就会

hisql.net 官网(文档编写中)

HiSql 源码(github) https://github.com/tansar/HiSql

git clone https://github.com/tansar/HiSql.git

::: tip

HiSql 查询方式提供两种查询方式

  1. 链式写法
  2. HiSql 语句 (非原生数据库的语句,但类似于SQL的语法可以跨库执行) 一套中间SQL语句 详请见HiSql语法 文档

HiSql主要的方向是低代码平台(低代码平台的特点是用户可以建表,如果建一张表要对应一个实体是行不通的) 所以暂时不支持Lambda表达式的写法,写也是HiSql与其它ORM框架的区别之一

:::

单表查询

HiSql生成的语句

通过ToSql可以查看当前操作生成的底层Sql语句 注:不同的数据库生成的语句会有差别

::: tip

HiSql底层对于SQL语句进行了AST语法,语义解析能智能识别语法错误

:::

//返回当前连接数据库类型的SQL查询语句
string sql1=sqlClient.Query("Hi_TabModel").Field("*").ToSql();
//返回当前连接数据库类型的SQL查询语句
// 注意这不是原生的sql语句 是HiSql定义的一套跨数据库的中间SQL语句 详请见[HiSql语法] 文档
string sql2=sqlClient.HiSql("select * from Hi_TabModel").ToSql();

在执行ToSql() HiSql会检测查询的表及字段的合法性,只要检测通过了才会编译成对应数据库的Sql查询语句

生成的SQL语句如下(SqlServer为例)


select [Hi_TabModel].[TabName],[Hi_TabModel].[TabReName],[Hi_TabModel].[TabDescript],[Hi_TabModel].[TabStoreType],[Hi_TabModel].[TabType],[Hi_TabModel].[TabCacheType],[Hi_TabModel].[TabStatus],[Hi_TabModel].[IsSys],[Hi_TabModel].[IsEdit],[Hi_TabModel].[IsLog],[Hi_TabModel].[LogTable],[Hi_TabModel].[LogExprireDay],[Hi_TabModel].[CreateTime],[Hi_TabModel].[CreateName],[Hi_TabModel].[ModiTime],[Hi_TabModel].[ModiName] from [Hi_TabModel] as [Hi_TabModel]

可能有人会问为什么*号会带出来所有的字段是不是生成的语句有问题?

::: tip

当字段使用*号时会查询表中所有的字段,如果字段的顺序要调整请修改系统表Hi_FieldModel中的SortNum的值,值越小排在越前面(当物理表中的字段顺序不是想要的但又不想修改物理表可以通过该方式调整顺序)

为了可以自定义排序所以会带出字段,不过没有关系这里不影响性能

:::

单表查询结果

hisql查询的查询语法与sql类似

提供了四种查询结果的返回类型

  1. ToTable() 返回一个DataTable表结果
  2. ToJson() 返回一个Json结果集
  3. ToList<T> 返回一个实体类集合 T 的类的属性必须与返回的结果集有字段相匹配
  4. ToDynamic() 返回一个动态类集 HiSql.TDynamic 可以查看文档
  5. ToEObjectAsync() 返回ExpandObject类集 (1.0.2.9及以上版本才支持)
//查询表Hi_TabModel的所有字段 并返回一个 DataTable的结果集
DataTable dt1= sqlClient.Query("Hi_TabModel").Field("*").ToTable();
//查询表Hi_TabModel的所有字段 并返回一个 DataTable的结果集
// 注意这不是原生的sql语句 是HiSql定义的一套跨数据库的中间SQL语句 详请见[HiSql语法] 文档
DataTable dt2= sqlClient.HiSql("select * from Hi_TabModel").ToTable();

查询指定字段

Field()方法支持多参数(params string[] )的字段 注意不要带数据库底层的符号如sqlserver [字段名] ,hisql在生成sql时将会自动处理

//仅查询表Hi_TabModel的部分字段 并返回一个 DataTable的结果集
DataTable dt= sqlClient.Query("Hi_TabModel").Field("TabName","TabReName").ToTable();
//仅查询表Hi_TabModel的部分字段 并返回一个 DataTable的结果集
// 注意这不是原生的sql语句 是HiSql定义的一套跨数据库的中间SQL语句 详请见[HiSql语法] 文档
DataTable dt= sqlClient.HiSql("select TabName,TabReName from Hi_TabModel").ToTable();

生成的SQL语句如下(SqlServer为例)

select [Hi_TabModel].[TabName],[Hi_TabModel].[TabReName] from [Hi_TabModel] as [Hi_TabModel]

单表分页查询

  1. Skip 表示取的页码数
  2. Take 表示每页获取数量
  3. Sort 可以支持多种方式如
    1. Sort("createtime desc") 注意这个适用于Hisql支持的所有库(不要用底层库的语法不然Hisql检测时会抛出异常)
    2. Sort("createtime desc","TabName asc") 多个排序条件时可以这样写
    3. Sort(new SortBy { { "createtime",SortType.DESC} }) 也支持这种写法
    4. Sort(new SortBy { { "createtime",SortType.DESC} , { "TabName", SortType.ASC } }) 多个参数写法
//方式1
DataTable dt1= sqlClient.Query("Hi_TabModel").Field("*")
.Sort("createtime desc"). Skip(1).Take(100).ToTable(); //方式2
DataTable dt2 = sqlClient.Query("Hi_TabModel").Field("*")
.Sort(new SortBy { { "createtime",SortType.DESC} }).Skip(1).Take(100).ToTable(); //如果需要返回当前查询条件的记录总数
int _total=0;
DataTable dt3 = sqlClient.Query("Hi_TabModel").Field("*")
.Sort(new SortBy { { "createtime",SortType.DESC} }).Skip(1).Take(100).ToTable(ref _total);
DataTable dt4= sqlClient.HiSql("select * from Hi_TabModel").Skip(1).Take(100).ToTable();

//如果需要返回当前查询条件的记录总数
int _total=0;
DataTable dt5 = sqlClient.HiSql("select * from Hi_TabModel").Skip(1).Take(100).ToTable(ref _total);

::: tip

在HiSql底层会根据页码生在不同的分页方式以追求性能极致

:::

Where条件查询

HiSql提供了多种查询语句的写法总有一款适合你

HiSql查询条件的特点是可以动态拼接(非生成数据库SQL),这是其它ORM框架完全不具备的用Lambda表达式的方式如果要拼动态条件试过的人都知道多痛苦,如果用原生SQL是无法跨库支持的且完全性不可控(sql注入),HiSql在底层编译器解析成不同的数据库语句。有兴趣的可以试一下ToSql()方法查看一下编译出来的SQL

可能有些人会问?用表达式这种强类型的不好吗? 当然好还是那句话如果你的项目不涉及到动态的或与低代码相关的建议你用传统的ORM工具,如果你的项目想做成高度配置型的HiSql将是不错的选择

//单值
DataTable dt1 = sqlClient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "HTest01" } }).ToTable();
//多值查询 或查询
DataTable dt2 = sqlClient.Query("Hi_FieldModel").Field("*").Where(new Filter {
{ "TabName", OperType.EQ, "HTest01" },
{ LogiType.OR},
{ "FieldName", OperType.EQ, "UName" }
}).ToTable();
DataTable dt3 = sqlClient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "HTest01" } }).ToTable();
//注意这不是原生的sql语句 是HiSql定义的一套跨数据库的中间SQL语句 详请见[HiSql语法] 文档
//hisql语法
DataTable dt4 = sqlClient.HiSql("select * from Hi_FieldModel as a where a.TabName='HTest01'").ToTable();
DataTable dt5 = sqlClient.HiSql("select * from Hi_FieldModel where TabName='HTest01'").ToTable();
DataTable dt6 = sqlClient.HiSql("select * from Hi_FieldModel where (TabName='HTest01' or FieldName='UName')").ToTable();
DataTable dt7 = sqlClient.Query("Hi_FieldModel").Field("*").Where("TabName='HTest01'").ToTable();
DataTable dt8 = sqlClient.Query("Hi_FieldModel").Field("*").Where("(TabName='HTest01' or FieldName='UName')").ToTable();

子查询

上面介绍的查询方式大家可能都看得出来查询是比较简单的,如果涉及到子查询怎么样写呢?下来就来演示一下

DataTable dt1= 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> { "HTest01", "Hi_TabModel" } } })
} }).ToTable();
//注意这不是原生的sql语句 是HiSql定义的一套跨数据库的中间SQL语句 详请见[HiSql语法] 文档
DataTable dt2 = sqlClient.HiSql("select * from Hi_FieldModel where TabName in (select TabName from Hi_TabModel where TabName in ('HTest01','Hi_TabModel'))").ToTable();

生成的SQL语句如下(SqlServer为例)

select [Hi_FieldModel].[TabName],[Hi_FieldModel].[FieldName],[Hi_FieldModel].[FieldDesc],[Hi_FieldModel].[IsIdentity],[Hi_FieldModel].[IsPrimary],[Hi_FieldModel].[IsBllKey],[Hi_FieldModel].[FieldType],[Hi_FieldModel].[SortNum],[Hi_FieldModel].[Regex],[Hi_FieldModel].[DBDefault],[Hi_FieldModel].[DefaultValue],[Hi_FieldModel].[FieldLen],[Hi_FieldModel].[FieldDec],[Hi_FieldModel].[SNO],[Hi_FieldModel].[SNO_NUM],[Hi_FieldModel].[IsSys],[Hi_FieldModel].[IsNull],[Hi_FieldModel].[IsRequire],[Hi_FieldModel].[IsIgnore],[Hi_FieldModel].[IsObsolete],[Hi_FieldModel].[IsShow],[Hi_FieldModel].[IsSearch],[Hi_FieldModel].[SrchMode],[Hi_FieldModel].[IsRefTab],[Hi_FieldModel].[RefTab],[Hi_FieldModel].[RefField],[Hi_FieldModel].[RefFields],[Hi_FieldModel].[RefFieldDesc],[Hi_FieldModel].[RefWhere],[Hi_FieldModel].[CreateTime],[Hi_FieldModel].[CreateName],[Hi_FieldModel].[ModiTime],[Hi_FieldModel].[ModiName] from [Hi_FieldModel] as [Hi_FieldModel]
where [Hi_FieldModel].[TabName] in (select [Hi_TabModel].[TabName] from [Hi_TabModel] as [Hi_TabModel]
where [Hi_TabModel].[TabName] in ('HTest01','Hi_TabModel')
)

虽然两种不同的写法,但是生成的语句是一模一样的,HiSql内置了HiSql语句编译器有兴趣的可以看一下源码,实现原理与其它ORM框架有着本质匹别解析性能比Lambda表达式方式要强

分类汇总查询

HiSql支持max,min,avg,sum,count 五种常用聚合函数

DataTable dt = sqlClient.Query("Hi_FieldModel").Field("FieldName", "count(FieldName) as CHARG_COUNT").Group(new GroupBy { { "FieldName"} }).ToTable();
DataTable dt2 = sqlClient.HiSql("select FieldName,count(FieldName) as CHARG_COUNT from  Hi_FieldModel group by FieldName").ToTable();

生成的sql如下(以sqlserver为例)

select [Hi_FieldModel].[FieldName],count(*) as CHARG_COUNT from [Hi_FieldModel] as [Hi_FieldModel]
group by [Hi_FieldModel].[FieldName]

对分类汇总不跳号排名

相有多个值同时则并列排名

DataTable dt_dens= sqlClient.Query("Hi_FieldModel").Field("FieldName", "count(FieldName) as CHARG_COUNT")
.Group(new GroupBy { { "FieldName" } })
.WithRank(DbRank.DENSERANK, DbFunction.COUNT, "FieldName", "rowidx1", SortType.DESC).ToTable();

生成的sql如下 (sqlserver)

 select [Hi_FieldModel].[FieldName],count(*) as CHARG_COUNT,
dense_rank() over( order by COUNT([FieldName]) DESC) as rowidx1
from [Hi_FieldModel] as [Hi_FieldModel]
group by [Hi_FieldModel].[FieldName]

查询结果如下

并列第一的都是第1名 但第二名这个号没有被占用,这种叫不跳号排名

分类汇总跳号排名

DataTable dt_rank = sqlClient.Query("Hi_FieldModel").Field("FieldName", "count(FieldName) as CHARG_COUNT")
.Group(new GroupBy { { "FieldName" } })
.WithRank(DbRank.RANK, DbFunction.COUNT, "FieldName", "rowidx2", SortType.DESC).ToTable();

生成的sql如下(sqlserver)


select [Hi_FieldModel].[FieldName],count(*) as CHARG_COUNT,
rank() over( order by COUNT([FieldName]) DESC) as rowidx2
from [Hi_FieldModel] as [Hi_FieldModel]
group by [Hi_FieldModel].[FieldName]

查询结果如下

当有几个并列第一时则跳过这此号 称为跳号排名

分类汇总结果增加行号

var dt1 = sqlClient.Query(
sqlClient.Query("Hi_FieldModel").Field("*").WithLock(LockMode.ROWLOCK).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").WithLock(LockMode.ROWLOCK).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.ROWNUMBER, new Ranks { { DbFunction.COUNT, "*" }, { DbFunction.COUNT, "*", SortType.DESC } }, "rowidx2")
.WithRank(DbRank.RANK, DbFunction.COUNT, "*", "rowidx3", SortType.ASC) .Group(new GroupBy { { "TabName" } }).ToTable();

多表查询

join 查询

大家可以对比与其它框架的写法,HiSql的语法更贴近于数据库的SQL语句,学习成本更低,且其它ORM框架由于受泛型类的限制,对Join表的数量是有限制的。

DataTable dt1 = 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, "HTest01" } })
.ToTable();
DataTable dt2 = sqlClient.HiSql("select  A.FieldName as Fname from Hi_FieldModel as A inner join Hi_TabModel as B on A.TabName = B.TabName where A.TabName='HTest01'").ToTable();

生成的sql如下 (sqlserver)


select [A].[FieldName] as [Fname] from [Hi_FieldModel] as [A]
inner join [Hi_TabModel] as [B] on [A].[TabName]=[B].[TabName]
where [A].[TabName] = 'HTest01'

hisql ORM 查询语句使用教程的更多相关文章

  1. 用lambda构建ORM查询语句

    本文介绍如何解析lambda表达式来获取一个满足条件的查询语句. 先看个截图  通过设置实体对象Article_Content的查询表达式,就可以获取对应的参数化SQL语句,使用起来很方便,减少了代码 ...

  2. Java开源协同办公项目:数据中心,自定义查询语句使用教程

    O2OA提供的数据管理中心,可以让用户通过配置的形式完成对数据的汇总,统计和数据分组展现,查询和搜索数据形成列表数据展现.也支持用户配置独立的数据表来适应特殊的业务的数据存储需求.本文主要介绍如何在O ...

  3. hisql orm update表数据更新文档

    更新 HiSql数据更新 HiSql 提供了好几种数据更新的方式下面一一介绍一下 如果你的表中增加了这四个字段 字段 描述 类型 CreateTime 创建时间 DateTime CreateName ...

  4. ORM查询条件

    模板: from django.db import models class Article(models.Model): title = models.CharField(max_length=20 ...

  5. Django(17)orm查询操作

    前言 查找是数据库操作中一个非常重要的技术.查询一般就是使用filter.exclude以及get三个方法来实现.我们可以在调用这些方法的时候传递不同的参数来实现查询需求.在ORM层面,这些查询条件都 ...

  6. hisql orm 框架insert数据写入教程

    hisql.net 官网(文档编写中) HiSql 源码(github) https://github.com/tansar/HiSql git clone https://github.com/ta ...

  7. 第二十篇ORM查询与SQL语句

    ORM查询与SQL语句 多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情 ...

  8. SQL Server-简单查询语句,疑惑篇(三)

    前言 对于一些原理性文章园中已有大量的文章尤其是关于索引这一块,我也是花费大量时间去学习,对于了解索引原理对于后续理解查询计划和性能调优有很大的帮助,而我们只是一些内容进行概括和总结,这一节我们开始正 ...

  9. Django 源码小剖: Django ORM 查询管理器

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...

随机推荐

  1. 2020 NUPCTF pwn题目

    去年的一场比赛,今年来把去年不会做的题目来看一下,只在buu找到三道题,剩下两道好像是内核题,算了,估计找到也不会做. npuctf_2020_level2 bss段上的格式化字符串漏洞的利用. 程序 ...

  2. [BUUCTF]REVERSE——新年快乐

    新年快乐 附件 例行查壳儿,32位程序,upx加壳儿 利用网上找到的脱壳儿工具,拿到了去壳儿后的程序 32位ida打开,shift+f12查看程序里的字符串,得到了关于flag的提示 双击,ctrl+ ...

  3. 工厂为什么要进行计划排产,APS高级计划排程系统的优势作用是什么?

    我们每个人的指挥中心是大脑,大脑对我们身体发出各种各样的指令,不停的告诉我们身体去干什么. 那么,一个制造企业的指挥中心是哪里?工厂每天都会接到各种各样的订单,通过几百上千的工人,使用各种设备来生产. ...

  4. AT2686 [ARC080A] 4-adjacent 题解

    Content 给定一个长度为 \(n\) 的数列 \(a\),请将其重新排列,使得 \(\forall i\in[1,n-1]\),都有 \(4\mid (a_i\cdot a_{i+1})\),或 ...

  5. navicat模型分享方法

    一. 查看模型保存路径选中模型如:<app-订单模型>,点击右键,对象信息,可以看到文件位置:C:\Users\Administrator\Documents\Navicat\Premiu ...

  6. win10使用cmake配置fmt生成vs2015解决方案(fmt version 7.0.1)

    !!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!! 作者:mohist 本文仅为参考,请以实际情况为准, fmt版本: 7.0.1 准备 下载源码fmt : htt ...

  7. 【LeetCode】 204. Count Primes 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 素数筛法 参考资料 日期 [LeetCode] 题目 ...

  8. 【九度OJ】题目1199:找位置 解题报告

    [九度OJ]题目1199:找位置 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1199 题目描述: 对给定的一个字符串,找出有重复的 ...

  9. 【LeetCode】883. Projection Area of 3D Shapes 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数学计算 日期 题目地址:https://leetc ...

  10. Codeforce 633C. Spy Syndrome 2

    C. Spy Syndrome 2 time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...