1. 概述
本文是对 Grails 3 框架及其核心 ORM 组件 GORM 的快速入门指南,适合有一定 Java/Groovy 开发经验的后端开发者参考。
Grails 是一个基于 Groovy 语言的全栈 Web 框架,底层深度集成了一系列成熟的 Java 技术栈:
- ✅ GORM:基于 Hibernate 实现的领域对象持久化层
- ✅ Spring Framework:提供依赖注入(DI)和应用上下文管理
- ✅ SiteMesh:负责页面布局与主题渲染
- ✅ Hibernate:作为默认的 JPA 实现,处理数据库映射与操作
简单来说,Grails 就是把这些主流技术“组装”起来,并通过约定优于配置(convention over configuration)的理念,让你用更少的代码快速搭建出功能完整的 Web 应用。
⚠️ 注意:虽然 Grails 使用 Groovy 编写,但与 Java 完全兼容。你可以混合使用 Java 类和 Groovy 类,无缝接入现有项目。
2. 数据源配置
默认情况下,Grails 在开发(development)和测试(test)环境中使用 HSQLDB 内存数据库,开箱即用,无需额外配置。
但实际开发中我们通常需要切换到 MySQL、PostgreSQL 等生产级数据库。这时可以通过修改 application.yml
文件来自定义数据源。
示例:配置 MySQL 数据源
environments:
development:
dataSource:
driverClassName: "com.mysql.cj.jdbc.Driver"
url: "jdbc:mysql://localhost:3306/grails_dev"
username: "root"
password: "password123"
dialect: org.hibernate.dialect.MySQL8Dialect
✅ 支持多环境配置,如 test
、production
可独立设置不同数据库。
✅ 推荐使用 com.mysql.cj.jdbc.Driver
(MySQL 8+ 驱动),避免使用已废弃的 com.mysql.jdbc.Driver
。
⚠️ 注意 URL 端口是否正确(MySQL 默认 3306,不是 8080)。
3. 领域模型(Domain)
Grails 的一大优势是自动建表能力。只要定义好 Domain 类,框架会根据 dbCreate
策略(如 create-drop
、update
)自动创建或更新数据库表结构。
定义 User 领域类
class User {
String userName
String password
String email
Integer age // 建议使用 Integer 而非 String
static constraints = {
userName blank: false, unique: true
password size: 5..10, blank: false
email email: true, blank: true
age min: 1, max: 150
}
static mapping = {
sort "userName"
table "users" // 自定义表名
}
}
关键特性说明:
- ✅ constraints:内联定义校验规则,无需注解(annotation-free),简洁直观
- ✅ 自动触发验证:调用
save()
时自动校验,失败返回errors
对象 - ✅ mapping:可指定排序、表名、索引等 ORM 映射行为
比如设置了 sort "userName"
后:
List<User> users = User.list() // 返回结果已按 userName 升序排列
当然你也可以在查询时手动指定排序:
User.list(sort: "userName", order: "desc")
但模型层统一定义更利于维护,避免到处写重复逻辑。
4. CRUD 操作
Grails 提供了两种方式生成基础 CRUD 接口:动态脚手架(Scaffolding)和静态代码生成。
✅ 动态脚手架(Dynamic Scaffolding)
只需一行代码,运行时自动生成完整 CRUD 接口:
class UserController {
static scaffold = true
}
框架会在运行时动态注入以下方法并暴露为 HTTP 接口:
index()
→ 列表页show(id)
→ 查看详情create()
/save()
→ 创建edit(id)
/update()
→ 修改delete(id)
→ 删除
✅ 适合快速原型开发
❌ 不推荐用于生产环境(缺乏灵活性)
✅ 静态脚手架(Static Scaffolding)
通过命令生成真实可编辑的控制器和视图代码:
# 仅生成视图
grails generate-views User
# 生成控制器 + 视图
grails generate-controller User
# 一键生成全部(推荐用于初学者)
grails generate-all User
生成的代码完全可控,便于定制业务逻辑,是生产项目的首选方式。
手动 CRUD 示例(GORM API 实践)
创建用户
def user = new User(
userName: "alice",
password: "pass123",
email: "alice@example.com",
age: 25
)
user.save(flush: true) // flush: true 表示立即执行 SQL
⚠️ 若 save 失败,可通过
user.errors
查看具体校验错误
查询单条记录
// 可编辑模式(默认)
def user = User.get(1)
// 只读模式(性能更优,适合仅展示场景)
def user = User.read(1)
✅
read()
使用 Hibernate 的load()
语义,延迟加载且不加入一级缓存
更新记录
def user = User.get(1)
user.userName = "alice_update"
user.age = 26
user.save(flush: true)
❗ 注意:必须先
get
再修改,不能直接new User(id:1).save()
(会插入新记录)
删除记录
def user = User.get(1)
user.delete(flush: true)
✅ 支持级联删除(需在 domain 中配置
hasMany
和belongsTo
)
5. GORM 查询
GORM 提供了多种灵活的数据检索方式,远比原生 HQL 更简洁。
5.1 find:HQL 查询
支持标准 HQL 语法:
def user = User.find("from User as u where u.userName = 'alice'")
支持参数化查询(推荐):
// 位置参数
def user = User.find("from User where userName = ?", ["alice"])
// 命名参数(更清晰)
def user = User.find("from User where userName = :username", [username: "alice"])
✅ 参数化可防止 SQL 注入,强烈建议使用
5.2 findBy:动态查找器
Grails 最实用的功能之一 —— 根据属性名自动生成查询方法。
def user = User.findByUserName("alice")
def user = User.findByUserNameAndAge("alice", 25)
def user = User.findByUserNameLike("ali%")
def user = User.findByAgeGreaterThanAndAgeLessThan(18, 60)
def user = User.findByUserNameNotEqual("admin")
✅ 方法名即 DSL,见名知意
✅ 支持 And
、Or
、NotEqual
、IsNull
、Between
等关键词
✅ 查询结果为单个对象(null 安全)
完整支持的操作符见官方文档:GORM Finders
5.3 Criteria:条件查询
适用于复杂查询场景,支持嵌套条件、分页、排序等。
def results = User.createCriteria().list {
projections {
property('id')
property('userName')
}
like("userName", "a%")
between("age", 18, 60)
and {
isNotNull("email")
eq("active", true)
}
order("userName", "asc")
maxResults(10)
firstResult(0)
}
⚠️ 注意:闭包 {}
是 Criteria 的语法要求,不能用 ()
✅ 支持 projections
实现 select 部分子段
✅ 可组合多个条件,逻辑清晰
5.4 executeQuery / executeUpdate:原生 HQL 操作
查询(executeQuery)
def usernames = User.executeQuery(
"SELECT u.userName FROM User u WHERE u.age > :minAge",
[minAge: 18]
)
返回的是 List,常用于聚合查询或只取部分字段。
更新/删除(executeUpdate)
// 批量删除
def rowCount = User.executeUpdate(
"DELETE User WHERE userName = :name",
[name: "temp_user"]
)
// 批量更新
def updated = User.executeUpdate(
"UPDATE User SET password = :newPass WHERE userName = :name",
[newPass: "new123", name: "alice"]
)
✅ 支持批量操作,性能优于逐条 save/delete
⚠️ 注意:executeUpdate
不触发 beforeUpdate
等事件钩子
6. 总结
Grails 3 是一个成熟、高效的全栈框架,特别适合需要快速交付的中小型项目。其核心亮点在于:
- ✅ 约定优于配置:减少样板代码,提升开发效率
- ✅ GORM 强大易用:支持动态查询、Criteria、HQL 多种方式
- ✅ 脚手架机制:快速生成 CRUD,加速原型开发
- ✅ 无缝集成 Spring + Hibernate:企业级能力背书
虽然近年来 Spring Boot 更为主流,但在 Groovy 技术栈或遗留 Grails 项目中,掌握 GORM 和基本开发模式仍是必备技能。
📌 建议:新手可从 generate-all
入手,理解生成代码后再逐步自定义;老手则可直接手写 Controller + GORM 查询,更灵活高效。