本文共 8956 字,大约阅读时间需要 29 分钟。
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 IFdecode(字段或字段的运算,值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); QueryResultqr = 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 existLINE 1: update fauser o set o.note='xxxx' ^SQL state: 42703Character: 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去赋值 (types.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, JavaTypeDescriptorjavaTypeDescriptor) { this.sqlTypeDescriptor = sqlTypeDescriptor; this.javaTypeDescriptor = javaTypeDescriptor;}
通过上面源码可以看到: 基本类型AbstractStandardBasicType有两个属性sqlTypeDescriptor 和 javaTypeDescriptor 。 每个继承AbstractStandardBasicType类的子类都会给这两个参数赋予初始值。
3. Hibernate初始化实体类中标注有@Lob类型的字段处理
SimpleValueBinder类中绑定typeelse 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类型的字段。解决方案
例如:
@Overridepublic 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.ClobTypesclobTypes) { super(sqlTypeDescriptor, clobTypes); } @Override public String getName() { return "materialized_clob"; }
再重写数据库方言, 注册重写的basicType.
public PostgreSqlDialect() { super(); addTypeOverride(StringClobType.INSTANCE); }
转载地址:http://hqani.baihongyu.com/