7

JPA を使用して、BitSet を DB に保存し、もちろん引き戻すことができるようにしたいと考えています。

私が持っているとします:

@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...
}

「columnDefinition」も定義する必要がありますか? それがどのように永続化されるか(toString()を使用して?)、さらにDBからどのようにロードされるかがよくわかりません。

これで私を助けてもらえますか?

ありがとう!

4

3 に答える 3

5

より効率的な方法 (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);
        }
    }
}
于 2014-03-18T11:50:14.550 に答える
3

デフォルトでは、JPAはJavaシリアル化を使用して、不明なSerializableタイプのプロパティを永続化します(したがって、シリアル化された表現がとして保存されますbyte[])。

データをより効率的に表現する方法がある可能性があるため、通常、それはあなたが望むものではありません。たとえばBitSet、数値(サイズが制限されている場合)、またはbyte[]その他(残念ながら、BitSetこれらの変換を行うためのメソッドを提供していないため、手動で実装する必要があります)として効率的に表すことができます。

データベースに含めるデータ表現の種類を決定したら、必要な変換を適用するようにJPAに指示する必要があります。2つのオプションがあります。

  • ゲッターとセッターで変換を実装します。たとえば、次のようになります。

    @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
        }
        ...
    }
    
  • プロバイダー固有の拡張機能を使用して、変換を暗黙的に実行します(たとえば、Hibernateのカスタムタイプ)。このアプローチにより、型変換ロジックをさまざまなエンティティで再利用できます。

于 2012-09-12T14:44:07.633 に答える