jxTMS使用示例--类表同步的继承

110 篇文章 0 订阅
44 篇文章 0 订阅

使用本示例需通过docker容器,请先下拉jxTMS的docker镜像并按说明启动tms容器,并从helloWorld开始尝试。

jxTMS类表同步的继承

继承是面向对象编程的核心概念,也是软件工程中提高代码复用、降阶系统复杂度、编程模型易于理解的关键性技术。所以jxTMS的一个设计目标就是:自定义的数据类也应具备继承的能力。数据类的继承非常简单,因为不管是python还是java都是面向对象的编程语言,自然都支持类的继承。但数据类是要映射到数据库中的某个表的,也就是说数据类的继承必须要解决数据库中的相应的数据表在继承时的操作简化问题,否则就会违背jxTMS的根本目标:低成本快速定制

这种为了确保数据类之间的继承语义的数据操作逻辑,jxTMS称之为类表同步。我们下面就来演示这种能力。

数据类的继承

我们在data文件中增加一个新的数据类:

class extDemo super demoData:
	field ID long primaryKey
	field Ext string len=32
;

注意和之前的demoData定义相比,多了【super demoData】,指示extDemo数据类是从demoData数据类继承而来的。

OK,我们现在就将data按用sftp管理jxTMS的代码所述更新到/home/tms/codeDefine/demo/demo/demo1目录中。

然后执行一次热机刷新,看看发生了什么:

1、通过日志,我们看到在加载demo模块时,系统报告:

2021-06-13 21:07:59.591 tty DEBUG [pool-3-thread-16] 数据表(extDemo)是否存在:false cn.ijingxi.tms.common.orm.jxORMobj.createTableInDB(jxORMobj.java:914)
2021-06-13 21:07:59.592 tty DEBUG [pool-3-thread-16] 创建数据表:extDemo cn.ijingxi.tms.common.orm.jxORMobj.createTableInDB(jxORMobj.java:917)
2021-06-13 21:07:59.592 tty DEBUG [pool-3-thread-16] CREATE TABLE extDemo(ID bigint NOT NULL PRIMARY KEY,Ext VARCHAR(32) NOT NULL) cn.ijingxi.tms.common.orm.jxORMobj.createTableInDB(jxORMobj.java:959)

即jxTMS在加载data文件时,检测到数据表(extDemo)不存在,随即根据data文件中的定义自动创建了extDemo数据表。

2、我们查看数据库验证一下:

mysql> use demo_6288;
mysql> desc extDemo;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| ID    | bigint(20)  | NO   | PRI | NULL    |       |
| Ext   | varchar(32) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

确实在数据库中根据我们在data文件中的定义创建了extDemo数据表。可是,按继承的定义,extDemo不是也应该包括了demoData中定义的Type、Name等字段吗?!请往下看。

创建extDemo对象

我们把sayHello函数修改一下:

@myModule.event('cmd', 'sayHello')
def sayHello(self, db, ctx):
	dd = pyORM.create(db,'extDemo')
	dd.Type = 'demo'
	dd.Name = 'Name-sayHello'
	dd.Ext = 'Ext-sayHello'

我们现在将capa.py文件按用sftp管理jxTMS的代码所述更新到/home/tms/codeDefine/demo/demo/demo1目录中。

然后执行一次热机刷新后,再次点击快捷栏中的【演示->helloWorld】,然后点击【点我】按钮。然后执行:

mysql> select * from extDemo;
+-------------------+--------------+
| ID                | Ext          |
+-------------------+--------------+
| 26600905801465938 | Ext-sayHello |
+-------------------+--------------+
1 row in set (0.00 sec)

mysql> select * from demoData;
+-------------------+--------+------+---------------------+---------------+
| ID                | NoUsed | Type | CreateTime          | Name          |
+-------------------+--------+------+---------------------+---------------+
|   103897269075998 |      0 | test | 2021-06-11 07:00:30 | ok            |
| 26600905801465938 |      0 | demo | 2021-06-13 13:20:42 | Name-sayHello |
+-------------------+--------+------+---------------------+---------------+
2 rows in set (0.00 sec)

可以看到现在在extDemo表中和demoData表中,同时多了一个ID相同的数据行。而这两行的Ext、Type、Name也恰好是我们在sayHello所赋予的。即在数据库层面,一个extDemo数据对象被拆分后分别放到extDemo数据表和demoData数据表中存储,然后通过共同的ID主键进行关联。

