您好我有两个域类如下
class Users {
String password
String firstName
String lastName
String emailAddress
String username
Company company
.....
static hasMany = [projects:Projects];
}
另一个班级
class Projects {
String projectName
String description
Users projectLead
Date dateCreated
Date lastUpdated
static belongsTo = Users
}
这些类显然有一对多关系,但现在我想通过添加“ProjectMembership”类将其更改为多对多关系,但我遇到的问题是我的应用程序已经投入生产并且已经有人已经使用该应用程序。在这种情况下,他们已经在db中有一个用户 - >多个项目。在这种情况下,我如何迁移现有数据并将我的prod应用程序更改为m2m关系,如下所示。
class Users {
String password
String firstName
String lastName
String emailAddress
String username
Company company
.....
static hasMany = [projectMemberships:ProjectMemberships];
}
另一个班级
class Projects {
String projectName
String description
Users projectLead
Date dateCreated
Date lastUpdated
static hasMany = [projectMemberships:ProjectMemberships];
}
和
class ProjectMemberships{
Users u
Projects p
}
答案 0 :(得分:2)
最好使用像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
中)。运行project_memberships
表的create table语句,例如
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