简体   繁体   English

将 java BitSet 保存到 DB

[英]Saving java BitSet to DB

Working with JPA, I would like to be able to save a BitSet to the DB and pull it back of course.使用 JPA,我希望能够将 BitSet 保存到 DB 并将其拉回来。

Suppose I have:假设我有:

@Entity
@Table(name = "myTable")
public class MyClass {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Object_Id")
    protected long id;

    @Column(name = "Tags")
    protected BitSet tags;

... getters & setters etc...
}

Should I define a "columnDefinition" as well?我应该定义一个“columnDefinition”吗? I don't really understand how it is persisted (using toString()?) and moreover how does it get loaded back from the DB.我真的不明白它是如何持久化的(使用 toString()?),而且它是如何从数据库加载回来的。

Can you please help me with this one?你能帮我解决这个问题吗?

Thanks!谢谢!

More efficient way (that uses int instead of byte[] ) requires a pretty simple custom class:更有效的方法(使用int而不是byte[] )需要一个非常简单的自定义类:

@Entity
@Access(AccessType.FIELD)
public class SampleEntity {

    @Transient
    private IntBitSet isolationLevel = new IntBitSet(0);

    public static final int USER_BIT = 0;
    public static final int DEVICE_BIT = 1;
    // 2, 3, 4, ...

    public boolean isUserIsolated() {
        return isolationLevel.bitGet(USER_BIT);
    }

    public boolean isDeviceIsolated() {
        return isolationLevel.bitGet(DEVICE_BIT);
    }

    public void setUserIsolated(boolean b) {
        isolationLevel.bitSet(USER_BIT, b);
    }

    public void setDeviceIsolated(boolean b) {
        isolationLevel.bitSet(DEVICE_BIT, b);
    }

    @Access(AccessType.PROPERTY)
    @Column
    public int getIsolationLevel() {
        return isolationLevel.getValue();
    }

    public void setIsolationLevel(int isolationLevel) {
        this.isolationLevel = new IntBitSet(isolationLevel);
    }

    private static class IntBitSet {
        private int value;

        public IntBitSet(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public boolean bitGet(int i) {
            return ((value >> i) & 1) == 1;
        }

        public void bitSet(int i, boolean b) {
            if (b) {
                bitSet(i);
            } else {
                bitUnset(i);
            }
        }
        private void bitSet(int i) {
            value = value | (1 << i);
        }
        private void bitUnset(int i) {
            value = value & ~(1 << i);
        }
    }
}

By default JPA uses Java serialization to persist properties of unknown Serializable types (so that you have a serialized representation stored as a byte[] ).默认情况下,JPA 使用 Java 序列化来持久化未知Serializable类型的属性(以便您将序列化表示存储为byte[] )。

Usually it's not what you want, because there can be more efficient ways to represent your data.通常这不是您想要的,因为可以有更有效的方式来表示您的数据。 For example, BitSet can be efficiently represented as a number (if its size is limited), or byte[] , or something else (unfortunately, BitSet doesn't provide methods to do these conversions, therefore you need to implement them manually).例如, BitSet可以有效地表示为数字(如果其大小有限)或byte[]或其他东西(不幸的是, BitSet不提供进行这些转换的方法,因此您需要手动实现它们)。

When you've decided what kind of data representation you want to have in the database you need to tell JPA to apply the necessary conversion.当您决定要在数据库中使用哪种数据表示时,您需要告诉 JPA 应用必要的转换。 There are two options:有两种选择:

  • Implement conversion in getters and setters.在 getter 和 setter 中实现转换。 For example, as follows:例如,如下:

     @Entity @Table(name = "myTable") @Access(AccessType.FIELD) public class MyClass { ... @Transient // Do not store this field protected BitSet tags; @Access(AccessType.PROPERTY) // Store the property instead @Column(name = "Tags") byte[] getTagsInDbRepresentation() { ... // Do conversion } void setTagsInDbRepresentation(byte[] data) { ... // Do conversion } ... }
  • Use provider-specific extension to perform the conversion implicitly (for example, custom types in Hibernate).使用特定于提供程序的扩展来隐式执行转换(例如,Hibernate 中的自定义类型)。 This approach allows you to reuse your type conversion logic in different entities.这种方法允许您在不同的实体中重用类型转换逻辑。

You can use any of the following conversion in the getter method你可以在getter方法中使用以下任何一种转换

byte[] bytes = bitSet.toByteArray();
long[] longs = bitSet.toLongArray();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM