简介
AnyLine的核心是一个面向运行时的元数据动态关系映射
主要用来读写元数据、动态注册切换数据源、对比数据库结构差异、生成动态SQL、复杂的结果集操作
适配各种关系型与非关系型数据库(及各种国产小众数据库)
常用于动态结构场景的底层支持,作为SQL解析引擎或适配器出现
如:数据中台、可视化、低代码、SAAS、自定义表单、异构数据库迁移同步、 物联网车联网数据处理、 条件/数据结构、 爬虫数据解析等。 参考【适用场景】
已经有了ORM了,为什么还要用AnyLine(D-ORM),他与ORM的区别是什么
-
面向场景不同
anyline主要面向动态场景,就是运行时随时可变的场景。
如我们常用的动态数据源,不是在部署时可以固定在配置文件中,
而是可能在不确定的时间,由不确定的用户提供的不确定数据源。
表结构等元数据也可能随着着用户或数据源的不同而随时变化。 -
针对产品不同
anyline一般不会直接用来开发一个面向终端用户的产品(如ERP、CRM等),而是用来开发一个中间产品(如低代码平台),让用户通过中间产品来生成一个最终产品。
再比如用anyline开发一个自定义查询分析工具,让用户通过这个工具根据业务需求生成动态报表。
anyline不是要提供一个可二次开发的半成品船,而是可以用来造船的动态船坞。 -
操作对象不同
anyline主要操作元数据,因为在项目开发之初,可能就没有一个如ERP/CRM之类的明确的产品,当然也就没有订单、客户之类的具体对象及属性,所以也没什么具体数据可操作。 -
面向用户(开发设计人员)不同
anyline要面向的不是开船的人,而是造船的人,而不是使用工具的人,而是设计工具的人。anyline的大部分代码与灵感也是来自这部分用户的日常实践。 -
所以对用户(开发设计人员)要求不同
一个ORM用户用了许多年的连接池,他可以只知道配置哪几个默认参数,也能正常开展工作。
但anyline的用户不行,他要求这个团队中至少有一个人要明白其所以然。
实际操作中与ORM最明显的区别是:
-
摒弃了各种繁琐呆板的实体类以及相关的配置文件
让数据库操作更简单,不要一动就是一整套的service/dao/mapping/VOPODTO有用没用的各种O,生成个简单的SQL也各种判断遍历。
-
强化了结果集的对象概念
面向对象的对象不是只有get/set/注解这么弱
需要把数据及对数据的操作封装在一起,作为一个相互依存的整体,并实现高度的抽象
要关注元数据,不要关注姓名、年龄等具体属性
强化针对结果集的数据二次处理能力
如结果集的聚合、过滤、行列转换、格式化及各种数学计算尽量作到一键...一键...
而不要像ORM提供的entity,map,list除了提供个get/set/foreach,稍微有点用的又要麻烦程序员各种判断各种遍历
如何实现
数据操作的两个阶段,1.针对数据库中数据 2.针对数据库查询的结果集(内存中的数据)-
提供一个通用的AnylineService实现对数据库的一切操作
-
提供一对DataSet/DataRow实现对内存数据的一切数学计算
DataSet/DataRow不是对List/Map的简单封装 他将是提高我们开发速度的重要工具,各种想到想不到的数学计算,只要不是与业务相关的都应该能实现
AnyLine解决或提供了什么
当然这种问题很难有定论,只能在实际应用过程中根据情况取舍。以参考【适用场景】和【实战对比】中的示例
即运行时才能最终确定 动态的数据源、数据结构、展现形式
如我们需要开发一个数据中台或者一个数据清洗插件,编码阶段我们还不知道数据来源、什么类型的数据库甚至不是数据库、会有什么数据结构对应什么样的实体类,
如果需要前端展示的话,更不会知道不同的终端需要什么各种五花八门的数据组合
那只能定义一个高度抽象的实体了,想来想去也只有Collection<Map>可以胜任了。
最常见的操作:根据条件分页查询一个表的几列
这一动就要倾巢出动一整套的service/dao/vo dto 各种O/mapper,生成个查询条件各种封装、为了拼接个SQL又是各种if else forearch
如果查询条件是由前端的最终用户动态提供的,那Java里if完了还不算完,xml中if也少不了
一旦分了页,又要搞出另一套数据结构,另一组接口,另一组参数(当然这种拙劣的设计只是极个别,不能代表ORM)
数据库负责的是存储,其结构肯定是与业务需要不一样的。所以结果集需要处理。当我们需要用Map处理数据或数学计算时,
如最常见的数据格式化、筛选、分组、平均值、合计、方差等聚合计算、
再如空值的处理包括,"",null,"null","\n","\r","\t"," "全角、半角等各种乱七八糟的情况;
这时就会发现Map太抽象了,除了get/set/forearch好像也没别的可施展了。
要处理的细节太多了,if都不够用了。
再比如多数据源的情况下,要切换个数据源又是IOC又是AOP一堆设计模式全出场。经常是在方法配置个拦截器。
在同一个方法里还能切换个数据源了?
数据中台里有可能有几百几千个数据源,还得配上几千个方法?
数据源是用户动态提交的呢怎么拦截呢?
这不是DB Util的本职工作么,还要借助其他?
哪个项目少了AOP依赖还切换不了数据源了?
如果只是写个helloworld,以上都不是问题,没什么解决不了的。但实现工作中是需要考虑工作量和开发速度的。
比如一个订单可能有几十上百列的数据,每个分析师需要根据不同的列查询。有那么几十列上同时需要<>=!=IN FIND_IN_SET多种查询方式算正常吧
不能让开发人员挨个写一遍吧,写一遍是没问题,但修改起来可就不是一遍两遍的事了
所以需要提供一个字典让用户自己去配置,低代码开发平台、自定义报表、动态查询条件应该经常有这个需求。
当用户提交上来一个列名、一个运算算、一组值,怎么执行SQL呢,不能在代码中各种判断吧,如果=怎么合成SQL,如果IN怎么合成SQL
DML方面hibernate还可以处理,DDL呢?国产库呢?小众库呢?
比如作一个异构数据库迁移工具,还能要求用户熟悉每种数据库的语法?是不是应该让用户提供几个参数自动生成就可以了。
比如提供*表示同步所有表,*-T1,T2表示同步除了T1,T2之外的所有表,不能让用户为每个表针对不同的库写不同的SQL吧。
选型之前,当然要搞明白优势劣势,参考【优势劣势】
误解
当然我们并不是要抛弃Entity或ORM,相反的 AnyLine源码中也使用了多达几十个Entity(如几何图形等)
在一些 可预知的 固定的 场景下,Entity的优势还是不可替代的
程序员应该有分辨场景的能力
如何使用
数据操作不要再从生成xml/dao/service以及各种配置各种O开始
默认的service已经提供了大部分的数据库操作功能。
操作过程大致如下:
DataSet set = service.querys("HR_USER(ID,NM)", condition(true,"anyline根据约定自动生成的=,in,like等查询条件"));
这里的查询条件不再需要各种配置,各种if else foreach标签
Anyline会自动生成,生成规则可以参考这里的【约定规则】
分页也不需要另外的插件,更不需要繁琐的计算和配置,指定true或false即可
如何集成
只需要一个依赖、一个注解即可实现与springboot,netty等框架项目完美整合,参考【入门系列】
大概的方式就是在需要操作数据库的地方注入AnylineService
接下来service就可以完成大部分的数据库操作了。常用示例可以参考【示例代码】
关于数据库的适配
直接看示例(代码都是一样的、可以用来测试一下自己的数据库是否被支持)https://gitee.com/anyline/anyline-simple/tree/master/anyline-simple-data-jdbc-dialect
(海量数据) LightDB
(恒生电子) greatdb
(万里数据库) mogdb
(云和恩墨) GoldenDB(中兴) GaiaDB-X
(百度云) TiDB AntDB(亚信) citus TDSQL(TBase)(腾讯云) 磐维数据库
(中国移动) CUDB
(中国联通) MuDB(沐融) HashData
(酷克) HotDB(热璞) UXDB(优炫) KunDB(星环) StarDB(京东) YiDB(天翼数智) UbiSQL
(平安科技) xigemaDB
(华胜信泰) SinoDB
(星瑞格) CockroachDB InfluxDB Informix MongoDB MogoDB RethinkDB
没有示例的看这个目录下有没有 【anyline-data-jdbc-dialect】还没有的请联系【技术支持】中的管理员