Grails框架之Domain与GORM

一 Grails概述

“Simplicity is the ultimate sophistication”-Lenardo da Vinci

如上艺术大师达芬奇所述,“简约是最终的复杂形式”,最美的东西往往是最本质、最简单的东西。Grails就是为了简化Java-Web企业级应用开发而生的轻量级开源框架。传统的Java程序员经历过编写复杂而令人生畏的XML配置文件,Grails基于“Convention is over Configuration”(约定大于配置)和“Don‘t Repeat Yourself”(不要重复造轮子)的开发理念,开发人员无需再手动编写复杂繁琐的配置,而将更多的精力专注于业务逻辑从而大大提高开发效率。Grails是构建于Spring和Hibernate之上的更高抽象层技术,其基于JVM并使用Groovy动态语言,可以无缝整合Java平台的开发技术。通俗来说,Grails即为基于传统Java开发技术之上而简化的专门用于快速构建小型Web应用的框架,其主要基于Hibernate、Spring、SiteMesh(一个健壮且稳定的页面布局渲染框架)、Tomcat、H2(一个利用纯Java技术实现的关系型数据库管理系统)。技术栈组件间关系如下图所示:

确切说Grails是一个全栈的开发环境而不仅仅是个Web开源框架,由上图可以看出Grails完全基于Java生态系统,其中Groovy是由Java5衍生出来的更为灵活的动态语言,它和Java无缝融合,并基于JDK之上,共用绝大部分的API。因此,Java程序员掌握Grails框架是件容易的事情。

Grails的优势主要体现在开发效率高,适用于快速构建小型的Web应用,可以满足大多数对系统要求不是很高的开发,但凡物必有其短。Grails是基于传统开源框架之上更高的抽象层技术,底层实现均已得到良好的封装,因此尚不能很好的胜任构建大型的企业级应用开发,这或许是Grails一直处于开源社区但却没有很好的推广的原因,所以给人的感觉此项技术很小众,缺乏良好的应用前景。架构上,Grails摈弃了传统的DAO层,直接分为view(视图)层、Controller(控制)层、Service(业务逻辑)层3 层架构,其具体请求处理逻辑如下图所示:

二 Domain数据模型设计

Domain实体类在任何的应用场景中都处于核心位置,它是数据的封装抽象形式,所以其重要性不言而喻。Grails框架中Domain实体类主要用于数据模型设计,可以定义其约束及实体类间关系,并映射为数据库的表间关系。案例是描述事物的良好方式,可以使得抽象复杂的概念具象化、简单化。假设现需构建一个在线歌曲商城应用,用户可以购买歌曲,评论歌曲,预览歌曲等,为简化描述问题先不考虑系统的实现方式,按需求分析该应用至少比包括Artist(艺术家)、Album(专辑)、Song(歌曲)3个实体,每个实体具有其特有的属性,约定每位Artist(艺术家)将拥有多张Album(专辑),而每张专辑收录多首Song(歌曲)。

数据持久化是开发中经常应用的操作,Grails将每一个实体类映射为数据库中的一张表,属性映射为对应字段。为保证数据的完整性和避免产生脏数据,Grails Domain Class可以同时设置约束和表间关系。Grails为domain class之间提供了多种关系,包括one-to-one(最简单),比如Car和Engine之间是一对一的关系

Class Car{
    Engine engine
}
Class Engine{
   Car car
}

该模型间是双向的一对一关系,并没有从属关系,但在实际情况中,我们会经常遇到实体间的从属关系,例如An Engine belongs to a Car,but a Car does not belong to an Engine  Grails提供实现该关系的机制。

Class car{
    Engine engine
}

Class Engine{
    static  belongsTo=[car:Car]
}//An Engine belongs to a Car

Engine类中belongsTo属性值是一个Map,键值key是car(Car类的引用),belongsTo表明Car实体是关系的拥有者,此时数据库中Car表中引用Engine主键id作为其外键,但Engine表中并无外键应用。若想Engine中引用Car表的主键id作为其外键,可以将二者的关系定义为:

Class Car{
    Engine engine
   static hasOne=[engine:Engine]
}
Class Engine{
    static belongsTo=[car:Car]
}

若An Engine belongsTo a Car,but has no reference to its owner,可以定位Engine实体为:

Class Engine{
   static belongsTo=Car
}//此时Engine表中并无引用Car表的外键

回归到案例本身,Grails中one-to-many同样非常简单,按需求分析得:(Artist与Album之间为1对多关系;Album与Song之间也为一对多关系),在定义关系的同时同时可以定义约束:

//艺术家
class Artist {
    String name
    static constraints = {
       name(nullable: false,unique: true)//定义非空唯一约束
    }
    static mapping = {
        version(false) //消除version默认属性
        id:‘identity‘ //主键自增
    }
    static hasMany = [albums:Album] //与Album建立一对多关系
}
//专辑
class Album {
    String title
    static constraints = {
    }
    static mapping = {
        version(false)
        id:‘identity‘
    }
    static hasMany = [songs:Song] //与Song建立一对多关系
    static  belongsTo = [artist:Artist]  //Album表外键引用Artist表的主键
}
//歌曲
class Song {
    String title
    Integer duration //歌曲时长

    static constraints = {
        title (blank: false,unique: true)
    }
    static mapping = {
        version(false)
        id:‘identity‘
        duration(min:1)
    }
    static  belongsTo = [album:Album] //Song表中外键应用Album表主键
}

