本文介绍了使用uuid作为id并映射到二进制列的grails的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的域对象使用UUID作为id。这个想法是,uuid可以由客户端提供,如果没有,则会生成UUID。我有这样的定义:

I want to use a UUID for the id for my domain objects. The idea is that the uuid could be provided by a client and if not a UUID will be generated. I have the definition as like so : :

class Person {
        static mapping = {
        id generator:'assigned' 
        }

        String id

        def getUUID  ={
            return java.util.UUID.randomUUID().toString();
        }


          transient beforeInsert = {
            if ( id == null || id.equals(""))
                      id = getUUID();
           }
}

现在假设我将包含在java UUID或客户端提供的UUID我希望将其存储在我的MySQL数据库的二进制字段中。检索时也有正确的格式发回。

Now assuming I strip the dashes out that are included in the java UUID or client provided UUID I'd like this to be stored in a binary field in my MySQL database. And also on retrieval have the correct format to send back.

我该如何做到这一点?想一个更好的方法来做到这一点?

How can I accomplish that? Thoughts on a better way to do this?

推荐答案

Grails和hibernate通常以它们的字符串形式处理UUID。使用二进制UUID可能需要多一点工作。声明 id 的类型为 UUID ,并提供一个hibernate用户类型以将其序列化为一个字节数组。您还需要告诉Grails用于UUID的SQL类型。例如:

Grails and hibernate usually handle UUIDs in their string form. Using binary UUIDs is possible with a little more work. Declare id to be of type UUID and provide a hibernate user type to serialize it as an array of bytes. You'll also need to tell grails what SQL type to use for the UUID. For example:

class Person {
    static mapping = {
        id generator:'assigned', type: UUIDUserType, sqlType: 'varbinary(16)'
    }

    UUID id

    def beforeInsert = {
        if (!id) {
            id = UUID.randomUUID()
        }
    }
}



The user type for UUID is:

import java.nio.ByteBuffer
import java.nio.LongBuffer
import java.sql.ResultSet
import java.sql.PreparedStatement
import java.sql.Types
import org.hibernate.usertype.UserType

public class UUIDUserType implements UserType {

    int[] sqlTypes() { [Types.VARBINARY] as int [] }
    Class returnedClass() { UUID }

    Object nullSafeGet(ResultSet resultSet, String[] names, owner) {
        byte[] value = resultSet.getBytes(names[0])
        return value ? bytesToUuid(value) : null
    }

    void nullSafeSet(PreparedStatement statement, value, int index) {
        if (value == null) {
                statement.setNull(index, Types.VARBINARY)
        } else {
                statement.setBytes(index, uuidToBytes(value))
        }
    }

    boolean equals(x, y) { x == y }
    int hashCode(x) { x.hashCode() }
    Object deepCopy(value) { value }
    boolean isMutable() { false }
    Serializable disassemble(value) { value }
    Object assemble(Serializable cached, owner) { cached }
    def replace(original, target, owner) { original }

    static byte[] uuidToBytes(uuid) {
        def bytes = new byte[16];
        ByteBuffer.wrap(bytes).asLongBuffer().with {
            put(0, uuid.mostSignificantBits)
            put(1, uuid.leastSignificantBits)
        }
        bytes
    }

    static UUID bytesToUuid(bytes) {
        ByteBuffer.wrap(bytes).asLongBuffer().with {
            new UUID(get(0), get(1))
        }
    }
}

这篇关于使用uuid作为id并映射到二进制列的grails的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 18:16