构建使用 GORM 的 Ratpack 应用程序
了解如何构建一个使用 GORM 作为数据访问工具包的 Ratpack 应用程序
作者:Sergio del Amo
Grails 版本 3.3.1
1 Grails 培训
Grails 培训 - 由创建并积极维护 Grails 框架的人员开发和提供的!
2 入门
在本指南中,你将使用 GORM 构建一个 Ratpack 应用程序。
2.1 所需条件
要完成本指南,你需要以下条件
-
一些时间
-
一个合适的文本编辑器或 IDE
-
安装了 JDK 1.8 或更高版本,且适当地配置了
JAVA_HOME
2.2 如何完成指南
要开始,请执行以下操作
-
下载并解压源代码
或
-
克隆 Git 存储库
git clone https://github.com/grails-guides/gorm-ratpack.git
Grails 指南存储库包含两个文件夹
-
initial
初始项目。通常是一个提供一些额外代码以助你快速上手的简单 Grails 应用程序。 -
complete
完成的示例。它是根据指南提出的步骤处理并对initial
文件夹应用这些更改的结果。
要完成本指南,请转到 initial
文件夹
-
在
grails-guides/gorm-ratpack/initial
中进行cd
并按照下一部分中的说明进行操作。
如果你在 grails-guides/gorm-ratpack/complete 中进行 cd ,则可以直接转到 完成的示例 |
3 编写应用程序
3.1 配置构建
编辑 build.gradle 文件以包含 GORM 依赖项。
dependencies {
compile "org.grails:grails-datastore-gorm-hibernate5:6.1.6.RELEASE"
runtime "com.h2database:h2:1.4.192"
runtime "org.apache.tomcat:tomcat-jdbc:8.5.0"
runtime "org.apache.tomcat.embed:tomcat-embed-logging-log4j:8.5.0"
runtime "org.slf4j:slf4j-api:1.7.10"
}
本指南使用 H2,一个内存数据库。
阅读 GORM 文档 了解更多信息。
3.2 GORM 配置
本指南中开发的 Ratpack 应用程序使用 Google Guice。 Google Guice 提供了模块的概念,这是一种提供对象的配方。
创建一个模块来配置 GORM。
package demo
import com.google.inject.AbstractModule
import com.google.inject.Provides
import groovy.transform.CompileStatic
import org.grails.orm.hibernate.HibernateDatastore
@CompileStatic
class GormModule extends AbstractModule {
@Override
protected void configure() {}
@Provides
HibernateDatastore hibernateDatastore() {
Map<String, Object> configuration = [
'hibernate.hbm2ddl.auto':'create-drop',
'dataSource.url':'jdbc:h2:mem:myDB'
] as Map<String, Object>
new HibernateDatastore(configuration, getClass().getPackage())
}
}
在独立使用时,可以通过向独立使用时,可以通过向 org.grails.orm.hibernate.HibernateDatastore
类传递一个 Map 或 PropertyResolver
接口的实例来配置 Hibernate 专用的 GORM。
3.3 创建域
创建两个域对象。
-
Manufacturer.groovy
-
Vehicle.groovy
随意使用您最喜欢的 IDE 创建它们或执行以下操作
$ cd complete/src/main/groovy/demo
$ touch Manufacturer.groovy
$ touch Vehicle.groovy
现在我们的所有类存根都已就位,让我们继续编辑它们。
package demo
import grails.gorm.annotation.Entity
import groovy.transform.ToString
import org.grails.datastore.gorm.GormEntity
@ToString
@Entity
class Manufacturer implements GormEntity<Manufacturer> {
String name
static hasMany = [vehicles: Vehicle]
static constraints = {
name blank: false
}
}
package demo
import grails.gorm.annotation.Entity
import org.grails.datastore.gorm.GormEntity
import groovy.transform.ToString
@ToString
@Entity
class Vehicle implements GormEntity<Vehicle> {
String name
Integer year
static belongsTo = [manufacturer: Manufacturer]
static constraints = {
name nullable: false, blank: false
}
}
Manufacturer
和 Vehicle
具有一个对多的关系。
我们在 Grails 之外使用 GORM。因此,我们需要使用 grails.gorm.annotation.Entity
为我们的域类添加注释。此外我们实现了 GormEntity
特性。它只是为了帮助在 Grails 之外对 GORM 提供 IDE 支持。
3.4 种子数据
创建一个 Service
,以封装应用程序启动时创建样本数据。
package demo
import grails.gorm.transactions.Transactional
import groovy.transform.CompileStatic
import org.grails.orm.hibernate.HibernateDatastore
import ratpack.exec.Blocking
import ratpack.service.Service
import ratpack.service.StartEvent
@CompileStatic
class BootStrapService implements Service {
void onStart(StartEvent e) throws Exception {
e.getRegistry().get(HibernateDatastore)
Blocking.exec {
populateWithSampleData()
}
}
@Transactional
void populateWithSampleData() {
Manufacturer audi = new Manufacturer(name: 'audi')
audi.addToVehicles(new Vehicle(name: 'A3', year: 1996))
audi.addToVehicles(new Vehicle(name: 'A4', year: 1994))
audi.save()
Manufacturer ford = new Manufacturer(name: 'ford')
ford.addToVehicles(new Vehicle(name: 'Ford KA', year: 1996))
ford.save()
}
}
3.5 创建处理程序
创建一个 Handler
。我们处理两个请求。
对 /
的请求返回制造商列表。对 /audi/vehicles
的请求返回名为 audi
的制造商的车辆列表。
package demo
import grails.gorm.transactions.ReadOnly
import groovy.transform.CompileStatic
import ratpack.exec.Blocking
import ratpack.groovy.handling.GroovyContext
import ratpack.groovy.handling.GroovyHandler
import static ratpack.jackson.Jackson.json
@CompileStatic
class ManufacturerHandler extends GroovyHandler {
@Override
protected void handle(GroovyContext context) {
String manufacturerName = context.pathTokens.id
Blocking.get {
manufacturerName ? findAllVehicleNameByManufacturerName(manufacturerName) : findAllManufacturerName()
} then { names ->
context.render(json(names))
}
}
@ReadOnly
List<String> findAllVehicleNameByManufacturerName(String manufacturerName) {
Vehicle.where { manufacturer.name == manufacturerName }.projections {
property('name')
}.list() as List<String>
}
@ReadOnly
List<String> findAllManufacturerName() {
Manufacturer.where {}.projections {
property('name')
}.list() as List<String>
}
}
3.6 Ratpack.groovy
替换 src/ratpack/Ratpack.groovy
的内容。
import demo.BootStrapService
import demo.GormModule
import demo.ManufacturerHandler
import static ratpack.groovy.Groovy.ratpack
ratpack {
bindings {
module GormModule
bindInstance new BootStrapService()
add(new ManufacturerHandler())
}
handlers {
get(":id/vehicles", ManufacturerHandler)
get(ManufacturerHandler)
}
}
之前的代码注册了配置 GORM 的 Module
、在启动时填充数据库的 Service
和 Handler
。
运行应用
./gradlew run
您应该可以调用端点
curl "http://localhost:5050"
并获取响应
["audi","ford"]
或者检索制造商的车辆
curl "http://localhost:5050/audi/vehicles"
并获取响应
["A3","A4"]