单表格单元格中的对象

时间:2012-08-26 14:00:11

标签: java sql database postgresql

我上了一堂课:

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

我想把这个类的对象放到数据库表的单个单元格中。有没有办法做到这一点?怎么样?

3 个答案:

答案 0 :(得分:5)

作为使用hstore作为mu is too short解释的替代方法,您有hstore,复合类型,Java序列化byteaxml

我认为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)

或作为单独的SELECT:

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

XML

XML数据类型实现SQL / XML标准。它丰富且便携。 SQL / XML为查询XML值提供xpath支持,您可以在结构化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的函数或运算符,所以它现在对数据库来说非常不透明;你不能写“查找我的json对象,其中'name'键以'a'开头”。期望在9.3中有所改善。

核心Java SDK中不存在JSON支持,但可以从多个库中获得,其中许多库支持通过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.java和PgJDBC 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中将序列化为二进制

可能最粗的选项作为值对数据库完全不透明,但您也可以serialize the value in Java并将其作为bytea存储在数据库中。

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

-

如果你能解释一下你想要实现的目标以及原因,那将是非常有帮助的。

答案 1 :(得分:2)

您可以将对象序列化为字符串,然后存储该字符串。 From Oracle SDN

答案 2 :(得分:2)

由于你正在使用PostgreSQL,你可以使用hstore

  

<强> F.16。 hstore

     

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

您可能需要升级PostgreSQL。

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