앞서 소개한 go-pg를 사용하면 json 데이터와 struct를 쉽게 맵핑할수 있었습니다 반면에 Grom은 직접적으로 맵핑이 불가능 하여 어려움이 있었습니다.
이번 글에서는 Gorm을 사용하여 데이터를 체계적으로 관리하기 위하여 json
데이터를 맵핑 하는 방법에 대하여 기술해 보겠습니다.
type User struct {
gorm.Model
Name string
Todos json.RawMessage `gorm:"type:jsonb;"`
Todo []Todo `gorm:"-"`
}
type Todo struct {
Todo string
Priority int64
}
기본적으로 Gorm에서 Postgres의 Jsonb 타입을 사용하기 위해서는*json.RawMessage
(= postgres.Jsonb
)* 을 사용하여 해당 값이 json
데이터임을 선언해 줍니다.이 후 gorm 태그를 사용하여 해당 컬럼이 jsonb
타입임을 알려줍니다
users
라는 하나의 테이블에서 nested 구조로 todo list를 같이 관리한다고 하였을때, 위에서 선언한 컬럼의 데이터를 모델에 바인딩하여 사용하기 위하여 gorm태그로 무시되는 Todo
배열을 추가해 줍니다.
json
으로 입력받은 json.RawMessage
데이터를 모델에 맵핑하기 위하여 json.Unmarshal
함수를 사용하여 Todos
로 들어온 데이터를 Todo
로 맵핑해줍니다.
func (u *User) UnmarshalTodoData() error {
return json.Unmarshal(u.Todos, &u.Todo)
}
맵핑 이후에는 다음과 같이 Todo
로 접근하여 데이터를 관리할 수 있습니다.
...
user.Todo[0].Todo = "Edited"
user.Todo[0].Priority = 1
...
위의 과정을 진행하고 실제로 데이터베이스에 적용하기 위해서는 다시 json.Marshal
을 사용하여 json.RawMessage
로 변환하는 과정을 거쳐 user.Todos
값을 변경 해주어야 합니다.
func (u *User) MarshalTodoData() error {
var err error
u.Todos, err = json.Marshal(u.Todo)
return err
}
위와 같은 과정을 통하여 json.Todos
에 값을 할당함으로서 gorm의 jsonb
타입의 자료를 구조체에 할당 하여 관리 할 수 있습니다.