ドメインクラスのDDLを見てみる
テーブル自動生成はHibernateのSchemaExport(hbm2ddl)を使っているので、特にGrailsだからというものではないのですが自動生成されるドメインクラスのテーブルを見てみます。grails-app/conf/Config.groovyでhibernate="off"となっている部分を"on"に変えると、HibernateのSQLがログに出力されるようになります。
テスト用のドメインクラスは↓でone-to-manyの関連が設定してあります。DBはHSQLです。
class Author { static hasMany = [ books : Book ] String name } class Book { static belongsTo = [author:Author] String title String description Date dateCreated Date lastUpdated }
これだと、
-- Authorテーブル create table author ( id bigint generated by default as identity (start with 1), version bigint not null, name varchar(255) not null, primary key (id) ) -- Bookテーブル create table book ( id bigint generated by default as identity (start with 1), version bigint not null, author_id bigint not null, date_created timestamp not null, description varchar(255) not null, last_updated timestamp not null, title varchar(255) not null, primary key (id) ) -- 外部キー alter table book add constraint FK2E3AE9CD85EDFA foreign key (author_id) references author
こうなります。
constraint
基本的には全ての列が"not null"で定義されます。BootStrap.groovyでテストデータを挿入しようとしたときに、nullのプロパティがあるために挿入されず無視されてしまい、ちょっとはまりました。
nullを許可する場合には以下の様にconstraintで設定します。また、Stringのプロパティはvarchar(255)で定義されていますが、サイズを変更する場合にもconstraintで設定できます。
class Book { static belongsTo = [author:Author] static constraints = { description(nullable:true, maxSize:1000) } String title String description }
これだと、
create table book (
〜
description varchar(1000),
〜
こうなります。
mapping
列の型自体を変更する場合にはmappingに設定します。
class Book { static belongsTo = [author:Author] String title String description static mapping = { description type:'text' } }
これだと
create table book ( 〜 description longvarchar not null, 〜 )
こうなります。
また、自動でバージョン管理用の列"version"が追加されますが、自動バージョン管理をやめる場合は、以下のようにmappingに設定します。
class Book { static belongsTo = [author:Author] String title String description static mapping = { version false } }
これで、version列とバージョンの管理はなくなります。
関連
関連について書いたときに、One-to-manyの場合にbelongsToを外すと連鎖削除がされないようなことを書いたのですが、実際のテーブルを見てみました。
class Author { static hasMany = [ books : Book ] String name } class Book { // static belongsTo = [author:Author] String title }
単純に外部キーが設定されないだけではなく、author_bookという連関テーブルが作られるようです。
create table author (id bigint generated by default as identity (start with 1), version bigint not null, name varchar(255) not null, primary key (id)) create table author_book (author_books_id bigint, book_id bigint) create table book (id bigint generated by default as identity (start with 1), version bigint not null, title varchar(255) not null, primary key (id)) alter table author_book add constraint FK2A7A111D3FA913A foreign key (book_id) references book alter table author_book add constraint FK2A7A111DC46A00AF foreign key (author_books_id) references author
以下の様にmany-to-manyの関連を設定すると、
class Author { static hasMany = [ books : Book ] String name } class Book { static belongsTo = Author static hasMany = [authors:Author] String title }
以下の様なDDLになります。
create table author (id bigint generated by default as identity (start with 1), version bigint not null, name varchar(255) not null, primary key (id)) create table author_book (authors_id bigint not null, books_id bigint not null, primary key (books_id, authors_id)) create table book (id bigint generated by default as identity (start with 1), version bigint not null, title varchar(255) not null, primary key (id)) alter table author_book add constraint FK2A7A111DA6B0CB7B foreign key (authors_id) references book alter table author_book add constraint FK2A7A111DED1C647B foreign key (books_id) references author