for*_*has 6 java persistence jpa bitset
使用JPA,我希望能够将BitSet保存到数据库并将其拉回到程序中.
假设我有:
@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...
}
Run Code Online (Sandbox Code Playgroud)
还应该定义"columnDefinition"吗?我真的不明白它是如何持久的(使用toString()?)而且它是如何从数据库中加载回来的.
你能帮帮我一下吗?
谢谢!
小智 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,JPA 使用 Java 序列化来保留未知Serializable类型的属性(以便您将序列化表示形式存储为byte[])。
通常这不是您想要的,因为可以有更有效的方法来表示您的数据。例如,BitSet可以有效地表示为数字(如果其大小有限),或byte[],或其他东西(不幸的是,BitSet没有提供执行这些转换的方法,因此您需要手动实现它们)。
当您决定在数据库中使用哪种数据表示形式时,您需要告诉 JPA 应用必要的转换。有两种选择:
在 getter 和 setter 中实现转换。例如如下:
@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
}
...
}
Run Code Online (Sandbox Code Playgroud)使用特定于提供者的扩展来隐式执行转换(例如, Hibernate 中的自定义类型)。这种方法允许您在不同的实体中重用类型转换逻辑。