Лучше всего это сделать с помощью инструмента миграции, такого как Liquibase, и плагин http://grails.org/plugin/database-migration, вероятно, лучше всего подходит для Grails, поскольку он использует Liquibase и тесно интегрирован с GORM.Но это достаточно легко сделать вручную.
Я бы не стал использовать hasMany
, поскольку вы можете легко управлять всем из класса ProjectMemberships
, поэтому ваши классы Users
и Projects
будут
class Users {
String password
String firstName
String lastName
String emailAddress
String username
Company company
.....
}
и
class Projects {
String projectName
String description
Date dateCreated
Date lastUpdated
}
Я бы пошел с классом ProjectMemberships
, который использует составной ключ, который требует, чтобы он реализовал Serializable
и имел хорошие hashCode
иequals
:
import org.apache.commons.lang.builder.HashCodeBuilder
class ProjectMemberships implements Serializable {
Users u
Projects p
boolean equals(other) {
if (!(other instanceof ProjectMemberships)) {
return false
}
other.u?.id == u?.id && other.p?.id == p?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (u) builder.append(u.id)
if (p) builder.append(p.id)
builder.toHashCode()
}
static ProjectMemberships get(long userId, long projectId) {
find 'from ProjectMemberships where u.id=:userId and p.id=:projectId',
[userId: userId, projectId: projectId]
}
static ProjectMemberships create(Users u, Projects p, boolean flush = false) {
new ProjectMemberships(u: u, p: p).save(flush: flush, insert: true)
}
static boolean remove(Users u, Projects p, boolean flush = false) {
ProjectMemberships instance = ProjectMemberships.findByUsersAndProjects(u, p)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(Users u) {
executeUpdate 'DELETE FROM ProjectMemberships WHERE u=:u', [u: u]
}
static void removeAll(Projects p) {
executeUpdate 'DELETE FROM ProjectMemberships WHERE p=:p', [p: p]
}
static mapping = {
id composite: ['p', 'u']
version false
}
}
Используйте ProjectMemberships.create()
, чтобы добавить отношение между пользователем и проектом, и ProjectMemberships.remove()
, чтобы удалить его.
Запустите grails schema-export
, чтобы увидеть обновленный DDL (он будет в target/ddl.sql
).Запустите оператор create table для таблицы project_memberships
, например,
create table project_memberships (
p_id bigint not null,
u_id bigint not null,
primary key (p_id, u_id)
)
Затем заполните его этим SQL-кодом (в зависимости от вашей базы данных вам может потребоваться немного другой синтаксис):
insert into project_memberships(p_id, u_id) select id, project_lead_id from projects
и, наконец, удалите столбец project_lead_id
из таблицы projects
.
Конечно, сделайте резервную копию базы данных перед внесением каких-либо изменений.
Вы можете получить проекты пользователя с помощью
def projects = ProjectMemberships.findAllByUsers(user)*.p
и аналогичные пользователи проекта с
def users = ProjectMemberships.findAllByProjects(project)*.u