Учебные материалы

Доступ к данным с GORM

Этот урок освещает пошаговое создание Spring Boot приложения с использованием Grails Object Relational Mapper (GORM) и Hibernate.

Что вы создадите

Вы создадите Spring приложение, которое сохраняет данные в БД в памяти с использованием GORM.

В этом уроке используется только библиотека Grails GORM. Вы не обязаны использовать весь web-стек Grails.

Что вам потребуется

  • Примерно 15 минут свободного времени
  • Любимый текстовый редактор или IDE
  • JDK 7 и выше
  • Gradle 1.8+
  • Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.

Как проходить этот урок

Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.

Чтобы начать с нуля, перейдите в Настройка проекта.

Чтобы пропустить базовые шаги, выполните следующее:

Когда вы закончите, можете сравнить получившийся результат с образцом в gs-accessing-data-gorm/complete.

Настройка проекта

Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle. Если вы не знакомы с ней, ознакомьтесь с соответсвующим уроком Сборка Java-проекта с использованием Gradle.

Создание структуры каталогов

В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру, командой mkdir -p src/main/groovy/hello для *nix систем:

└── src
    └── main
        └── groovy
            └── hello

Создание файла сборки Gradle

Ниже представлен начальный файл сборки Gradle. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.

Если вы посмотрите на pom.xml, вы найдете, что указана версия для maven-compiler-plugin. В общем, это не рекомендуется делать. В данном случае он предназначен для решения проблем с нашей CI системы, которая по умолчанию имеет старую(до Java 5) версию этого плагина.

build.gradle

buildscript {
    repositories {
        maven { url "https://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE")
    }
}

apply plugin: 'groovy'
apply plugin: 'spring-boot'

jar {
    baseName = 'gs-accessing-data-gorm'
    version =  '0.1.0'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "https://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.grails:gorm-hibernate4-spring-boot:1.1.0.RELEASE")
    runtime("com.h2database:h2")
    testCompile("junit:junit")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

Spring Boot gradle plugin предоставляет множество удобных возможностей:

  • Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
  • Он ищет public static void main() метод, как признак исполняемого класса
  • Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий

Создание GORM сущности

В этом примере мы моделируем простую сущность Person с использованием GORM:

src/main/groovy/hello/Person.groovy

package hello

import grails.persistence.*

@Entity
class Person {
    String firstName
    String lastName

    static constraints = {
        firstName blank:false
        lastName blank:false
    }
}

Блок ограничения описывает любые правила валидации. В данном случае, накладывается ограничение только на использование непустых полей.

Создание контроллера ресурсов

Создайте контроллер для вашего Groovy Spring приложения:

src/main/groovy/hello/GreetingController.groovy

package hello

import org.springframework.web.bind.annotation.*
import org.springframework.http.*
import static org.springframework.web.bind.annotation.RequestMethod.*

@RestController
class GreetingController {

    @RequestMapping(value="/person/greet", method = GET)
    String greet(String firstName) {
        def p = Person.findByFirstName(firstName)
        return p ? "Hello ${p.firstName}!" : "Person not found"
    }

    @RequestMapping(value = '/person/add', method = POST)
    ResponseEntity addPerson(String firstName, String lastName) {
        Person.withTransaction {
            def p = new Person(firstName: firstName, lastName: lastName).save()
            if(p) {
                return new ResponseEntity(HttpStatus.CREATED)
            }
            else {
                return new ResponseEntity(HttpStatus.BAD_REQUEST)
            }
        }
    }

}

Пример описывает две REST точки выхода:

  • addPerson позволяет добавлять нового человека
  • greet приветствует человека по его имени

Далее вы увидите как запустить приложение и создать новую сущность Person.

Создание приложения исполняемым

Несмотря на то, что пакет этого сервиса может быть в составе web-приложения и WAR файлов, более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение. Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый старый main() Java-метод. Попутно, вы используете поддержку Spring для встроенного Tomcat контейнера сервлетов как HTTP среду выполнения вместо развертывания на сторонний экземпляр.

src/main/groovy/hello/Application.groovy

package hello

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.ComponentScan

@EnableAutoConfiguration
@ComponentScan
class Application {
    static void main(String[] args) {
        SpringApplication.run Application, args
    }
}

