过程模式之O/R映射映射

       对象方式的基础是用具有数据和行为的对象来构建应用;关系方式的基础是将数据存储在表的行中。在将对象用关系数据库存储时,自然存在对象/关系阻抗不匹配。它们的本质区别使得这两种方式结合的并不完美。
      要将对象成功映射到关系数据库,就要了解这两种方式及其区别,从中选择折衷的方案。在此引用《过程模式(上)》(Scott.W.Ambler著)原文:
     要减少对象/关系阻抗不匹配的影响,您需要:
        .使用对象标识符
       .掌握映射的基本知识
       .避免存储过程
       .了解将对象映射到关系型数据库的现实情况
    1 . 对象标识符
     对象标识符OID唯一标识对象,不会发生重复。在关系数据库的表中,需要选择一个主属性,以标识不同的元组。每个元组的各个属性均涉及到业务含义,而具有任何业务含义的元组属性再未来都可能会改变。引用含业务关系的属性作为主键,一旦业务发生变化,维护工程将是非常庞大的。而OID是不具有任何业务含义的,这也是其最大的优点。如果将OID作为主键,一旦业务变化,修改的仅仅是数据库的表,并不会对应用造成影响。这种方式的不足之处就是它不能完全解决我们在对象间导航的问题。
    使用OID作为主键的另一好处就是它使我们容易地自动维护对象间的关系,可以写一组通用的代码维护应用。
    2 . 映射的基本原理
    将对象映射到表的列中的时候,一个属性对应一列,但应去掉不是持久的属性。一些对象的有些属性本身可能是对象,所以有时候需要将一个OO属性映射到数据库的多列。记住:任何给定的属性将被映射到零个/多个列。
    存在继承关系的对象如何映射到关系数据库?也可以理解为如何组织数据库中已继承的属性。有如下方案可选择:
       1) . 对整个类层次结构使用一个表:层次结构中所有类的属性都存储在一张表中。这种方式简单,容易生成任意报表。但是当类层次结构中的某一处增加了新属性,就需要增加新列,这也就增加了类层次结构中的耦合。如果添加的属性错误,将会影响到该层次结构中所有的类,而不仅仅是获得新属性的那个子类。同时它也浪费了数据库的空间,不是每一列都适合表中的每个对象。
        2) .每个具体的类使用一个表:每个表都包含所代表的类的属性及其继承属性。这种方式生成报表也比较容易。但当修改一个类时,就需要修改其映射表及其子类的表。还有就是,当对象更改其角色,它的数据就需要复制到对应的表中,同时要为其指定新的OID,在数据较多的时候,工作量也不容忽视。最后,在对象支持多角色的时候,难以保持数据完整性。
        3) .每个类使用一个表:这样的类的属性是OID及特定于该类的那些属性。这种方式最符合面向对象的概念,支持多态(只需在对象可能拥有角色的相应表中保留记录)。修改超类和添加子类也比较容易,只需要修改/添加一个表(外加维护关系的表,如果有)。这种方式缺点就是读写数据的时间加长,可以通过将类层次结构的每个表放在不同的物理磁盘驱动器上进行巧妙的组织数据库。在不添加试图模拟所需的表的时候,生成任意报表就比较困难了。
       从数据库角度,关联和聚合的唯一区别就是对象间绑定的紧密程度。使用聚合,读入的所有数据实际上是需要的部分,而使用关联,需要执行的操作并不是那么明显。关系数据库中的关系是通过外键来维护,在一对一和一对多的关系中,外键能够维持。在多对多的关系中,我们应引入关联表,它的唯一用途就是维护关系数据库的两个表或多个表间的关系。
    3 . 避免存储过程
     存储过程是在20世纪80年代为了支持结构化开发者构建c/s应用需要而引入的。对结构化开发是一个好办法,但并不适用面向对象的开发。
     将对象映射到关系数据库时,不要使用存储过程。原因如下:
       1) 使用该方式,数据库很快成为整个应用的瓶颈。存储过程是在关系数据库服务器上运行的功能,如果经常调用,即使一个简单的存储过程也会使服务器不堪重负。
       2) 存储过程是用专门的语言编写的,这也可能成为中断运行的因素。随着时间推移,一旦更换数据库供应商,变化的影响就会暴露出来。
       3) 这种方式极大增加了数据库中的耦合。存储过程直接访问各个表,这些表与存储过程耦合,所增加的耦合降低了DBA的灵活性(需要重新组织数据库,重新编写存储过程)。这同时也增加了开发者的维护负担。
       当构建打算抛弃的原型(假设尚未构建坚固的持久层)或映射到一个旧的数据库而其设计完全不适合对象且不能根据特定的需要改造该数据库时,选择存储过程是有意义的。对后一种情况,无需使用存储过程编写这些代码,可以使用自选的语言编写并在数据库外运行它(避免网络流量,故可能需要放在服务器上)
    4 .  对象映射到关系数据库的现实
     对象和关系数据库是常见的情况。
     硬编码sql极不可取:增加了应用与数据库设计耦合,可维护性较差。最好的办法是在持久层动态生成sql,虽然动态sql速度较慢,但维护性得到增强。
     数据模型无法驱动类图:需要映射到旧数据库时,不应该降低对象设计的质量,不要用数据模型做类图设计的基础。
    表连接很慢:在合理的地方跨越而非连接是克服对象/关系不匹配的一个选择。
    避免使用组合键。它作为外键会增加数据库的开销,增加了数据库设计的复杂度,而且在处理多字段时会导致附加处理需求。


   注:本文摘自Scotte.W.Ambler的《过程模式(上)》,并稍做修改整理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,你的问题是如何在XMF09B或XMF09C开发板中完成以上功能。以下是详细的步骤和代码示例: 步骤1:初始化USART0 首先,需要初始化USART0,选择UART模式,波特率9600,并将I/O引脚映射到备用位置1。这可以通过以下代码实现: ```c void USART0_Init(void) { // 选择UART模式 USART0->CR1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS); USART0->CR1 &= ~USART_CR1_OVER8; USART0->CR2 &= ~(USART_CR2_STOP); USART0->CR3 &= ~(USART_CR3_ONEBIT); // 设置波特率为9600 USART0->BRR = 0x1D4C; // 使能USART0 USART0->CR1 |= USART_CR1_UE; // 将USART0的TX和RX引脚映射到备用位置1 GPIOB->AFR[1] |= (0x07 << (4*5)); // TX GPIOB->AFR[1] |= (0x07 << (4*6)); // RX GPIOB->MODER |= (0x02 << (2*5)); // TX GPIOB->MODER |= (0x02 << (2*6)); // RX } ``` 步骤2:控制LED灯 接下来,需要根据收到的数据控制LED灯,并返回相应的提示信息。可以使用以下代码实现: ```c void controlLED(uint8_t data) { if (data == 0xA1) // 收到 “0xA1”,点亮D4灯 { GPIOC->BSRR |= GPIO_BSRR_BS_4; // 点亮D4灯 USART0_SendString("D4 is open!\r\n"); // 返回提示信息 } else if (data == 0xA2) // 收到 “0xA2”,关闭D4灯 { GPIOC->BSRR |= GPIO_BSRR_BR_4; // 关闭D4灯 USART0_SendString("D4 is closed!\r\n"); // 返回提示信息 } else if (data == 0xB1) // 收到 “0xB1”,点亮D6灯 { GPIOC->BSRR |= GPIO_BSRR_BS_6; // 点亮D6灯 USART0_SendString("D6 is open!\r\n"); // 返回提示信息 } else if (data == 0xB2) // 收到 “0xB2”,关闭D6灯 { GPIOC->BSRR |= GPIO_BSRR_BR_6; // 关闭D6灯 USART0_SendString("D6 is closed!\r\n"); // 返回提示信息 } else // 收到其他数据,不控制LED灯,返回错误信息 { USART0_SendString("ERROR!!!\r\n"); // 返回错误信息 } } ``` 步骤3:接收数据并调用控制LED灯函数 最后,需要在主函数中循环接收USART0收到的数据,并根据数据调用控制LED灯函数。可以使用以下代码实现: ```c int main(void) { USART0_Init(); GPIOC->MODER |= 0x01 << (2*4); // D4灯 GPIOC->MODER |= 0x01 << (2*6); // D6灯 while (1) { if (USART0->ISR & USART_ISR_RXNE) // 判断是否接收到数据 { uint8_t data = (uint8_t)(USART0->RDR & 0xFF); // 从寄存器中读取数据 controlLED(data); // 根据数据控制LED灯 } } } ``` 以上就是在XMF09B或XMF09C开发板中完成以上功能的详细步骤和代码示例。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值