显示导航

构建使用 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 如何完成指南

要开始,请执行以下操作

Grails 指南存储库包含两个文件夹

  • initial 初始项目。通常是一个提供一些额外代码以助你快速上手的简单 Grails 应用程序。

  • complete 完成的示例。它是根据指南提出的步骤处理并对 initial 文件夹应用这些更改的结果。

要完成本指南,请转到 initial 文件夹

  • grails-guides/gorm-ratpack/initial 中进行 cd

并按照下一部分中的说明进行操作。

如果你在 grails-guides/gorm-ratpack/complete 中进行 cd,则可以直接转到 完成的示例

3 编写应用程序

3.1 配置构建

编辑 build.gradle 文件以包含 GORM 依赖项。

build.gradle
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。

src/main/groovy/demo/GormModule.groovy
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

现在我们的所有类存根都已就位,让我们继续编辑它们。

src/main/groovy/demo/Manufacturer.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
    }
}
src/main/groovy/demo/domain/Vehicle.groovy
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
    }
}

ManufacturerVehicle 具有一个对多的关系。

我们在 Grails 之外使用 GORM。因此,我们需要使用 grails.gorm.annotation.Entity 为我们的域类添加注释。此外我们实现了 GormEntity 特性。它只是为了帮助在 Grails 之外对 GORM 提供 IDE 支持。

3.4 种子数据

创建一个 Service,以封装应用程序启动时创建样本数据。

/src/main/groovy/demo/BootStrapService.groovy
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 的制造商的车辆列表。

src/main/groovy/demo/ManufacturerHandler.groovy
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 的内容。

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、在启动时填充数据库的 ServiceHandler

运行应用

./gradlew run

您应该可以调用端点

curl "http://localhost:5050"

并获取响应

["audi","ford"]

或者检索制造商的车辆

curl "http://localhost:5050/audi/vehicles"

并获取响应

["A3","A4"]

4 您需要 GORM 或 Grails 的帮助吗?

Object Computing, Inc. (OCI) 赞助本指南的创建。可提供多种咨询和支持服务。

OCI 是 Grails 的家

认识该团队