使用PostgreSQL
分享人:杨景
分享人:杨景
名字 | 存储尺寸 | 描述 | 范围 |
---|---|---|---|
smallint | 2字节 | 小范围整数 | -32768 to +32767 |
integer | 4字节 | 整数的典型选择 | -2147483648 to +2147483647 |
bigint | 8字节 | 大范围整数 | -9223372036854775808 to +9223372036854775807 |
numeric | 可变 | 用户指定精度,精确 | 最高小数点前131072位,以及小数点后16383位 |
real, float4 | 4字节 | 可变精度,不精确 | 6位十进制精度 |
double precision, float8 | 8字节 | 可变精度,不精确 | 15位十进制精度 |
serial | 4字节 | 自动增加的整数 | 1到2147483647 |
bigserial | 8字节 | 自动增长的大整数 | 1到9223372036854775807 |
名字 | 存储尺寸 | 描述 |
---|---|---|
varchar(n) | 有限制的变长 | |
char(n) | 定长 | |
text | 无限变长 | |
bytea | 1或4字节外加真正的二进制串 | 变长二进制串 |
名字 | 存储尺寸 | 描述 | 最小值 | 最大值 | 解析度 |
---|---|---|---|---|---|
timestamp [(p)] [without time zone] | 8字节 | 包括日期和时间(无时区) | 4713 BC | 294276 AD | 1微秒/14位 |
timestamp [(p)] with time zone | 8字节 | 包括日期和时间,有时区 | 4713 BC | 294276 AD | 1微秒/14位 |
date | 4字节 | 日期(没有一天中的时间) | 4713 BC | 5874897 AD | 1日 |
time [(p)] [without time zone ] | 8字节 | 一天中的时间(无日期) | 00:00:00 | 24:00:00 | 1微秒/14位 |
time [(p)] with time zone | 12字节 | 一天中的时间(不带日期),带有时区 | 00:00:00+1459 | 24:00:00-1459 | 1微秒/14位 |
interval [fields] [(p)] | 16字节 | 时间间隔 | -178000000年 | 178000000年 | 1微秒/14位 |
JSON | 基本类型 | PostgreSQL类型 注释 |
---|---|---|
string | text | 不允许\u0000,如果数据库编码不是 UTF8,非 ASCII Unicode 转义也是这样 |
number | numeric | 不允许NaN 和 infinity值 |
boolean | boolean | 只接受小写true和false拼写 |
null | (无) | SQL NULL是一个不同的概念 |
select '[1, 2, "foo", null]'::jsonb;
select '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::jsonb;
SELECT '{"bar": " baz", "balance": 7.77, "active":false}'::json;
-------------------------------------------------
{"bar": " baz", "balance": 7.77, "active":false}
(1 row)
SELECT '{"bar": " baz", "balance": 7.77, "active":false}'::jsonb;
--------------------------------------------------
{"bar": " baz", "active": false, "balance": 7.77}
(1 row)
SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
json | jsonb
-----------------------+-------------------------
{"reading": 1.230e-5} | {"reading": 0.00001230}
(1 row)
select XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>');
select XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>');
select '<foo>bar</foo>'::xml;
名字 | 存储尺寸 | 描述 | 范围 |
---|---|---|---|
money | 8字节 | 货币额 | -92233720368547758.08到+92233720368547758.07 |
bool | 1字节 | 状态为真或假 | |
enum | 通过 create type mood as enum('sad', 'ok', 'happy'); 创建枚举类型 | ||
cidr | 7或19字节 | IPv4和IPv6网络 | |
inet | 7或19字节 | IPv4和IPv6主机以及网络 | |
macaddr | 6字节 | MAC地址 | |
macaddr8 | 8字节 | MAC 地址 (EUI-64 格式) |
zh_CN.UTF-8
FROM postgres:10.5
RUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8
ENV LANG zh_CN.utf8
ENV TZ Asia/Shanghai
COPY init.sql /docker-entrypoint-initdb.d/
docker run
时执行些数据库初始化工作。create user massdata with nosuperuser replication encrypted password 'Massdata.2018';
create database massdata owner = massdata template = template0 encoding = 'UTF-8'
lc_ctype = 'zh_CN.UTF-8' lc_collate = 'zh_CN.UTF-8';
\c massdata;
create extension adminpack;
create extension hstore;
$ docker build -t postgres-10-dev .
$ docker run -h postgres-10-dev -p 5432:5432 --name=postgres-10-dev -d postgres-10-dev
$ docker run -it --rm --link=postgres-10-dev postgres-10-dev \
psql -h postgres-10-dev -d massdata -U massdata
psql (10.4 (Debian 10.4-2.pgdg90+1))
Type "help" for help.
massdata=>
create table t_book(
id serial primary key,
isbn varchar(64) not null,
title varchar(255) not null,
authors text[] not null,
created_at timestamptz
);
create unique index t_book_isbn_idx on t_book(title);
alter table t_book add column description text null;
\d t_book;
massdata=> \d t_book;
Table "public.t_book"
Column | Type | Collation | Nullable | Default
-------------+--------------------------+-----------+----------+------------------------------------
id | integer | | not null | nextval('t_book_id_seq'::regclass)
isbn | character varying(64) | | not null |
title | character varying(255) | | not null |
authors | text[] | | not null |
created_at | timestamp with time zone | | |
description | text | | |
Indexes:
"t_book_pkey" PRIMARY KEY, btree (id)
"t_book_isbn_idx" UNIQUE, btree (title)
massdata=> select id, isbn, title, authors from t_book;
id | isbn | title | authors
----+-------------------+--------------------------------+-----------------------------------------------
1 | 978-7-115-48356-0 | Scala实用指南 | {文卡特·苏帕拉马尼亚姆}
2 | 9787111370048 | Java并发编程 | {"Brian Goetz","Time Peierls","Joshua Bloch"}
3 | 9787111255833 | Effective Java中文版(第二版) | {"joshua Bloch"}
(3 rows)
massdata=> select id, isbn, title, authors from t_book
massdata-> where 'Joshua Bloch' like any(authors);
id | isbn | title | authors
----+---------------+--------------------------------+------------------
3 | 9787111255833 | Effective Java中文版(第二版) | {"joshua Bloch"}
(1 row)
any
函数来匹配数组内的任一个元素。unnest
函数将数组字段值转换成表数据记录massdata=> select p.id, p.isbn, p.title, p.authors from
massdata-> (select *, unnest(authors) as author from t_book) p
massdata-> where p.author like '%Bloch';
id | isbn | title | authors
----+---------------+--------------------------------+-----------------------------------------------
2 | 9787111370048 | Java并发编程 | {"Brian Goetz","Time Peierls","Joshua Bloch"}
3 | 9787111255833 | Effective Java中文版(第二版) | {"joshua Bloch"}
(2 rows)
ilike
操作符来进行忽略大小写的字符比较massdata=> select id, isbn, title, authors from t_book
massdata-> where 'joshua Bloch' ilike any(authors);
id | isbn | title | authors
----+---------------+--------------------------------+-----------------------------------------------
2 | 9787111370048 | Java并发编程 | {"Brian Goetz","Time Peierls","Joshua Bloch"}
3 | 9787111255833 | Effective Java中文版(第二版) | {"joshua Bloch"}
(2 rows)
t_user
用户表create table t_user(
id bigserial primary key,
username varchar(255) not null,
attrs jsonb not null default '{}',
created_at timestamptz not null default now()
);
create unique index t_user_username_uidx on t_user(username);
insert into t_user(username, attrs) values
('yangbajing', '{"nickname":"羊八井","age":32,"email":"yangbajing@gmail.com", "contacts":[{"city":"重庆","address":"渝北区金开大道西段106号10栋移动新媒体产业大厦11楼"}]}'),
('yangjing', '{"nickname":"杨景","age":32}'),
('yangjiajiang', '{"nickname":"杨家将","age":32, "contacts":[{"city":"江津","address":"重庆市江津区南门路"}]}');
massdata=> select * from t_user;
id | username | attrs | created_at
----+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------
-------
2 | yangjing | {"age": 32, "nickname": "杨景"} | 2018-09-03 12:00:42.274
754+00
1 | yangbajing | {"age": 33, "email": "yangbajing@gmail.com", "contacts": [{"city": "重庆", "address": "渝北区金开大道西段106号10栋移动新媒体产业大厦11楼"}], "nickname": "羊八井"} | 2018-09-03 12:00:42.274
754+00
3 | yangjiajiang | {"age": 32, "contacts": [{"city": "江津", "address": "重庆市江津区南门路"}], "nickname": "杨家将"} | 2018-09-04 08:53:35.6
29468+00
(2 rows)
col1
,col2
,col3
这样无意义的字段->>
操作符根据 username 查询massdata=> select id, username, attrs from t_user where attrs->>'nickname' = '杨景';
id | username | attrs
----+----------+---------------------------------
2 | yangjing | {"age": 32, "nickname": "杨景"}
(1 row)
massdata=> select id, username, attrs from t_user where attrs @> '{"contacts":[{"city":"重庆"}]}'::jsonb;
id | username | attrs
1 | yangbajing | {"age": 32, "email": "yangbajing@gmail.com", "contacts": [{"city": "重庆", "address": "渝北区金开大道西段106号10栋移动新媒体产业大厦11楼"}], "nickname": "羊八井"}
(1 row)
massdata=> select id, username, attrs from t_user where attrs @> '{"contacts":[{"city":"江津"}]}'::jsonb;
id | username | attrs
3 | yangjiajiang | {"age": 32, "contacts": [{"city": "江津", "address": "重庆市江津区南门路"}], "nickname": "杨家将"}
(1 row)
massdata=> select id, username, attrs from t_user where attrs->'age' = '32'::jsonb;
id | username | attrs
2 | yangjing | {"age": 32, "nickname": "杨景"}
3 | yangjiajiang | {"age": 32, "contacts": [{"city": "江津", "address": "重庆市江津区南门路"}], "nickname": "杨家将"}
create index t_user_attrs_idx ON t_user using gin(attrs);
操作符 | 右操作数类型 | 描述 | 例子 | 例子结果 |
---|---|---|---|---|
-> | int | 获得JSON 数组元素(索引从 0 开始,负整数结束) | '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2 | {"c":"baz"} |
-> | text | 通过键获得JSON 对象域 | '{"a": {"b":"foo"}}'::json->'a' | {"b":"foo"} |
->> | int | 以文本形式获得JSON 数组元素 | '[1,2,3]'::json->>2 | 3 |
->> | text | 以文本形式获得JSON 对象域 | '{"a":1,"b":2}'::json->>'b' | 2 |
#> | text[] | 获取在指定路径的JSON 对象 | '{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}' | {"c": "foo"} |
#>> | text[] | 以文本形式获取在指定路径的JSON 对象 | '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}' | 3 |
操作符 | 右操作数类型 | 描述 | 例子 |
---|---|---|---|
@> |
jsonb |
左边的 JSON 值是否包含顶层右边JSON路径/值项? | '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb |
<@ |
jsonb |
左边的JSON路径/值是否包含在顶层右边JSON值中? | '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb |
? |
text |
字符串是否作为顶层键值存在于JSON值中? | '{"a":1, "b":2}'::jsonb ? 'b' |
?| |
text[] |
这些数组字符串中的任何一个是否作为顶层键值存在? | '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c'] |
?& |
text[] |
这些数组字符串是否作为顶层键值存在? | '["a", "b"]'::jsonb ?& array['a', 'b'] |
|| |
jsonb |
连接两个jsonb 值到新的jsonb 值 |
'["a", "b"]'::jsonb || '["c", "d"]'::jsonb |
- |
text |
从左操作数中删除键/值对或字符串元素。基于键值匹配键/值对。 | '{"a": "b"}'::jsonb - 'a' |
- |
text[] |
从左操作数中删除多个键/值对或string元素。 键/值对基于其键值进行匹配。 | '{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[] |
- |
integer |
删除指定索引的数组元素(负整数结尾)。如果顶层容器不是一个数组,那么抛出错误。 | '["a", "b"]'::jsonb - 1 |
#- |
text[] |
删除指定路径的域或元素(JSON数组,负整数结尾) | '["a", {"b":1}]'::jsonb #- '{1,b}' |
key=>value
对:massdata=> select 'a=>1,a=>2,b=>null'::hstore;
hstore
---------------------
"a"=>"1", "b"=>NULL
(1 row)
=>
号周围的空白将被忽略。一个值可以是SQL NULL
(不区分大小写)。WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
massdata=> WITH RECURSIVE t(n) AS (
VALUES (1)
UNION ALL
SELECT n+1 FROM t WHERE n < 100
)
massdata-> SELECT sum(n) FROM t;
sum
------
5050
(1 row)
massdata=> select * from t_org;
id | name | parent
----+----------------+--------
1 | 机级组织 |
2 | 市工商 | 1
3 | 市公安 | 1
4 | 市工商小微企部 | 2
(4 rows)
massdata=> with recursive tree as (
select id, name, parent from t_org where id = 4
union all
select t_org.id, t_org.name, t_org.parent from t_org, tree where t_org.id = tree.parent
) select id, name from tree offset 1;
id | name
----+----------
2 | 市工商
1 | 机级组织
(2 rows)
create or replace function array_reverse(anyarray) returns anyarray as $$
select array(select $1 [ i ] from generate_subscripts($1, 1) as s(i) order by i desc);
$$ language 'sql' strict immutable;
massdata=> select array_reverse(array(with recursive tree as (
select id, name, parent from t_org where id = 4
union all
select t_org.id, t_org.name, t_org.parent from t_org, tree where t_org.id = tree.parent
) select id from tree offset 1)) as parents;
parents
---------
{1,2}
(1 row)
INSERT
、UPDATE
和DELETE
命令都有支持可选的RETURNING
子句,使用RETURNING
可以避免执行额外的数据查询来收集数据。RETURNING
子句的内容与SELECT
命令的输出列表相同。它可以包含命令的目标表的列名,或者包含使用这些列的值表达式。一个常见的简写是RETURNING *
,它按顺序选择目标表的所有列。insert into t_org (name, parent) values ('市公安', 1) returning id;
update t_org set name = '市公安局' where id = 3 returing *;
delete from t_org where id = 3 returing *;
on conflict
可以在发生主键冲突时控制接下来的动作。我们可以选择更新已有数据,或者忽略本次操作。massdata=> insert into t_org (id, name, parent) values (3, '市公安局', 1);
ERROR: duplicate key value violates unique constraint "t_org_pkey"
DETAIL: Key (id)=(3) already exists.
massdata=> insert into t_org (id, name, parent)
values (3, '市公安局', 1)
on conflict (id) do update set name = EXCLUDED.name, parent = EXCLUDED.parent;
INSERT 0 1
on conflict(xxx) do
特性,必需指定(复合)主键。on conflict(xxx) do nothing
在主键冲突时进行忽略(不返回错误也不更新数据)。on conflict(xxx) do
特性。insert into t_org (id, name, parent)
values (3, '市公安局', 1), (4, '市工商局小微企部', 2), (5, '市体育局', 1)
on conflict (id) do update set name = EXCLUDED.name, parent = EXCLUDED.parent;
CREATE EXTENSION
来安装postgres_fdw扩展。CREATE SERVER
创建一个外部服务器对象,它用来表示你想连接的每一个远程数据库。指定除了user
和password
之外的连接信息作为该服务器对象的选项。CREATE USER MAPPING
创建一个用户映射,每一个用户映射都代表你想允许一个数据库用户访问一个外部服务器。指定远程用户名和口令作为用户映射的user
和password
选项。CREATE FOREIGN TABLE
或者IMPORT FOREIGN SCHEMA
创建一个外部表。外部表的列必须匹配被引用的远程表。但是,如果你在外部表对象的选项中指定了正确的远程名称,你可以使用不同于远程表的表名和/或列名。$ docker run -h postgres-10-dev2 --link=postgres-10-dev --name=postgres-10-dev2 -d postgres-10-dev
$ docker run -it --rm --link=postgres-10-dev2 postgres-10-dev psql -h postgres-10-dev2 -U postgres -d massdata
massdata=# create extension postgres_fdw ;
CREATE EXTENSION
massdata=# create server foreign_server foreign data wrapper postgres_fdw options (host 'postgres-10-dev', port '5432', dbname 'massdata');
CREATE SERVER
massdata=# create user MAPPING FOR postgres server foreign_server options (user 'postgres', password 'postgres');
CREATE USER MAPPING
massdata=# create foreign table ft_org(
id int not null,
name varchar(128) not null,
parent int null
) server foreign_server options(schema_name 'public', table_name 't_org');
CREATE FOREIGN TABLE
massdata=# select * from ft_org ;
id | name | parent
----+----------------+--------
1 | 市级组织 |
2 | 市工商 | 1
3 | 市公安 | 1
4 | 市工商小微企部 | 2
(4 rows)
massdata=# \d ft_org
Foreign table "public.ft_org"
Column | Type | Collation | Nullable | Default | FDW options
--------+------------------------+-----------+----------+---------+-------------
id | integer | | not null | |
name | character varying(128) | | not null | |
parent | integer | | | |
Server: foreign_server
FDW options: (schema_name 'public', table_name 't_org')
select
、insert
、update
和delete
操作远程表。insert
语句支持on conflict do nothing
,但不支持on conflict do update
。FROM mysql:5.7
ENV LANG zh_CN.utf8
ENV TZ Asia/Shanghai
COPY init.sql /docker-entrypoint-initdb.d/
$ docker build -t mysql-5.7-dev .
$ docker run -p 3306:3306 --name=mysql-5.7-dev -h mysql-5.7-dev -e MYSQL_ROOT_PASSWORD=Mysql.2018 -d mysql-5.7-dev
$ docker run --rm -it --link=mysql-5.7-dev mysql-5.7-dev mysql -h mysql-5.7-dev -D massdata -u massdata -pMassdata.2018
mysql> insert into test(name, created_at) values ('MySQL', now()), ('PostgreSQL', now());
Query OK, 2 rows affected (0.06 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql_fdw
扩展的PostgreSQL数据库$ docker run --name=pgsql-fdq-mysql -h pgsql-fdq-mysql --link=mysql-5.7-dev -d geographica/postgis-fdw-mysql
$ docker run -it --rm --link=pgsql-fdq-mysql geographica/postgis-fdw-mysql psql -h pgsql-fdq-mysql -U postgres # 密码:postgres
postgres@pgsql-fdq-mysql ~> create extension mysql_fdw;
postgres@pgsql-fdq-mysql ~> create server mysql_server foreign data wrapper mysql_fdw options(host 'mysql-5.7-dev', port '3306');
postgres@pgsql-fdq-mysql ~> create user mapping for postgres server mysql_server options(username 'massdata', password 'Massdata.2018');
postgres@pgsql-fdq-mysql ~> create foreign table ft_test(
id bigint not null,
name varchar(255),
created_at timestamp
) server mysql_server options(dbname 'massdata', table_name 'test');
postgres@pgsql-fdq-mysql ~> select * from ft_test;
id | name | created_at
----+------------+---------------------
1 | MySQL | 2018-09-05 02:07:17
2 | PostgreSQL | 2018-09-05 02:07:17
(2 rows)
mysql_fdw
支持PostgreSQL 9.3, 9.4, 9.5, 9.6, 10。ALTER TABLE DETACH PARTITION
或者使用DROP TABLE
删除一个单独的分区都远快于一个批量操作。这些命令也完全避免了由批量DELETE
造成的VACUUM负载。创建分区表和子表:
create table t_log(
id uuid not null,
content text not null,
created_at timestamp not null
) partition by range(created_at);
create table t_log_his partition of t_log for values from ('1970-01-01') to ('2018-01-01');
create table t_log_201801 partition of t_log for values from ('2018-01-01') to ('2018-02-01');
create table t_log_201802 partition of t_log for values from ('2018-02-01') to ('2018-03-01');
create table t_log_201803 partition of t_log for values from ('2018-03-01') to ('2018-04-01');
插入数据:
insert into t_log(id, content, created_at) values
(uuid_generate_v4(), 'TRACE', '2017-12-11'),
(uuid_generate_v4(), 'DEBUG', '2018-01-11'),
(uuid_generate_v4(), 'INFO', '2018-02-11'),
(uuid_generate_v4(), 'WARN', '2018-03-11');
插入分区范围之外的数据会报错:
massdata=> insert into t_log(id, content, created_at) values (uuid_generate_v4(), 'ERROR', '2018-04-11');
ERROR: no partition of relation "t_log" found for row
DETAIL: Partition key of the failing row contains (created_at) = (2018-04-11 00:00:00).
通过explain
显示执行计划,可以看到分别从4张子表内获取的数据:
massdata=> explain select * from t_log;
QUERY PLAN
----------------------------------------------------------------------
Append (cost=0.00..78.80 rows=3880 width=56)
-> Seq Scan on t_log_201801 (cost=0.00..19.70 rows=970 width=56)
-> Seq Scan on t_log_201802 (cost=0.00..19.70 rows=970 width=56)
-> Seq Scan on t_log_201803 (cost=0.00..19.70 rows=970 width=56)
-> Seq Scan on t_log_his (cost=0.00..19.70 rows=970 width=56)
(5 rows)
create table t_log_201804 partition of t_log for values from ('2018-04-01') to ('2018-05-01');
alter table t_log attach partition t_log_201804 for values from ('2018-04-01') to ('2018-05-01');
drop table t_log_201804;
alter table t_log detach partition t_log_201804;
massdata=> \d+ t_log;
Table "public.t_log"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
------------+--------------------------+-----------+----------+---------+----------+--------------+-------------
id | uuid | | not null | | plain | |
content | text | | not null | | extended | |
created_at | timestamp with time zone | | not null | | plain | |
Partition key: RANGE (created_at)
Partitions: t_log_201801 FOR VALUES FROM ('2018-01-01 00:00:00+00') TO ('2018-02-01 00:00:00+00'),
t_log_201802 FOR VALUES FROM ('2018-02-01 00:00:00+00') TO ('2018-03-01 00:00:00+00'),
t_log_201803 FOR VALUES FROM ('2018-03-01 00:00:00+00') TO ('2018-04-01 00:00:00+00'),
t_log_his FOR VALUES FROM ('1970-01-01 00:00:00+00') TO ('2018-01-01 00:00:00+00')
虽然在PG里存储日志不是一个好的设计,但使用分区表来进行日志存储也不失为一个可行的方案。
任务系统都有崩溃的可能,数据库备份工作的重要性毋庸置疑。
pg_dump
、pg_dumpall
。pg_dump
pg_dump -Fp -c --insert --column-inserts massdata > massdata.sql
当使用文本格式并导出为insert插入语句时,应同时指定--column-inserts
参数来明确指定列的名称,不然当字段顺序变化或有新的列时可能不能正确恢复数据
pg_dump -Fc -c massdata > massdata.dat
psql -h localhost -U massdata -d massdata < massdata.sql
pg_restore -h localhost -U massdata -d massdata massdata.dat
PostgreSQL支持JDBC 4协议,JDBC URL连接示例如下:
jdbc:postgresql://host:port/database
String url = "jdbc:postgresql://localhost/massdata";
Properties props = new Properties();
props.setProperty("user","massdata");
props.setProperty("password","Massdata.2018");
props.setProperty("ssl","true");
Connection conn = DriverManager.getConnection(url, props);
String url = "jdbc:postgresql://localhost/massdata?user=massdata&password=Massdata.2018&ssl=true";
Connection conn = DriverManager.getConnection(url);
spring.datasource.name=main
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.jdbc-url=jdbc:postgresql://localhost:5432/massdata
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=massdata
spring.datasource.password=Massdata.2018
Java Type | Default PostgreSQL™ Type |
---|---|
short | int2 |
int | int4 |
long | int8 |
float | float4 |
double | float8 |
boolean | bool |
String | varchar, text |
java.sql.Time | time [ without time zone ] |
java.sql.Date | date |
java.sql.timestamp | timestamp [ without time zone ] |
byte[] | bytea |
需要使用JDBC 4.2才支持
PostgreSQL™ | Java SE 8 |
---|---|
DATE | LocalDate |
TIME [ WITHOUT TIME ZONE ] | LocalTime |
TIMESTAMP [ WITHOUT TIME ZONE ] | LocalDateTime |
TIMESTAMP WITH TIME ZONE | OffsetDateTime |
读
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500");
while (rs.next())
{
System.out.print("Column 1 returned ");
LocalDate localDate = rs.getObject(1, LocalDate.class));
System.out.println(localDate);
}
rs.close();
st.close();
写
LocalDate localDate = LocalDate.now();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, localDate);
st.executeUpdate();
st.close();
PostgresQL提供了两种使用数组类型的方式。
java.sql.Connection.createArrayOf(String, Object[])
创建对象数组,使用PreparedStatement.setArray(int, Array)
设置值。PreparedStatement.setObject
方法直接设置数组,支持以下Java数组的自动映射:Java Type | Default PostgreSQL™ Type |
---|---|
short[] | int2[] |
int[] | int4[] |
long[] | int8[] |
float[] | float4[] |
double[] | float8[] |
boolean[] | bool[] |
String[] | varchar[] |
羊八井
www.yangbajing.me
weibo.com/yangbajing
yangbajing at gmail com