main() метод передает управление вспомогательному классу SpringApplication, где Application.class - аргумент его run() метода. Это сообщает Spring о чтении метаданных аннотации из Application и управлении ею как компонента в Spring application context.

Аннотация @ComponentScan говорит Spring'у рекурсивно искать в пакете hello и его потомках классы, помеченные прямо или косвенно Spring аннотацией @Component. Эта директива гарантирует, что Spring найдет и зарегистрирует GreetingController, потому что он отмечен @Controller, который, в свою очередь, является своего рода @Component аннотацией.

Аннотация @EnableAutoConfiguration переключает на приемлемое по умолчанию поведение, основанное на содержании вашего classpath. К примеру, т.к. приложение зависит от встраиваемой версии Tomcat (tomcat-embed-core.jar), Tomcat сервер установлен и сконфигурирован на приемлемое по умолчанию поведение от вашего имени. И т.к. приложение также зависит от Spring MVC (spring-webmvc.jar), Spring MVC DispatcherServlet сконфигурирован и зарегестрирован для вас - web.xml не нужен! Автоконфигурация полезный и гибкий механизм. Подробную информацию смотрите в API документации.

Сборка исполняемого JAR

Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.

./gradlew build

Затем вы можете запустить JAR-файл:

java -jar build/libs/gs-accessing-data-gorm-0.1.0.jar

Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run, либо вы можете собрать приложение с mvn clean package и запустить JAR примерно так:

java -jar target/gs-accessing-data-gorm-0.1.0.jar
Процедура, описанная выше, создает исполняемый JAR. Вы также можете вместо него собрать классический WAR-файл.

Запуск приложения

Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:

./gradlew clean build && java -jar build/libs/gs-accessing-data-gorm-0.1.0.jar
Если вы используете Maven, то можете запустить ваш сервис таким образом: mvn clean package && java -jar target/gs-accessing-data-gorm-0.1.0.jar.

Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:

./gradlew bootRun
С mvn - mvn spring-boot:run.

Тестирование приложения

Когда приложение запустится, вы можете создать нового человека, отправив POST запрос. К примеру, используя *nix инструмент curl:

$ curl -i -X POST -d "firstName=Homer&lastName=Simpson" http://localhost:8080/person/add

Результат ответа, показанном ниже, указывает на то, что ресурс был создан:

HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Content-Length: 0
Date: Wed, 19 Feb 2014 13:21:06 GMT

Затем вы можете отправить GET запрос на /greet для получения приветствия:

$ curl -i http://localhost:8080/person/greet?firstName=Homer
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 12
Date: Wed, 19 Feb 2014 13:22:15 GMT

Hello Homer!

Поддержка Groovy Script

Предыдущий пример требовал от вас установки системы сборки Gradle или Maven, но вы можете также использовать GORM в простом Groovy скрипте.

Как пример, создайте новый файл app.groovy и поместите в него следующий код:

app.groovy

@Grab("org.grails:gorm-hibernate4-spring-boot:1.1.0.RELEASE")
@Grab("h2")
import grails.persistence.*
import org.springframework.http.*
import static org.springframework.web.bind.annotation.RequestMethod.*

@RestController
class GreetingController {

    @RequestMapping(value="/person/greet", method = GET)
    String greet(String firstName) {
        def p = Person.findByFirstName(firstName)
        return p ? "Hello ${p.firstName}!" : "Person not found"
    }

    @RequestMapping(value = '/person/add', method = POST)
    ResponseEntity addPerson(String firstName) {
        Person.withTransaction {
            def p = new Person(firstName: firstName).save()
            return new ResponseEntity( p ? HttpStatus.CREATED : HttpStatus.BAD_REQUEST)
        }
    }
}

@Entity
class Person {
    String firstName
}
Не имеет значения, где расположен файл.

Далее, установите Spring Boot CLI.

Запустите его как показано ниже:

$ spring run app.groovy
Предполагается, что вы завершили предыдущее приложение, дабы избежать коллизии портов.

Настройка DataSource

javax.sql.DataSource, используемый для создания соединений, может быть настроен в соответствии с инструкцией руководства пользователя Spring Boot.

Итог

Поздравляем! Вы только что создали Spring приложение с использованием GORM для доступа к данным.

С оригинальным текстом урока вы можете ознакомиться на spring.io.

comments powered by Disqus