- 浏览: 33917 次
最新评论
-
flyisland:
well done!我是搜索grails+ajax找到你的网站 ...
GORM翻译 -
stiffler:
谢谢!这篇文章解决了我的问题~支持,加油~期待更多精彩文章不知 ...
grails的命名策略和数据库连接
第一次翻译,翻译的不好,希望大牛们可以校正,说实话grails关注的人实在太少,哎,现在弄的缺乏信心了.
Grails : GORM
Grails Object Relational Mapping (GORM)
介绍
域对象是任何商业应用的核心. 这些对象保持商业过程的状态同样也实现行为. 他们通过one-to-one或者one-to-many等关系相互连接起来.
GORM是Grails对象关系映射(ORM) 的实现. 他使用Hibernate 3 引擎(一个非常流行和灵活的开源ORM 解决方法),GORM同时支持动态和静态的域对象创建,在缺省情况下,Grails采用动态的域对象创建,这样可以不用写hibernate的配置文件.
你同样可以使用Java写一个Grails的域对象,[参见 Hibernate Integration 这里介绍了怎样用java写一个grails域对象但是仍然可以使用域对象的动态方法]
创建一个域对象
Grails中一个域对象从本质上来说是一个带有id和version属性的Groovy类.
Book.groovy
class Book {
Long id
Long version
String title
}
你可以在你的Grails项目的根目录下面使用如下命令快捷的创建一个域对象定义:
grails create-domain-class
创建关系
定义一个一对多的关系就是简单的定义一个Set类型的属性,然后把属性加入到” relatesToMany”这个map中:
Author.groovy
class Author {
Long id
Long version
def relatesToMany = [ books : Book ]
String name
Set books = new HashSet()
}
Groovy一个主要的特性是他支持静态键入,这就意味这我们不需要把one-to-one, many-to-one关联放入relationships这个map中:
Book.groovy
class Book {
Long id
Long version
Author author
String title
}
one-to-many拥有者就是定为one的这一端 (在上面的例子中是 "Author.groovy"), 但如果你创建了一个one-to-one的映射,那么定义这个关联关系的拥有者就非常重要了. 例如如果我们有一个Author类,它没有和Book定义关联关系, (ie in a one-to-one scenario), 那么Grails会假定Book是Author的拥有者.实际上这是非常严重的错误. 因为这意味着当你删除一个Book实例的时候,这个删除操作同样会去删除该实例对应的Author,因为拥有者是Book而不是Author.这不是我们要得到的结果.
因此我们必需在one-to-one或者many-to-one这样的关系中定义一个被拥有这样的属性. 在Grails中我们在被拥有者这一端定义一个"belongsTo" 属性:
Book.groovy
class Book {
Long id
Long version
def belongsTo = Author
Author author
String title
}
如下,一个域对象可以同时被多个对象拥有:
@Property belongsTo = [Author,Publisher]
换句话说:
• 一个拥有者能够拥有其他域对象
• 被拥有这使用'belongsTo' 属性指向他的拥有者
• 如果一个拥有者被删除了,所有属于他的被拥有者也将消失
关系概要
下面这个表格定义了两个类A和B之间可能的关联关系
关系可能是单向的 (->) 或者双向的(<->),也拥有关系的类型one-to-one (1:1), one-to-many (1:m), many-to-one (m:1), and many-to-many (n:m).
拥有者的字体是粗体.
A:B 单向 双向
1:1 A -> B A <-> B ; B.belongsTo = [A]
1:m A -> Set ; A.relatesToMany= [B] A -> Set ; A.relatesToMany = [B]; B -> A
m:1 A -> B A -> B ; B -> Set ; B.relatesToMany = [A]
n:m Grails中未实现 Grails中未实现
在one-to-many中如果one这端是拥有者的话那么,不需要belongsTo 定义
opposite of
映射继承
GORM使用 table-per-heirarchy 继承,从本质上来说父对象和所有子对象共享共用一张表:
class Content {
Long id
Long version
String author
}
class BlogEntry extends Content {
URL url
}
class Book extends Content {
String ISBN
}
class PodCast extends Content {
byte[] audioStream
}
上面的定义允许你运行多态查询:
def content = Content.findAll() // find all blog entries, books and pod casts
content = Content.findAllByAuthor('Joe Bloggs') // find all by author
def podCasts = PodCast.findAll() // find only pod casts
Technical note for those interested: Under the covers, only one table is used in the table-per-hierarchy model. A class column specifies the subclass and any fields in the subclasses are included on the same table. Subclass fields cannot be "required" because the underlying columns need to be nullable for the other subclasses. This doesn't however prevent you from using Validation constraints to ensure that subclass fields are "required".
技术提示:在继承关系中所有对象只有一张表,所有父类属性和子类属性都放在这张表里面,子类的属性不能是”require”因为他有可能在其他子类中是可以为空的,但是这并不妨碍你对子类的字段使用校验条件”constraints”使用required条件
Optional(可选的) 和Transient(瞬时的)属性
在缺省情况下,所有的属性都是persistent(可持久化) 和required(必需的),你可以使用名为”optionals”(可选的)和”transients”(瞬时的)类型为List属性来改变他:
Book.groovy
class Book {
Long id
Long version
def optionals = [ "releaseDate" ]
def transients = [ "digitalCopy" ]
Author author
String title
String author
Date releaseDate
File digitalCopy
}
CRUD 操作
Grails域对象使用动态的持久化方法容易的在域对象上进行CRUD (Create/Read/Update/Delete)操作:
Create
为了在数据库中创建一个域对象的实例,域对象可以使用save方法,save方法可以把关系中的其他对象也级联保存. 在下面这个例子中,我们仅仅调用一个author的”save”方法,那么Author和Book实例都将存储到数据库中:
def a = new Author(name:"Stephen King")
def b = new Book(title:"The Shining",author:b)
a.books.add(b)
// persist
a.save()
注意:在通常情况下,推荐使用在你的域对象中添加一个方法管理域对象关系,而不是象上面那样直接加入一个实例到”books”这个Set中.例如下面的例子中就添加了一个addBook方法:
def addBook(book) {
if(!books)books = new HashSet()
book.author = this
books.add(book)
return this
}
GORM 将会管理你的域对象数据存储到数据库, 但是不会自动为你管理对象之间的关系的优化.因此代码将变成:
def a = new Author(name:"Stephen King")
a.addBook(new Book(title:"The Shining"))
.addBook(new Book(title:"IT"))
.save()
Read
Grails中有很多中方式得到域对象实例, 更多的信息可以参见 Domain Class Querying, 然而如果我们知道域对象实例的id属性,那么我们可以用get静态方法来得到:
Book.get(1)
或者使用 "findAll", "list" 或 "listOrderByX" 来获取多个对象:
Book.findAll() // retrieve all
Book.list(10) // lists first 10 instances
Book.listOrderByTitle() // lists all the instances ordered by the "title" property
Update
更新一个域对象实例和save方法不同, 他可能不会明确调用save方法来保存. 如果没有异常发生,那么对象所做的修改将会被自动保存到数据库[但是这个对象必需是从数据库获取的,否则必需显式调用save,因为在调用save的时候,如果数据库里没有这个对象,会多执行一跳sql语句获取对象的主键]:
def b = Book.get(1)
b.releaseDate = new Date()
这种行为可能不是一直是我们所希望,特别是当我们和validation条件结合的情况下, (可能你不希望你的域对象实例没有经过检验就存到数据库中.因此当你直接调用save方法的时候,如果对象不符合检验条件,那么他将不会被存入数据库:
def b = Book.get(1)
b.title = null // can't have a null title
b.save() // won't save as fails to validate
有时,我们可能需要在校验失败的时候仍然保存对象到数据库,那么我们可以显式调用validate方法来校验:
def b = Book.get(1)
b.publisher = "Print It"
if(!b.validate()) {
b.publisher = Publisher.DEFAULT
}
在上面的例子中,对象在校验失败的时候仍然保存到数据库. 如果你希望validate方法在校验失败的时候不存入数据库,你可以使用validate(true):
b.validate(true)
可选的是,如果你向明确控制对象的持久化(保存到数据库)你可以使用discard方法,他将会把对象从持久化框架中剔除,从而不把对象修改保存到数据库中:
def b = Book.get(1)
b.title = "A New Title"
// something happenedd to change your mind
b.discard()
Delete
域对象实例能使用delete方法从数据库中删除掉:
def b = Book.get(1)
b.delete()
域对象查询
使用动态方法查询
Grails有很多种方法通过动态方法查询域对象的实例, 详细的情况参考 DomainClass Dynamic Methods:
def results = Book.findByTitle("The Stand")
results = Book.findByTitleLike("Harry Pot%")
results = Book.findByReleaseDateBetween( firstDate, secondDate )
results = Book.findByReleaseDateGreaterThan( someDate )
results = Book.findByTitleLikeOrReleaseDateLessThan( "%Something%", someDate )
// find by relationship
results = Book.findAllByAuthor( Author.get(1) )
使用实例查询
你可以使用find方法查询域对象仅仅通过传递一个域对象实例.
def b = Book.find( new Book(title:'The Shining') )
使用criteria builder查询(criteria builder是hibernate架构的一种便捷查询方式)
对于高级的查询或者域对象交叉查询可以使用Criteria (详见 Builders):
def c = Book.createCriteria()
def results = c {
like("author.name", "Stephen%")
between("releaseDate", firstDate, secondDate )
}
使用HQL语言查询(HQL:Hibernate Query Language[hibernate查询语言])
另外,可以使用hibernate本身的查询语言HQL:
def results = Book.find("from Book as b where b.title like 'Lord of the%'")
或者带有参数:
def results = Book.find("from Book as b where b.title like ?", ["The Shi%"])
Document generated by Confluence on Jul 14, 2006 09:01
Grails : GORM
Grails Object Relational Mapping (GORM)
介绍
域对象是任何商业应用的核心. 这些对象保持商业过程的状态同样也实现行为. 他们通过one-to-one或者one-to-many等关系相互连接起来.
GORM是Grails对象关系映射(ORM) 的实现. 他使用Hibernate 3 引擎(一个非常流行和灵活的开源ORM 解决方法),GORM同时支持动态和静态的域对象创建,在缺省情况下,Grails采用动态的域对象创建,这样可以不用写hibernate的配置文件.
你同样可以使用Java写一个Grails的域对象,[参见 Hibernate Integration 这里介绍了怎样用java写一个grails域对象但是仍然可以使用域对象的动态方法]
创建一个域对象
Grails中一个域对象从本质上来说是一个带有id和version属性的Groovy类.
Book.groovy
class Book {
Long id
Long version
String title
}
你可以在你的Grails项目的根目录下面使用如下命令快捷的创建一个域对象定义:
grails create-domain-class
创建关系
定义一个一对多的关系就是简单的定义一个Set类型的属性,然后把属性加入到” relatesToMany”这个map中:
Author.groovy
class Author {
Long id
Long version
def relatesToMany = [ books : Book ]
String name
Set books = new HashSet()
}
Groovy一个主要的特性是他支持静态键入,这就意味这我们不需要把one-to-one, many-to-one关联放入relationships这个map中:
Book.groovy
class Book {
Long id
Long version
Author author
String title
}
one-to-many拥有者就是定为one的这一端 (在上面的例子中是 "Author.groovy"), 但如果你创建了一个one-to-one的映射,那么定义这个关联关系的拥有者就非常重要了. 例如如果我们有一个Author类,它没有和Book定义关联关系, (ie in a one-to-one scenario), 那么Grails会假定Book是Author的拥有者.实际上这是非常严重的错误. 因为这意味着当你删除一个Book实例的时候,这个删除操作同样会去删除该实例对应的Author,因为拥有者是Book而不是Author.这不是我们要得到的结果.
因此我们必需在one-to-one或者many-to-one这样的关系中定义一个被拥有这样的属性. 在Grails中我们在被拥有者这一端定义一个"belongsTo" 属性:
Book.groovy
class Book {
Long id
Long version
def belongsTo = Author
Author author
String title
}
如下,一个域对象可以同时被多个对象拥有:
@Property belongsTo = [Author,Publisher]
换句话说:
• 一个拥有者能够拥有其他域对象
• 被拥有这使用'belongsTo' 属性指向他的拥有者
• 如果一个拥有者被删除了,所有属于他的被拥有者也将消失
关系概要
下面这个表格定义了两个类A和B之间可能的关联关系
关系可能是单向的 (->) 或者双向的(<->),也拥有关系的类型one-to-one (1:1), one-to-many (1:m), many-to-one (m:1), and many-to-many (n:m).
拥有者的字体是粗体.
A:B 单向 双向
1:1 A -> B A <-> B ; B.belongsTo = [A]
1:m A -> Set ; A.relatesToMany= [B] A -> Set ; A.relatesToMany = [B]; B -> A
m:1 A -> B A -> B ; B -> Set ; B.relatesToMany = [A]
n:m Grails中未实现 Grails中未实现
在one-to-many中如果one这端是拥有者的话那么,不需要belongsTo 定义
opposite of
映射继承
GORM使用 table-per-heirarchy 继承,从本质上来说父对象和所有子对象共享共用一张表:
class Content {
Long id
Long version
String author
}
class BlogEntry extends Content {
URL url
}
class Book extends Content {
String ISBN
}
class PodCast extends Content {
byte[] audioStream
}
上面的定义允许你运行多态查询:
def content = Content.findAll() // find all blog entries, books and pod casts
content = Content.findAllByAuthor('Joe Bloggs') // find all by author
def podCasts = PodCast.findAll() // find only pod casts
Technical note for those interested: Under the covers, only one table is used in the table-per-hierarchy model. A class column specifies the subclass and any fields in the subclasses are included on the same table. Subclass fields cannot be "required" because the underlying columns need to be nullable for the other subclasses. This doesn't however prevent you from using Validation constraints to ensure that subclass fields are "required".
技术提示:在继承关系中所有对象只有一张表,所有父类属性和子类属性都放在这张表里面,子类的属性不能是”require”因为他有可能在其他子类中是可以为空的,但是这并不妨碍你对子类的字段使用校验条件”constraints”使用required条件
Optional(可选的) 和Transient(瞬时的)属性
在缺省情况下,所有的属性都是persistent(可持久化) 和required(必需的),你可以使用名为”optionals”(可选的)和”transients”(瞬时的)类型为List属性来改变他:
Book.groovy
class Book {
Long id
Long version
def optionals = [ "releaseDate" ]
def transients = [ "digitalCopy" ]
Author author
String title
String author
Date releaseDate
File digitalCopy
}
CRUD 操作
Grails域对象使用动态的持久化方法容易的在域对象上进行CRUD (Create/Read/Update/Delete)操作:
Create
为了在数据库中创建一个域对象的实例,域对象可以使用save方法,save方法可以把关系中的其他对象也级联保存. 在下面这个例子中,我们仅仅调用一个author的”save”方法,那么Author和Book实例都将存储到数据库中:
def a = new Author(name:"Stephen King")
def b = new Book(title:"The Shining",author:b)
a.books.add(b)
// persist
a.save()
注意:在通常情况下,推荐使用在你的域对象中添加一个方法管理域对象关系,而不是象上面那样直接加入一个实例到”books”这个Set中.例如下面的例子中就添加了一个addBook方法:
def addBook(book) {
if(!books)books = new HashSet()
book.author = this
books.add(book)
return this
}
GORM 将会管理你的域对象数据存储到数据库, 但是不会自动为你管理对象之间的关系的优化.因此代码将变成:
def a = new Author(name:"Stephen King")
a.addBook(new Book(title:"The Shining"))
.addBook(new Book(title:"IT"))
.save()
Read
Grails中有很多中方式得到域对象实例, 更多的信息可以参见 Domain Class Querying, 然而如果我们知道域对象实例的id属性,那么我们可以用get静态方法来得到:
Book.get(1)
或者使用 "findAll", "list" 或 "listOrderByX" 来获取多个对象:
Book.findAll() // retrieve all
Book.list(10) // lists first 10 instances
Book.listOrderByTitle() // lists all the instances ordered by the "title" property
Update
更新一个域对象实例和save方法不同, 他可能不会明确调用save方法来保存. 如果没有异常发生,那么对象所做的修改将会被自动保存到数据库[但是这个对象必需是从数据库获取的,否则必需显式调用save,因为在调用save的时候,如果数据库里没有这个对象,会多执行一跳sql语句获取对象的主键]:
def b = Book.get(1)
b.releaseDate = new Date()
这种行为可能不是一直是我们所希望,特别是当我们和validation条件结合的情况下, (可能你不希望你的域对象实例没有经过检验就存到数据库中.因此当你直接调用save方法的时候,如果对象不符合检验条件,那么他将不会被存入数据库:
def b = Book.get(1)
b.title = null // can't have a null title
b.save() // won't save as fails to validate
有时,我们可能需要在校验失败的时候仍然保存对象到数据库,那么我们可以显式调用validate方法来校验:
def b = Book.get(1)
b.publisher = "Print It"
if(!b.validate()) {
b.publisher = Publisher.DEFAULT
}
在上面的例子中,对象在校验失败的时候仍然保存到数据库. 如果你希望validate方法在校验失败的时候不存入数据库,你可以使用validate(true):
b.validate(true)
可选的是,如果你向明确控制对象的持久化(保存到数据库)你可以使用discard方法,他将会把对象从持久化框架中剔除,从而不把对象修改保存到数据库中:
def b = Book.get(1)
b.title = "A New Title"
// something happenedd to change your mind
b.discard()
Delete
域对象实例能使用delete方法从数据库中删除掉:
def b = Book.get(1)
b.delete()
域对象查询
使用动态方法查询
Grails有很多种方法通过动态方法查询域对象的实例, 详细的情况参考 DomainClass Dynamic Methods:
def results = Book.findByTitle("The Stand")
results = Book.findByTitleLike("Harry Pot%")
results = Book.findByReleaseDateBetween( firstDate, secondDate )
results = Book.findByReleaseDateGreaterThan( someDate )
results = Book.findByTitleLikeOrReleaseDateLessThan( "%Something%", someDate )
// find by relationship
results = Book.findAllByAuthor( Author.get(1) )
使用实例查询
你可以使用find方法查询域对象仅仅通过传递一个域对象实例.
def b = Book.find( new Book(title:'The Shining') )
使用criteria builder查询(criteria builder是hibernate架构的一种便捷查询方式)
对于高级的查询或者域对象交叉查询可以使用Criteria (详见 Builders):
def c = Book.createCriteria()
def results = c {
like("author.name", "Stephen%")
between("releaseDate", firstDate, secondDate )
}
使用HQL语言查询(HQL:Hibernate Query Language[hibernate查询语言])
另外,可以使用hibernate本身的查询语言HQL:
def results = Book.find("from Book as b where b.title like 'Lord of the%'")
或者带有参数:
def results = Book.find("from Book as b where b.title like ?", ["The Shi%"])
Document generated by Confluence on Jul 14, 2006 09:01
评论
1 楼
flyisland
2007-04-21
well done!
我是搜索grails+ajax找到你的网站的,目前关注grail的人在数量上的确不多,不过我相信groovy+grail会渐渐获得重视的。希望看到你更多的文章!
我是搜索grails+ajax找到你的网站的,目前关注grail的人在数量上的确不多,不过我相信groovy+grail会渐渐获得重视的。希望看到你更多的文章!
发表评论
-
grails0.22压力测试
2006-11-11 16:58 1799grails0.3终于发布了,不过好像改了很多东西,正在看文档 ... -
grails的命名策略和数据库连接
2006-08-29 07:31 3470grails直接使用hibernate的ImprovedNam ... -
给grails添加text映射支持
2006-08-27 01:45 2627在grails中,domain class的String字段总 ... -
在grails job中碰到的问题的解决
2006-08-15 15:26 2438想在job中直接调用velocity,于是把velocity- ... -
Grails的Ajax
2006-08-15 15:12 4353grails支持ajax,目前可以使用三种库: prototy ... -
Grails的Javascript验证DIY
2006-08-11 11:11 4237看到Grails的validation标签居然是没实现,一下子 ... -
grails的mvc相关功能
2006-08-02 16:45 2722grails的Domain Class/*.gsp(或 ... -
grails的job
2006-08-02 16:44 3532打算再我的项目中引入静态页面的生成,因为这几天看代码看的太紧张 ... -
Grails0.2的一个Bug[输出的html文件内容缺失]修理过程
2006-08-02 16:42 2172[Blog搬家到Javaeye] 一听 ...
相关推荐
文档的最后部分通常包括更新日志和译者日志,记录了文档的版本变更情况以及翻译工作的相关记录,为开发者提供了文档的维护和更新信息。 通过这些知识点的介绍,可以看出GORM不仅仅是一个ORM库,更提供了一整套解决...
Gorm 官方网站 本网站为 ,您可以在访问其内容 为文档做贡献 ...要以您的语言翻译 GORM,您需要在发布请求,以便将其添加到 。 开发本网站 这个网站是用 $ npm install $ npm install hexo -g $ hexo serve
本文档是基于 GORM v1.x 版本的文档翻译的。目前已迁移到上面的新地址。概述全功能ORM(几乎)关联(包含一个,包含多个,属于,多对多,多种包含)Callbacks(创建/保存/更新/删除/查找之前/之后)预加载(急加载)...
通过go-odbc库,Go程序员可以使用标准的sql包来编写数据库操作代码,而这些操作会被翻译成ODBC API的调用,最终与数据库进行交互。 从示例代码可以看出,go-odbc的使用与普通的sql包使用非常类似。首先,通过sql....
无需查询翻译-GORM和Spring Data都使用正则表达式和模式匹配以及运行时生成的代理,以在运行时将Java接口上的方法定义转换为查询。 Micronaut Data中不存在这种运行时转换,并且此工作由Micronaut编译器在编译时...
在IT行业中,技术文章是传播知识、交流经验的重要载体,"paper-code"项目就是这样一个平台,它致力于将优秀的技术文章与个人实践经验相结合,通过翻译、举例说明和分享,帮助开发者深入理解架构设计、模式设计、模型...
在“Go语言中文网”中,你可以找到丰富的学习资源,包括但不限于官方文档的中文翻译、社区讨论、教程、实战案例等,这些都是学习和掌握Go语言的重要途径。Golang中文社区则为开发者提供了一个交流平台,人们可以在...
3. **数据库集成**:为了简化数据访问,可能包含了对流行数据库ORM(如Gorm、Xorm)的集成,提供便捷的数据操作API。 4. **错误处理与日志**:项目可能提供了更强大的错误处理机制,以及结构化的日志系统,便于调试...
5. **数据库接口与ORM**:如Gorm、sqlx,提供方便的数据库操作和对象关系映射。 6. **微服务架构**:学习如何使用Go语言实现微服务,例如Istio、Envoy等。 7. **并发编程**:Go语言的goroutine和channel是其并发模型...
开发设置转到Google翻译:GORM,graphql-go。 Utilizando um banco de dados Postgres。 Para rodar o servidor,simplesmente rodar dentro da意大利面server : go run main.go利用localhost:8000/graphql使用...
2. **数据库**:如Gorm、sqlx,简化了与数据库的交互。 3. **网络编程**:如Net/http,提供HTTP服务器和客户端实现。 4. **并发**:如context、sync,支持Go语言特有的并发模型。 5. **测试**:如 testify、ginkgo,...