C++ ORM ODB 入门介绍(二)

Wesley13
• 阅读 745

本节主要介绍ODB中的继承和C++之间的关系。

ORM中的O的关系是很复杂的。其中之一便是对象的继承体系。

在C++语言中支持类之间的继承,这这些继承的关系是否可以同时映射到数据库呢?

1. ODB中的继承类型

ODB支持2中继承类型,abstract和polymorphic。根据ODB文档的描述,abstract方式为复用继承。而polymorphic是属于虚拟继承(支持C++的动态联编).

我们知道,要把一个C++类定义为数据库对象,需要使用#pragma db object 指令告诉ODB编译器。而abstract和polymorphic都是object的一种模式,因此需要使用指令#pragma db object abstract 或者#pragma db object polymorphic指令来通知编译器,基类的继承模型。

abstract和polymorphic在同一个基类中是不能共存的,要不选择abstract要不就选择polymorphic。

2. abstract和polymorphic的区别

从数据库的表现来看,abstract对应的object类,ODB没有为其生成对应的表格,很惊讶吧,不是说每个object类都至少会映射一个表格吗?怎么abstract object没有呢?因为派生类仅仅是把abstract 类的字段合并到自己的表格中而已,有点很想C++的POD类型,仅仅是内存布局上合并在一起,只不过在这里是合并在同一个表格上。

另外abstract object不能有 标记为id属性的字段。因为他不是一个数据库持久对象。也不能使用load、persist、update、find、erase等数据库方法直接操作abstract object类对象。

polymorphic的行为和C++的动态类型几乎是一样的。ODB会为polymorphic的基类生成一个独立的表格,里面会包含子类的类型信息。polymorphic可以有id属性,整个继承体系的id在相同的线性空间上,也就是不同派生类的对象的id不能相同。在load、find的时候,会根据数据库表格里面存储的类类型自动创建正确的子类。在persist、update、erase的时候,也可以直接只用polymorphic的基类调用即可,ODB生成的代码会自动的去识别子类的类型,并调用相应的trait类。

3.polymorphic表格

ODB文档描述:polymorphic的表格有三种方式分别为table-per-hierarchy, table-per-difference, and table-per-class

table-per-hierarchy: 就是每个polymorphic类及其派生类共用一个表格。大表,对于不相关的字段赋值为NULL。

table-per-difference: 就是polymorphic基类有一个表格,让后每个派生类也有自己的一个表格,派生类的表格只保存与自己像个的字段,不保存基类的字段。但是这样有个问题,就是在load对象的时候需要使用联合查询或者2次查询。在update,persist的时候需要2或者多条SQL语句。(推荐使用、数据库没有太多的冗余字段)

table-per-class: 每个派生类一个表格,并且把基类的信息一起合并在一起。和abstract的派生类的表格类似。

4.早期版本如何实现polymorphic

polymorphic特性实在ODB1.8版本才引入的。早期1.4,1.5版本只支持abstract模式。这个时候ODB自己不支持动态类型,需要自己额外添加一个关联映射对象,除了类名称,字段和abstract类一模一样,并且自己增加类型信息字段。在dbevent的persist、erase事件的时候,同步操作关联类,相对比较麻烦。

5.实例

使用入门(一)的数据模型;

加上数据库id为1的类型为一个Zone类。那么一下2中方式都可以正确的从数据库加载Zone的信息.

shared_ptr  z = db.load(1);

shared_ptr e = db.load(1);

persist时, shared_ptr z( new Zone()) 或者 shared_ptr(new Zone());都可以直接调用db.persist(z). update、erase与persist相同。

不能在abstract类上调用persist\update\erase等操作.

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
C++ ORM ODB 入门介绍(一)
:::欢迎广大oscer拍砖和交流.C的语言特性决定了在C中的ORM框架不可能像Java,C那没有那么灵活。C的ORM框架一般都是基于模板,编译时,因此其效率比起Java中的ORM框架更高。ODB是一个比较独立,成熟的基于CTemplate的ORM框架。使用pragma编译指令和ODB.exe编译器生成SQL的特化版本。pr
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
JS必知的6种继承方式
JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。那么如何在JS中实现继承呢?让我们拭目以待JS继承的实现方式既然要实现继承,那么首先我们得有一个父类,代码如下:// 父类function Person(name) { // 给构造函数添加了参数  this.name  name;
Wesley13 Wesley13
2年前
C++ ORM ODB 入门(三)
本节介绍ODB的事务与异常。数据库操作经常涉及到操作多个表格,或者表格中的多行数据。因此必须保证整个过程是原子性的。ODB为数据库的事务提供了易于使用的接口。使用odb::databse的相关方法(persist、update、erase、load)时,必须处于某个事务之间。事务由odb::transcation类表示.odb::tra
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这