使用JPA/Hibernate将BigDecimal[][]持久化到MySQL数据库



我需要使用Hibernate将BigDecimal[][]类型持久化到MySQL数据库。我不知道怎么做。我试过这个:

@Getter
@Setter
@ToString
@RequiredArgsConstructor
@Embeddable
@TypeDef(name = "coordinates_array",
typeClass = BigDecimalArrayType.class)
public class Geometry {
private String type;
@Type(
type = "coordinates_array",
parameters = @org.hibernate.annotations.Parameter(
name = "sql_array_type",
value = "BigDecimal"
)
)
@Column(
name = "coordinates",
columnDefinition = "BigDecimal[][]"
)
BigDecimal[][] coordinates;}

没有BigDecimalArrayType类。如何定义BigDecimalArrayType?或者我们还有什么可以替代的吗?

正如我的评论中所提到的,由于您不想将数组保存在"纯文本";你可以按照这个方法走。

使用两个字段,一个是持久字段(DB的一部分(,另一个是瞬态字段(仅应用程序逻辑的一部分。持久性将是您的CoordinateHolderbyte[],而瞬态将是BigDecimal[][]

这是CoordinateHolder的类。正如您所看到的,我正在使用@Transient来禁止持久化字段。

@Embeddable
public class CoordinateHolder implements Serializable
{
@Transient
private BigDecimal[][] transientCoordinates; // Will not be saved in the DB, is part only of the business logic.
public BigDecimal[][] getTransientCoordinates()
{
return transientCoordinates;
}
public void setTransientCoordinates(BigDecimal[][] transientCoordinates)
{
this.transientCoordinates = transientCoordinates;
}
}

在这之后,让我们来看看实体类:

@Entity(name = "test_name")
public class TestEntity
{
// Your id...
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Embedded
private CoordinateHolder coordinateHolder;
@Lob
@Column(name = "coordinates", columnDefinition = "BLOB")
private byte[] blobCoordinates;
public void setCoordinates(BigDecimal[][] arr)
{
if (coordinateHolder == null)
{
coordinateHolder = new CoordinateHolder();
}
coordinateHolder.setTransientCoordinates(arr);
}
public BigDecimal[][] getCoordinates()
{
if (coordinateHolder == null)
{
return null;
}
return coordinateHolder.getTransientCoordinates();
}

// This can also be done through Entity listeners which actually do the same thing
// Pre persist is always performed before persisting this entity
@PrePersist
public void prePersisting()
{
System.out.println("Hey I am being persisted. And now I am turning my transient coordinates into BLOB for the db");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out;
try
{
out = new ObjectOutputStream(bos);
out.writeObject(coordinateHolder);
out.flush();
blobCoordinates = bos.toByteArray();
} catch (Exception e)
{
// Do smth with your exception...
e.printStackTrace();
} finally
{
try
{
bos.close();
} catch (IOException ignored)
{
// ignore close exception
}
}
}
// Perform after loading...
@PostLoad
public void postLoading()
{
System.out.println("Hey I am being fetched, I am turning my BLOB into the array holder so that you can use it in your app");
ByteArrayInputStream bis = new ByteArrayInputStream(this.getBlobCoordinates());
ObjectInput in = null;
try
{
in = new ObjectInputStream(bis);
CoordinateHolder o = (CoordinateHolder) in.readObject();
this.setCoordinateHolder(o);
}
catch (Exception e)
{
// Do smth with your exception...
e.printStackTrace();
}
finally
{
try
{
if (in != null)
{
in.close();
}
} catch (IOException ex)
{
// ignore close exception
}
}
}
... Further getters and setters...
}

代码是用注释描述的,应该是可以理解的。这使你有可能坚持你需要的东西。

如果您想保持原样,而不是将行/列分解到适当的表中,也许您可以将BigDecimal[][]转换为blob。

最新更新