技术开发 频道

Java开发2.0:NoSQL

  返回比赛

  我不会重复 Gaelyk 简介中的那个票据示例,相反,为保持新鲜感,我将在本文中使用一个赛跑主题,并构建一个应用程序来展示即将讨论的技术。

  如图 1 中的 “多对多” 图表所示,一个 Race拥有多个 Runner,一个 Runner可以属于多个 Race。

  图 1. 比赛和参赛者

  如果我要使用一个关系表结构来设计这个关系,至少需要 3 个表:第 3 表将是链接一个 “多对多” 关系的联接表。所幸我不必局限于关系数据模型。相反,我将使用 Gaelyk(和 Groovy 代码)将这个 “多对多” 关系映射到 Google 针对 Google App Engine 的 Bigtable 抽象。事实上,Gaelyk 允许将 Entity当作 Map,这使得映射过程相当简单。

  无模式数据存储的好处之一是无须事先知道所有事情,也就是说,与使用关系数据库架构相比,可以更轻松地适应变化。(注意,我并非暗示不能更改架构;我只是说,可以更轻松地适应变化。)我不打算定义我的域对象上的属性 —我将其推迟到 Groovy 的动态特性(实际上,这个特性允许创建针对 Google 的 Entity对象的域对象代理)。相反,我将把我的时间花费在确定如何查找对象并处理关系上。这是 NoSQL 和各种利用无模式数据存储的框架还没有内置的功能。

  Model 基类

  我将首先创建一个基类,用于容纳 Entity对象的一个实例。然后,我将允许一些子类拥有一些动态属性,这些动态属性将通过 Groovy 的方便的 setProperty方法添加到对应的 Entity实例。setProperty针对对象中实际上不存在的任何属性设置程序调用。(如果这听起来耸人听闻,不用担心,您看到它的实际运行后就会明白。)

  清单 2 展示了位于我的示例应用程序的一个 Model实例的第一个 stab:

  清单 2. 一个简单的 Model 基类

package com.b50.nosql

  import com.google.appengine.api.datastore.DatastoreServiceFactory

  import com.google.appengine.api.datastore.Entity

  abstract class Model {

  def entity

  static def datastore
= DatastoreServiceFactory.datastoreService

  
public Model(){

  super()

  }

  
public Model(params){

  this.@entity
= new Entity(this.getClass().simpleName)

  params.each{ key, val
->

  this.setProperty key, val

  }

  }

  def getProperty(
String name) {

  
if(name.equals("id")){

  return entity.key.id

  }
else{

  return entity.
"${name}"

  }

  }

  void setProperty(
String name, value) {

  entity.
"${name}" = value

  }

  def save(){

  this.entity.save()

  }

  }

  注意抽象类如何定义一个构造函数,该函数接收属性的一个 Map —我总是可以稍后添加更多构造函数,稍后我就会这么做。这个设置对于 Web 框架十分方便,这些框架通常采用从表单提交的参数。Gaelyk 和 Grails 将这样的参数巧妙地封装到一个称为 params的对象中。这个构造函数迭代这个 Map并针对每个 “键 / 值” 对调用 setProperty方法。

  检查一下 setProperty方法就会发现 “键” 设置为底层 entity的属性名称,而对应的 “值” 是该 entity的值。

0
相关文章