0

我有一堂课:

 class Person{ 
   String name; 
   String surname; 
   String miasto; 
 }

我想将此类的对象放入数据库表的单个单元格中。有没有办法做到这一点?如何?

4

3 回答 3

5

作为使用hstoreas mu 的替代方法的解释太简短了,您有hstore、 复合类型、 Java-serializedbyteaxml.

我认为 hstore 可能是一个更好的选择,但这是一个可行的替代方案,并且可以更好地用于某些用途。很难推荐其中一个,因为您没有解释您要做什么以及为什么。

上面列出的每个选项的解释如下。

复合型

复合类型是结构化的和强类型的,易于查询,表达能力强,速度快,并保留了类型系统的全部功能,因此您可以在其中包含各种复杂的值、数组等。但是,从应用程序代码中以文本形式查询和编写它们真的很痛苦,因此您经常会发送额外的查询来使用它们。

甚至不要考虑从 JPA 和其他 ORM(如 Hibernate)中使用它们——你会认为它们的@Embedded类支持复合类型,但你错了。

尝试添加或更改复合类型在使用后确实是一种痛苦的经历。记住这一点。

CREATE TYPE person AS ( name text, surname text, miasto text );

CREATE TABLE some_table (id integer primary key, blah text, this_person person);

INSERT INTO some_table(id,blah,this_person)
VALUES (1,'fred',ROW('a','b','c'));

SELECT (this_person).name FROM some_table;

访问:

regress=# SELECT * FROM some_table ;
 id | blah | this_person 
----+------+-------------
  1 | fred | (a,b,c)
(1 row)

或者,为了避免必须解析复合类型的行语法:

regress=# SELECT t.id, t.blah, (t.this_person).* FROM some_table t;
 id | blah | name | surname | miasto 
----+------+------+---------+--------
  1 | fred | a    | b       | c
(1 row)

或作为单独的选择:

regress=# SELECT (t.this_person).* FROM some_table t;
 name | surname | miasto 
------+---------+--------
 a    | b       | c
(1 row)

XML

XML 数据类型实现 SQL/XML 标准。它丰富且便携。SQL/XML 提供xpath对查询 XML 值的支持,您可以对结构化 XML 数据编写一些相当复杂且功能强大的查询。XML 在大多数应用程序中都易于使用,并且在 Java 中可以使用JAXB和 JAXB 注释从本机 Java 对象轻松编组和解组。

您不需要对 Java 或 Pg 进行任何扩展即可使用 XML。

XML 值是结构化的,但类型不是,它接受任何格式良好的自由格式 XML 文档或片段。添加IS DOCUMENT约束以禁止片段。执行更严格的结构是一种痛苦。AFAIK Pg 目前无法针对 XML DSD 或数据库中的其他模式定义验证 XML,因此执行结构需要混乱且缓慢的xpath约束。

XML 值没有类型,值存储为字符串。

CREATE TABLE some_table (id integer primary key, blah text, this_person xml);

INSERT INTO some_table(id,blah,this_person)
VALUES (1,'fred', '<person><name>a</name><surname>b</surname><miasto>c</miasto></person>');

SELECT (xpath('/person/name/text()', this_person))[1] from some_table ;

JSON

JSON 是一种被许多语言和应用程序广泛理解的标准格式。使用起来相当容易。Pg 中的 JSON 支持非常新,目前还没有任何函数或运算符用于操作和查询 JSON,因此目前对数据库非常不透明;您不能编写诸如“查找'name'键以'a'开头的json对象”之类的查询。预计在 9.3 中会有所改善。

JSON 支持在核心 Java SDK 中不存在,但可从多个库中获得,其中许多库支持通过 JAXB 绑定扩展对 POJO 进行编组/解组。参见,例如 Jackson 的 JAXB 支持。

JSON 类型接受任何格式正确的 JSON 文档。它不提供任何方式来强制执行特定结构。JSON 值是类型化的,但仅接受 JSON 支持的有限类型集,其他所有内容都必须存储为字符串。

-- in Pg 9.2 and above; for 9.1 use the json91 backport
CREATE EXTENSION json;

CREATE TABLE some_table (id integer primary key, blah text, this_person json);

INSERT INTO some_table(id,blah,this_person)
VALUES (1,'fred', '{"name": "a", "surname":"b", "miasto":"c"}');

-- No easy way to subscript out json values in 9.1, but it's very convenient
-- with any app that has json support.

HSTORE

hstore功能强大,并在查询数据时为您提供了许多很好的谓词和运算符。但是,格式是非标准的,并且在应用程序代码中使用起来会很痛苦。如果使用 JDBC,org/postgresql/util/HStoreConverter.javaPgJDBC hstore 支持会有所帮助。

hstore类型接受任何hstore值。结构可以通过CHECK约束来强制执行。hstore值是文本;hstore 中没有数据类型。

-- In Pg 9.1 and above; for older versions hstore is available but is
-- added differently. See the documentation.
CREATE EXTENSION hstore;

CREATE TABLE some_table (id integer primary key, blah text, this_person hstore);

INSERT INTO some_table(id,blah,this_person)
VALUES (1,'fred', hstore(ARRAY['name','surname','miatso'], ARRAY['a','b','c']));

SELECT this_person -> 'name' from some_table ;

在java中序列化为二进制

可能是最简单的选项,因为该值对数据库完全不透明,但您也可以在 Java 中序列化该值并将其存储bytea在数据库中。

每当类更改时,您必须编写自定义反序列化例程来处理仍在数据库中的旧版本的类。没有非 java 代码可以使用该值,并且您不能在数据库中查询它。

--

如果您能解释一下您要通过此实现的目标以及原因,那将非常有帮助。

于 2012-08-27T00:04:03.297 回答
2

您可以将对象序列化为字符串,并将其存储。 来自 Oracle SDN

于 2012-08-26T14:03:02.937 回答
2

由于您使用的是 PostgreSQL,因此您可以使用hstore

F.16。hstore

该模块实现了 hstore 数据类型,用于在单个 PostgreSQL 值中存储键/值对集。这在各种场景中都很有用,例如具有许多很少检查的属性的行或半结构化数据。键和值只是文本字符串。

您可能需要升级 PostgreSQL。

然而,对于这样一个简单的模式,一个三(或四)列的表,也许还有一个外键可能也能起到同样的作用。

于 2012-08-26T20:00:29.687 回答