读取extDemo对象

我们把helloWorld的prepareDisp函数修改一下:

@myModule.event('prepareDisp', 'helloWorld')
def helloWorld(self, db, ctx):
	#请把26600905801465938换成你查到的ID值
	dd = pyORM.getByID(db.getDBConn(),'extDemo',26600905801465938)
	self.setOutput('outText',utils.getMsg('{}.{}.{}/from:{}',dd.Type,dd.Name,dd.Ext,dd.ID))

我们现在将capa.py文件按用sftp管理jxTMS的代码所述更新到/home/tms/codeDefine/demo/demo/demo1目录中。

然后执行一次热机刷新后,再次点击快捷栏中的【演示->helloWorld】然后看一下【说点啥】后的显示内容。

演示结果表面,我们在用getByID读取一个extDemo数据对象时,jxTMS会自动做一个extDemo和demoData两数据表的联合查询【ID相等为条件】,然后将查询出来的数据赋值给创建出来的extDemo数据对象。

在数据源中,jxTMS也会自动关联extDemo和demoData,大家可以尝试着把sql文件中的listDemoData做如下的修改【修改前最好把原来的listDemoData复制后改名为listDemoDataOld】:

sql listDemoData
from extDemo as ta
select ta.all
where ta.Type=='demo'
orderBy ta.CreateTime DESC;

我们现在将capa.py文件按用sftp管理jxTMS的代码所述更新到/home/tms/codeDefine/demo/demo/demo1目录中。

然后执行一次热机刷新后,再次点击快捷栏中的【演示->listDemoData】然后看看能否显示出正确的数据。

可以看到,虽然我们在from子句中只写了extDemo表,但jxTMS会自动为我们关联demoData。

总结

jxTMS的类表同步的继承能力,使得数据类被继承后,在python中的使用就如同未继承的数据类一样,而jxTMS会自动在数据库层面实现数据的正确存储与同步读取。这就完全不需要开发者在数据类继承后还需要做任何额外的数据管理了,从而大大降低了对开发者的要求还提高了相关操作的可靠性。

注:由于担心jxTMS所提供的数据表自动管理能力太过强大,导致修改数据类定义时误删除数据列,笔者不得不限制了这一能力:jxTMS只会根据data文件来创建数据库中没有过的同名数据表,但创建后绝不会根据data中数据类定义的变化就去修改数据库表的定义。

数据库中数据表的定义如果要变动,开发者只能手动进行调整,这是为了避免开发者随意修改data中数据类的定义,使得jxTMS根据这个修改删除了数据库中的列,导致数据丢失。而之前笔者反复说了,jxTMS不提供数据删除能力,即jxTMS的开发逻辑是:错就错了,但不能删

也就是说,在设计数据类时,一定要想清楚,否则到时再想修改就只能手动进行了。

那么,如果我们一定需要修改数据类的定义呢?!简单的很,我们这节说的不就是类表同步的继承吗!在原来的类上继承出来一个新的数据类就好了,最多有些属性现在不用了就是。而且更关键的是:这不会影响原有代码,所以我们拷贝一下老代码到新的事件响应函数中,然后老代码不动,对新增数据在新的事件响应函数中处理就好了。

当然,即便我们有了类表同步的继承能力,使得我们可以近乎随心所欲的扩展数据类,但毕竟每次继承都是多做了一个表级的级联,就数据库的查询来说,效率是会下降的,所以还是建议大家在设计数据类时,要尽可能的想清楚,为日后的扩展留点余地。

注:jxTMS没有限制继承的层数,理论上讲不管继承了多少层,jxTMS都会自动沿着继承层次完成所有父表的关联。但关系数据库中表的级联是一个笛卡尔乘积的运算,所以级联的多了,查询效率肯定会下降

如果大家还对之前的那个问题【按继承的定义,extDemo不是也应该包括了demoData中定义的Type、Name等字段吗?!】有疑问,不理解jxTMS为什么会把extDemo拆分为extDemo和demoData。

那么请思考一下:

1、按照继承的定义,子类也是基类,那么extDemo对象是不是demoData对象?

2、反映到数据库中,26600905801465938号的extDemo是不是也是26600905801465938号的demoData?

3、那如果extDemo也包括了demoData中定义的Type、Name等字段,那我们要查询26600905801465938号的demoData时,系统该如何知道要从extDemo表中查而不是从demoData表中查呢?!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值