数据中台和低代码平台的选型之D-ORM

最近参与了一个项目是给简道云提供后台支持的 用户自己配置数据源生成报表,汇集金蝶用友等系统的进销存财务之类的数据,有点数据中台和低代码的意思。
之前一直都是用mybatis不明白为什么要换个不熟悉的小众工具,
想建议换成mybatis但是没敢说,因为mybatis大家都知道,既然没用肯定是有原因的。
还是研究一下再说下结论吧,
项目进行过程中我才慢慢发现,幸好我没提建议,要不然显得我肤浅了。
如果用了mybatis,光一个查询条件就够我加不完的班了,
处理结果集数据更是个灾难,因为以前用的那些个实体类,现在都不知道怎么创建了。
而且计算个数据真是纯手工打造了。以前都是查出来个实体对象返回给前端还没觉得有什么,现在真要计算数据了才发一实体类根本就不适合处理计算数据。
但是有个非常非常非常糟糕的事情是,anyline的文档很不好用,找文档都不知道怎么找,而且因为版本更新太快,许多文档都是过时的(包括官网文档)。
遇到问题问领导怎么处理,你猜他怎么回复,让我自己猜。这真让我怀疑我是不是真的进了个软件公司。
值得庆幸的是大部分竟然真能猜中了。可见这个anyline的设计还真是按程序员的思路设计的,
这不得不引用一句官方用语:Anyline的一切也源于近一线人员。每个思路、每个类、方法、参数都来自于大家 车到山前那一刻的灵感和期望。
还真是所想即所得。当然这不能掩盖文档的缺陷。总不能什么都靠猜吧,猜错了算谁的。
 

因为使用时间有限,不是非常了解,具体细节就不评论了,还是引用一段官方说明吧:

动态、运行时

即运行时才能最终确定 动态的数据源、数据结构、展现形式
如我们需要开发一个数据中台或者一个数据清洗插件,编码阶段我们还不知道数据来源、什么类型的数据库甚至不是数据库、会有什么数据结构对应什么样的实体类,
如果需要前端展示的话,更不会知道不同的终端需要什么各种五花八门的数据组合
那只能定义一个高度抽象的实体了,想来想去也只有Collection可以胜任了。

简单快速的操作数据库

最常见的操作:根据条件分页查询一个表的几列
这一动就要倾巢出动一整套的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呢?国产库呢?

误解

当然我们并不是要抛弃Entity或ORM,相反的 AnyLine源码中也使用了多达几十个Entity
在一些 可预知的 固定的 场景下,Entity的优势还是不可替代的
程序员应该有分辨场景的能力
AnyLine希望程序员手中多一个数据库操作的利器,而不是被各种模式各种hello world限制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HibernateD 是 D 语言的 ORM 框架,类似 Java 的 Hibernate,示例代码:import hibernated.core; // Annotations of entity classes class User {     long id;     string name;     Customer customer;     @ManyToMany // cannot be inferred, requires annotation     LazyCollection!Role roles; } class Customer {     int id;     string name;     // Embedded is inferred from type of Address     Address address;     Lazy!AccountType accountType; // ManyToOne inferred     User[] users; // OneToMany inferred     this() {         address = new Address();     } } @Embeddable class Address {     string zip;     string city;     string streetAddress; } class AccountType {     int id;     string name; } class Role {     int id;     string name;     @ManyToMany // w/o this annotation will be OneToMany by convention     LazyCollection!User users; } // create metadata from annotations EntityMetaData schema = new SchemaInfoImpl!(User, Customer, AccountType,                                   T1, TypeTest, Address, Role, GeneratorTest); // setup DB connection factory MySQLDriver driver = new MySQLDriver(); string url = MySQLDriver.generateUrl("localhost", 3306, "test_db"); string[string] params = MySQLDriver.setUserAndPassword("testuser", "testpasswd"); DataSource ds = ConnectionPoolDataSourceImpl(driver, url, params); // create session factory Dialect dialect = new MySQLDialect(); SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds); scope(exit) factory.close(); // Create schema if necessary { // get connection Connection conn = ds.getConnection(); scope(exit) conn.close(); // create tables if not exist factory.getDBMetaData().updateDBSchema(conn, false, true); } // Now you can use HibernateD // create session Session sess = factory.openSession(); scope(exit) sess.close(); // use session to access DB // read all users using query Query q = sess.createQuery("FROM User ORDER BY name"); User[] list = q.list!User(); // create sample data Role r10 = new Role(); r10.name = "role10"; Role r11 = new Role(); r11.name = "role11"; Customer c10 = new Customer(); c10.name = "Customer 10"; User u10 = new User(); u10.name = "Alex"; u10.customer = c10; u10.roles = [r10, r11]; sess.save(r10); sess.save(r11); sess.save(c10); sess.save(u10); // load and check data User u11 = sess.createQuery("FROM User WHERE name=:Name").                            setParameter("Name", "Alex").uniqueResult!User(); assert(u11.roles.length == 2); assert(u11.roles[0].name == "role10" || u11.roles.get()[0].name == "role11"); assert(u11.roles[1].name == "role10" || u11.roles.get()[1].name == "role11"); assert(u11.customer.name == "Customer 10"); assert(u11.customer.users.length == 1); assert(u11.customer.users[0] == u10); assert(u11.roles[0].users.length == 1); assert(u11.roles[0].users[0] == u10); // remove reference u11.roles.get().remove(0); sess.update(u11); // remove entity sess.remove(u11); 标签:HibernateD

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值