我上了一堂课:
class Person{
String name;
String surname;
String miasto;
}
我想把这个类的对象放到数据库表的单个单元格中。有没有办法做到这一点?怎么样?
答案 0 :(得分:5)
作为使用hstore
作为mu is too short解释的替代方法,您有hstore
,复合类型,Java序列化bytea
和xml
。
xml
data type JSON
数据类型的json
值,9.1-backported version hstore
我认为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数据类型实现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是一种标准格式,被许多语言和应用程序广泛理解。它很容易使用。 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
功能强大,在查询数据时为您提供了许多好的谓词和运算符。但是,格式是非标准的,在应用程序代码中使用起来很麻烦。如果使用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 ;
可能最粗的选项作为值对数据库完全不透明,但您也可以serialize the value in Java并将其作为bytea
存储在数据库中。
每当类更改时,您必须编写自定义反序列化例程来处理仍在数据库中的旧版本的类。没有非java代码可以使用该值,您无法在数据库中查询它。
-
如果你能解释一下你想要实现的目标以及原因,那将是非常有帮助的。
答案 1 :(得分:2)
您可以将对象序列化为字符串,然后存储该字符串。 From Oracle SDN
答案 2 :(得分:2)
由于你正在使用PostgreSQL,你可以使用hstore:
<强> F.16。 hstore 强>
该模块实现了hstore数据类型,用于在单个PostgreSQL值中存储键/值对的集合。这在各种场景中都很有用,例如具有许多很少检查的属性的行或半结构化数据。键和值只是文本字符串。
您可能需要升级PostgreSQL。
但是,对于这样一个简单的模式,三个(或四个)列表,也许是一个外键也可能同样起作用。