问题描述
说我有一个字段content
,它是一个json.我想将其存储在数据库中,以便我的域类仅保留1字段. (这更多是大脑的任务;-)
Say I have a field content
that is a json. I would like to store it in database so that my domain class keeps only the 1 field only. (It's more of a brain task ;-)
class MyDomain{
def content
static constraints = {
content nullable: false, blank: false, sqlType: "text" // adapter from JSON to String??
}
def beforeInsert(){
content = content.toString()
}
def beforeUpdate(){
content = content.toString()
}
def afterInsert(){
content = JSON.parse(content) as JSON
}
def afterUpdate(){
content = JSON.parse(content) as JSON
}
def onLoad(){
content = JSON.parse(content) as JSON
}
}
我希望我的域对象仅公开content
,所以我不想使用String contentAsText
之类的其他字段,因为它在外部是可见的.
I want my domain object to expose only content
so I don't want to use another field like String contentAsText
because it would be visible outside.
在整个GORM文档中,我还没有找到如何管理它的方法.我已经尝试过beforeValidate()/beforeInsert()
和onLoad()
方法,但是没有运气...
In the whole GORM documentation I haven't found a thing how to manage it. I've tried beforeValidate()/beforeInsert()
and onLoad()
methods but no luck...
在值保持不变之前,我该如何调整它?
How can I adapt the value before it gets persisted?
推荐答案
您可以为JSONElement
定义自定义的休眠user-type
,如下所述:https://stackoverflow.com/a/28655708/607038
You can define a custom hibernate user-type
for JSONElement
as described here: https://stackoverflow.com/a/28655708/607038
在域类约束中:
static constraints = {
content type: JSONObjectUserType
}
用户类型类别:
import org.grails.web.json.JSONObject
import org.hibernate.HibernateException
import org.hibernate.engine.spi.SessionImplementor
import org.hibernate.type.StandardBasicTypes
import org.hibernate.usertype.EnhancedUserType
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException
import java.sql.Types
class JSONObjectUserType implements EnhancedUserType, Serializable {
private static final int[] SQL_TYPES = [Types.VARCHAR]
@Override
public int[] sqlTypes() {
return SQL_TYPES
}
@Override
public Class returnedClass() {
return JSONObject.class
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true
}
if (x == null || y == null) {
return false
}
JSONObject zx = (JSONObject) x
JSONObject zy = (JSONObject) y
return zx.equals(zy)
}
@Override
public int hashCode(Object object) throws HibernateException {
return object.hashCode()
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
Object jsonObject = StandardBasicTypes.STRING.nullSafeGet(resultSet, names, session, owner)
if (jsonObject == null) {
return null
}
return new JSONObject((String) jsonObject)
}
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
if (value == null) {
StandardBasicTypes.STRING.nullSafeSet(preparedStatement, null, index, session)
} else {
JSONObject jsonObject = (JSONObject) value
StandardBasicTypes.STRING.nullSafeSet(preparedStatement, jsonObject.toString(), index, session)
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value
}
@Override
public boolean isMutable() {
return false
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value
}
@Override
public Object assemble(Serializable cached, Object value) throws HibernateException {
return cached
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original
}
@Override
public String objectToSQLString(Object object) {
throw new UnsupportedOperationException()
}
@Override
public String toXMLString(Object object) {
return object.toString()
}
@Override
public Object fromXMLString(String string) {
return new JSONObject(string)
}
}
这篇关于修改字段以存储到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!