PostgreSQL特点:
1. PostgreSQL 可以在所有主要操作系统中运行;
2. PostgreSQL支持文本、图像、声音和视频;
3. 支持SQL的基本功能,例如: 复杂SQL查询,子选择,外键,触发器,视图,事务,多进程并发控制(MVCC),流式复制(9.0),热备(9.0)
4. 在PostgreSQL中, 表可以设置为从 ‘父’表继承其特征;
5. 可以安装多个扩展以向PostgreSQL添加附加功能;
PostgreSQL常用工具:
1. psql: 命令行工具, 也是管理PostgreSQL的主要工具;
2. pgAdmin 是免费开源图形用户界面管理工具;
3. pgFouine: 日志分析器,可以从PostgreSQL日志文件创建报告。
create index store on store; ×
oracle | postgreSQL | 描述 |
---|---|---|
bitant(a, b) | a & b | 按位与运算 |
nvl(a, 0) | coalesce(a, 0) | 判空 |
to_number(int) | to_number(int, text) 例如: to_number(123, "999999") : text表示精度 | 转成数值类型 |
to_char(int) | to_char(int, text) 例如 to_char(123, "999999") : text表示精度 | 转成字符类型 |
to_date(text) | to_date(text, text) | 格式化日期 |
sysdate | current_date | 当前时间 |
instr('great', 'eat) | positon('eat' IN 'great') | 字符串中包含字符 |
序列名.nextval | nextval(序列名) | 序列的下一个取值 |
insert into monthsettle(no,startdate,finishdate,holder,settler,settletime)
values(200301,to_timestamp('2003.1.1 0:00:01','yyyy.mm.dd hh24:mi:ss'),to_timestamp('2003.1.25 23:59:59','yyyy.mm.dd hh24:mi:ss'),'','',null);
oracle: 左连接 : a.id = b.id(+) ;
右连接 : a.id(+) = b.id
postgreSQL: 左连接:a left join b on a.id = b.id
右连接:a right join b on a.id = b.id
decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
该函数的含义如下:
IF 条件=值1 THEN
RETURN(翻译值1)
ELSIF 条件=值2 THEN
RETURN(翻译值2)
......
ELSIF 条件=值n THEN
RETURN(翻译值n)
ELSE
RETURN(缺省值)
END IF
decode(字段或字段的运算,值1,值2,值3)
这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3
当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多
postgreSQL:
Select CASE
WHEN foo = 'hi' THEN 'there'
WHEN foo = 'good' THEN 'bye'
ELSE 'default'
END
QueryDefinition def = new QueryDefinition();
def.addCondition("storeGid", Integer.valueOf(user.getUuid()));
当storeGid字段数据类类型为integer时, 需要转成对应的数据类型传入,不然会报错(integer == varying)。
NativeBigInQueryExecutor queryExecutor = new NativeBigInQueryExecutor(getEm(), sq, fields);
QueryResult qr = queryExecutor.query(definition.getPage(),
definition.getPageSize(), WholeSaleBck.class);
create or replace view dual as
select NULL::"unknown" where 1=1;
alter table dual owner to postgres;
grant all on table dual to postgres;
grant select on table dual to public;
select count(1) from (select * from store) s;
insert into store (name) values ('');
insert into store (name) values (null);
第一种方式获取的值并不等于null.
create or replace function concat(text, text)
returns text as
$body$select coalesce($1,'') || coalesce($2,'')$body$
language 'sql' volatile;
alter function concat(text, text) owner to postgres;
create table abc (
username varchar(30),
type varchar(30),
id integer
);
select * from abc; select * from ABC; (查询的表都为abc表)
select * from "ABc"; (查询的表为ABc表)
关键字: type,
使用双引号时
INSERT INTO ABC ("TYPE") VALUES ("ab"); ×
INSERT INTO ABC ("type") VALUES ("ab"); √
update fauser o set o.note='xxxx';
提示报错:
ERROR: column "o" of relation "fauser" does not exist
LINE 1: update fauser o set o.note='xxxx'
^
SQL state: 42703
Character: 21
问题背景
分析过程
1. hibernate根据查询的结果集转化成对应实体类时出现的类型错误。
AbstractEntityPersister.hydrate()加载数据结果集:
final ResultSet propertyResultSet = propertyIsDeferred ? sequentialResultSet : rs;
final String[] cols = propertyIsDeferred ? propertyColumnAliases[i] : suffixedPropertyColumns[i];
values[i] = types[i].hydrate( propertyResultSet, cols, session, object );
public class User {
private String username;
private Integer password;
}
User类定义的属性username为String, 对应hibernate在加载该实体为持久化对象时绑定的type就是默认的string, 对应的BasicType是StringType;
2. Hibernate解析type去赋值 (typesi.hydrate( propertyResultSet, cols, session, object )
protected final T nullSafeGet(ResultSet rs, String name, WrapperOptions options) throws SQLException {
return sqlTypeDescriptor.getExtractor( javaTypeDescriptor ).extract( rs, name, options );
}
public AbstractStandardBasicType(SqlTypeDescriptor sqlTypeDescriptor, JavaTypeDescriptor javaTypeDescriptor) {
this.sqlTypeDescriptor = sqlTypeDescriptor;
this.javaTypeDescriptor = javaTypeDescriptor;
}
通过上面源码可以看到: 基本类型AbstractStandardBasicType有两个属性sqlTypeDescriptor 和 javaTypeDescriptor 。 每个继承AbstractStandardBasicType类的子类都会给这两个参数赋予初始值。
3. Hibernate初始化实体类中标注有@Lob类型的字段处理
SimpleValueBinder类中绑定type
else if ( property.isAnnotationPresent( Lob.class ) ) {
if ( mappings.getReflectionManager().equals( returnedClassOrElement, java.sql.Clob.class ) ) {
type = "clob";
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, java.sql.Blob.class ) ) {
type = "blob";
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, String.class ) ) {
type = Hibernate.MATERIALIZED_CLOB.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Character.class ) && isArray ) {
type = Hibernate.WRAPPER_CHARACTERS_CLOB.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, char.class ) && isArray ) {
type = Hibernate.CHARACTERS_CLOB.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Byte.class ) && isArray ) {
type = Hibernate.WRAPPER_MATERIALIZED_BLOB.getName();
}
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, byte.class ) && isArray ) {
type = Hibernate.MATERIALIZED_BLOB.getName();
}
可以看到当实体类的java类型为String时,type = Hibernate.MATERIALIZED_CLOB.getName(), 对应的基本类型是MaterializedClobType。
查看MaterializedClobType源码:
public MaterializedClobType() {
this(
ClobTypeDescriptor.DEFAULT,
new AlternativeLobTypes.ClobTypes( MaterializedClobType.class )
);
}
protected MaterializedClobType(SqlTypeDescriptor sqlTypeDescriptor,
AlternativeLobTypes.ClobTypes clobTypes) {
super( sqlTypeDescriptor, StringTypeDescriptor.INSTANCE, clobTypes );
}
public String getName() {
return "materialized_clob";
}
由上述代码可以看到, MaterializedClobType中默认的sqlTypeDescriptor 是ClobTypeDescriptor.DEFAULT
从而让hibernate以ClobTypeDescriptor类型来处理clob类型的字段。
解决方案
例如:
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor)
{
switch (sqlTypeDescriptor.getSqlType())
{
case Types.CLOB:
return LongVarcharTypeDescriptor.INSTANCE;
case Types.BLOB:
return LongVarbinaryTypeDescriptor.INSTANCE;
}
return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
}
public static final StringClobType INSTANCE = new StringClobType(
LongVarcharTypeDescriptor.INSTANCE, null);
protected StringClobType(SqlTypeDescriptor sqlTypeDescriptor,
AlternativeLobTypes.ClobTypes clobTypes) {
super(sqlTypeDescriptor, clobTypes);
}
@Override
public String getName() {
return "materialized_clob";
}
再重写数据库方言, 注册重写的basicType.
public PostgreSqlDialect() {
super();
addTypeOverride(StringClobType.INSTANCE);
}