Grails(Java笨狗)系列---The Application Domain

任何面向对象语言,不管是桌面,Server,Mobile 应用程序,Domain在程序中都是重要的。

Domain是任何企业应用的核心,比如在书店应用中需要Book,在购物应用中需要Order,这些企业实体相互关联着,他们的状态可以被保存,或者在以后的某个时刻被取回。

在OOP中,Object拥有属性,字段,方法。数据库中的表格拥有Columns和primary keys。如果你使用过ORM,那么对象与数据库的映射将非常的简单。

Grails是构建在Spring+Hibernate之上的,不过他提供了一种更简单的映射Grails Object-RelationalMapping (GORM)。

Grails使用Hibernate’高度定制配置APIs,考虑更加容易使用ORM映射, 通过运用规约的力量使用新的映射战略叫Grails Object-relational Mapping (GORM)。

Domain class 可以通过命令行 create-domain-class创建:

grails create-domain-class Person

 他将创建一个路径为 grails-app/domain/Person.groovy 的类:

class Person {	
}

  假如你在 DataSource设置了 dbCreate property 为 "update", "create" or "create-drop"  , Grails w将自动产生修改你的数据表格。

你可以通过添加属性来定制你的Domain class:

class Person {	
	String name
	Integer age
	Date lastVisit
}
  •  Basic CRUD

基本的CRUD (Create/Read/Update/Delete) 操作. 

  1. Create:设置Domain属性 然后调用 save方法保存到数据库中(利用潜在的hibernate ORM层):

    def p = new Person(name:"Fred", age:40, lastVisit:new Date())
    p.save()
     注意Groovy中new一个对象与Java中的差别,这点,会在相应的Groovy系列教材中讲到。
  2. Read:Grails 会自动添加一个  id property 在你的 domain class ,通过id来取得对应的Domain class:

    def p = Person.get(1)
    assert 1 == p.id
  3. Update:更新某个实体, 先设置其属性然后再次调用 save 方法:

    def p = Person.get(1)
    p.name = "Bob"
    p.save()
     
  4. Delete:删除实体通过 delete 方法:

    def p = Person.get(1)
    p.delete()
     
  • Domain Modelling in GORM

下面我们来看下怎么样设计 domain in GORM.

  1. 创建a domain class 你可以在命令行提示符中运行 create-domain-class (必须在项目路径下使用此命令行,谨记!!!):
    grails create-domain-class Book
     结果一个 class 将在你的项目路径grails-app/domain/Book.groovy下被创建:
    class Book {	
    }
     注:假如你想创建packages,只需要把class移动到你相应的packages中,不过必须是在grails-app/domain下,然后按照Java的packages规则来声明packages。上面的Class被自动映射到一个名为book的数据表格中 (和class同样的名字,当然它是小写的).上面这些都是通过ORM Domain Specific Language规约产生的。
  2. 现在可以使用 Java类型来定义你的 properties
    class Book {
    	String title
    	Date releaseDate
    	String ISBN
    }
    每个属性将被映射到 数据库对应表格的column中。这里有个规约:每个 column名字都是小写的,除了class的 properties使用的“驼峰”书写方式的 properties名字就需要使用“—”符号了。比如: releaseDate将被自动写成 release_date。但是你也可以通过Constraints or  ORM DSL.定制。 
  • GORM中的关联:
  1. One-to-one

class Face {
    Nose nose
}
class Nose {	
}
 上面,我们使用了单向one-to-one 关联从 Face 到 Nose. 如果使用双向one-to-one 关联,看下面的代码:
class Face {
    Nose nose
}
class Nose {	
	Face face
}
 上面两段代码都很容易理解。下面我们看下第3段代码:
class Face {
    Nose nose
}
class Nose {	
	static belongsTo = [face:Face]
}

上面我们使用了“ belongsTo ”,设置 Nose "属于" Face.

new Face(nose:new Nose()).save()

保存Face的同时,必须要保存Nose,因为这里是一个“ belongsTo ”关系,假如你使用下面的代码:

new Nose(face:new Face()).save() // will cause an error

将会产生错误。

就拿客户和订单来做比较,当然这里是使用一对一的,一个客户对应一个订单,保存客户的同时,你得把它的订单一起保存,因为这个订单是属于某个客户的,倒转过来思维,因为订单没有设置belongsTo,也就是说他不会关心他的客户是谁,可以把belongsTo这个看作是某个class的属性,如果你保存一个没有的属性当然会出错,不知道大家能不能理解,这个是我自己的意思。

继续:

def f = Face.get(1)
f.delete() // both Face and Nose deleted

删除某个Faces会同时删除对应的Nose,反过来不成立。就如上面所说的,既然某个Nose是某个Face的属性,因为设置了belongsTo,我们暂时这样来理解,如果客户都不存在,订单还有存在的价值吗,其实也就是一个class被删除了,属于他的属性还会继续存在吗?

相关推荐