此时实体间关系为: 此时数据库中映射为Artist、Album、Song三张表,其中Artist与Album以artist_id关联,Album与Song以Album_id关联。

Hibnerate对Grails底层做了良好的封装,使得常规的CRUD操作变得异常简单,实体类只需调用API即可完成数据持久化操作,在此不再展开描述

二 GORM原理

时间: 2024-08-27 18:14:20

Grails框架之Domain与GORM的相关文章

grails框架的g:paginate分页标签的使用

我用到的grails是2.4.4. 该版本下游一个标签g:paginate 该标签下有以下几个参数:total(必须要填写的项).controller.action.prev.max.offset等等,我用到的有这几个参数,详细参数的使用参考API文档. 普通分页:(Tsystemparam是我代码的一个域类) 后台代码:写在控制器下需要执行的方法 params.max=5//给params参数附一个map集合key=max.value=5,每页展示的数据条数 \\跳转到showsysParam

Grails 配置

也许在这里谈论配置对于一个“约定优于配置”的框架来说,这可能比较奇怪,但这些配置通常都是一次性,我们最好还是先了解他们的大概. 由于Grails提供了默认设置,你确实可以在不做任何配置的情况下进行开发和应用.Grails也内嵌了一个Web容器和一个称为HSQLDB的内存数据库,这意味着你甚至都不用安装数据库了. 不过,在将来某些情况下你还是会想要安装一个真正的数据库的,我们将在随后的一些章节进行描述. 1 基本配置 Grails提供了一个名为 grails-app/conf/Config.gro

windows8.1操作系统cmd下grails命令无效

最近决定使用intellij idea工具来开发基于Grails框架的应用程序,,在安装好jdk 1.7以及配置好jdk和grails环境变量后进行grails测试,在win8.1的命令行窗口中输入以下命令发现无法创建应用程序: 图一 反复尝试,在win8.1的环境下无法像win7环境下正确创建一个application,最终找到的解决办法是: 不要首先输入grails命令后再输入create-app等命令,如果要创建grails application,那么cmd打开命令行窗口后直接输入gra

grails 呈现html ckeditor

Grails框架,用ckeditor获取的用户编辑的富文本,需要呈现出来,中有如下问题: 1.恶意代码危险: 当呈现HTML文件或XHTML文件时,你必须对每个对象调用encodeAsHTML(). 2.如何呈现为html,而非源代码. 如一段文本<a href=www.baidu.com>百度</a>,想呈现成      百度 方法1.在gsp中直接使用${content}会呈现源代码,应该使用${raw(content)} ,或者<%=expression%>(这个

Micronaut 教程:如何使用基于 JVM 的框架构建微服务?

本文要点: Micronaut 是一种基于 jvm 的现代化全栈框架,用于构建模块化且易于测试的微服务应用程序.Micronaut 提供完全的编译时.反射无关的依赖注入和 AOP.该框架的开发团队和 Grails 框架的开发团队是同一个.Micronaut 框架集成了云技术,服务发现.分布式跟踪.断路器等微服务模式也内置到了框架中.在本教程中,你将使用不同的语言创建三个微服务:Java.Kotlin 和 Groovy.你还将了解使用 Micronaut HTTP 客户端消费其他微服务是多么容易,

主流脚本语言的比较和选择

主流脚本语言的比较和选择 —— Hywhy 过去这一年的时间里,我买了不少书,查了很多资料,可以算是认真的学习了几种主流的脚本 语言,因为我一直想搞一个好用的自动化工具,来方便我们的系统维护.虽然这个愿望还没有达成,但是在这个过程中,还是学到了很多东西.今天下午,跟同事们 聊天时,说到了脚本语言,这是比较难得的,也正好借这个契机,把我的一些看法说一说,有不妥和错误的地方,请大家多指正. 为什么选择脚本语言 为什么选择脚本语言,可能每个人面对的实际情况都不一样.语言本身没有好坏之分,只有合适或者不

Nhibernate学习教程(2)-- 第一个NHibernate程序

NHibernate之旅(2):第一个NHibernate程序 本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4-1.设计持久化类 4-2.编写映射文件 5.数据访问层 5-1.辅助类 5-2.编写操作 6.数据访问层的测试 6-1.配置NHibernate 6-2.测试 结语 开始使用NHibernate 我们亲自动手,一步一步搭建一个NHibernate程序来,我以一个实际场景电子交易程序来模拟,客户/订单

NHibernate之旅(2):第一个NHibernate程序

本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4-1.设计持久化类 4-2.编写映射文件 5.数据访问层 5-1.辅助类 5-2.编写操作 6.数据访问层的测试 6-1.配置NHibernate 6-2.测试 结语 作者注:2009-11-06已更新 开始使用NHibernate 我们亲自动手,一步一步搭建一个NHibernate程序来,我以一个实际场景电子交易程序来模拟,客户/订单/产品的经典组合.由于是第一

我的NHibernate之行(一):NHibernate五部曲

NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去.--百度百科 简介 从网上找到下面的一张图,自认为这张图相当好: 简单的说ORM,能够达到这样一种效果:我们不用去知道数据库(R)的内容,系统根据M,通过对对象(O)的操作,自动完成访问数据库.例如要完成"根据ID查询",我们对对象使用了Get<