Работа с Grails: GORM — Забавное название и серьезная технология

Защита

В прошлом месяце вводная статья серии Работа с Grails познакомила с новым каркасом для разработки Web-приложений, называемым Grails. Grails включает в себя такие современные подходы, как MVC (Model-View-Controller — модель-представление-контроллер), разделение обязанностей (separation of concerns) и соглашение по конфигурации (convention over configuration). В сочетании со встроенными возможностями скаффолдинга Grails позволяет получить первую работающую версию Web-сайта за несколько минут.

Эта статья посвящена другой области, которую также упрощает Grails: долговременному сохранению объектов с помощью API GORM. Статья начинается с описания того, что такое ORM (object-relational mapper — объектно-реляционный преобразователь) и как создать отношение типа «один ко многим». Далее рассказывается о проверке данных, гарантирующей, что приложение не будет поражено синдромом garbage in/garbage out (неправильные данные на входе/неправильные данные на выходе). Будет показано практическое использование Grails ORM DSL (domain-specific language — язык для конкретной доменной области), который позволяет детально настраивать способ постоянного сохранения POGO-объектов (plain old Groovy objects — обычные старые Groovy-объекты) за рамками приложения. Наконец, будет показано, как легко переключиться с одной реляционной базы данных на другую. Подойдет любая база данных, поддерживающая JDBC-драйвер и Hibernate-диалект.

Об этой серии статей

Grails — это современный каркас для разработки Web-приложений, соединяющий известные Java-технологии, например, Spring и Hibernate с современными подходами типа «соглашение по конфигурации» (convention over configuration). Будучи написан на Groovy, Grails обеспечивает прозрачную интеграцию с существующим Java-кодом, одновременно добавляя гибкость и динамику языков сценариев. После изучения Grails ваши взгляды на Web-разработку изменятся навсегда.

Определение ORM

Реляционные базы известны с конца 70-х годов, а разработчикам ПО до сих пор приходится тратить силы на то, чтобы эффективно сохранять в них объекты и загружать обратно. Современное ПО основано на объектно-ориентированных принципах, а не на реляционном подходе, используемом в большинстве популярных баз данных.

Образовался целый класс программ — ORM (объектно-реляционный преобразователь) — для облегчения задачи перемещения данных между базами данных и кодом и обратно. В частности, эту проблему пытаются решить три популярных Java API — Hibernate, TopLink и JPA (Java Persistence API — Java API для перманентного хранения объектов) (см. раздел Ресурсы), хотя ни один из них не является идеальным. Эта проблема настолько постоянна (случайный каламбур), что у нее даже есть собственное название: object-relational impedance mismatch (объектно-реляционное рассогласование) (см. раздел Ресурсы).

GORM — это «тонкий» Groovy-фасад над Hibernate. (По-видимому, «Gibernate» показалось создателям не таким благозвучным, как «GORM»). Это значит, что все существующие для Hibernate приемы работают и здесь; например, полностью поддерживаются HBM-файлы для преобразования и аннотирования. Однако эта статья фокусируется на интересных новых возможностях, которые привносит GORM.
Объектно-ориентированные базы данных и Grails

Некоторые разработчики пытаются устранить проблему «объектно-реляционного рассогласования», используя базы данных, поддерживающие объекты естественным способом. Серия статей The busy Java developer’s guide to db4o Теда Ньюарда (Ted Neward) на страницах developerWorks хорошо освещает этот предмет, показывая современные объектно-ориентированные базы на практике. Было бы здорово, если бы какой-нибудь J2EE-программист написал db4o-плагин для Grails, доказав, что объектно-ориентированные базы данных так же готовы к профессиональному использованию, как и их реляционные аналоги. Однако пока использование GORM и традиционной реляционной базы данных — это лучшая стратегия для перманентного хранения объектов в Grails.

Создание связей «один-ко-многим»

Сохранение POGO-объектов в таблицы базы данных на первый взгляд кажется не такой уж сложной задачей. Действительно если один POGO-объект отображается на одну таблицу, в этом нет ничего сложного, свойства POGO-объекта идеально совпадают со столбцами таблицы. Но если объектная модель сколько-нибудь сложна, например, содержит два POGO-объекта, связанных между собой, задача может резко усложниться.

Например, рассмотрим Web-сайт приложения Trip Planner, разработка которого была начата в прошлой статье. Неудивительно, что POGO-объект Trip играет важную роль в приложении. Откройте файл Open grails-app/domain/Trip.groovy (см. листинг 1) в текстовом редакторе: