Hibernate查询oracle数据库char类型字段,获取不到结果的问题

问题分析:

1)去掉按月份搜索的条件是可以的查询到数据。

2)拼接sql的形式是可以查询到信息的数据。

3)用其他Varchar2类型的字段动态绑定参数查询是可以的。

/**
* YM 在数据库为char类型,字符长度为8,而字段为年月 例如:202101,而要和数据库中char类型的长度一致,长度不够的,用空格补齐。
*/
if (StringUtils.isNotEmpty(ym)) {
    sql += " and mapp.YM=:YM";
    params.put("YM", ym);
}

结论:该问题可能和字段类型和hibernate的动态绑定有关系。

查询材料解释:

https://community.oracle.com/tech/developers/discussion/comment/506702#Comment_506702

Select * From table Where column = ?
setObject(1, "compValue")

will never return anything if the type of column would be e.g. CHAR(20)

This behaviour is inconsistent to executing the same select as statement in the following form

Statement.executeQuery(Select * From table Where column = "compValue")

which will return all rows, where the value matches.

The difference in the behaviour lies in the fact, that for a PreparedStatment the number of characters must match.


==================================================================================


use setFixedCHAR(....).,
 
quote from Oracle9i JDBC API Docs
 
 
public void setFixedCHAR(int paramIndex,
java.lang.String x)
throws java.sql.SQLException
 
Sets the disignated parameter to a String and executes a non-padded comparison with a SQL CHAR.
 
CHAR data in the database is padded to the column width. This leads to a limitation in using the setCHAR() method to bind character data into the WHERE clause of a SELECT statement--the character data in the WHERE clause must also be padded to the column width to produce a match in the SELECT statement. This is especially troublesome if you do not know the column width.
 
setFixedCHAR() remedies this. This method executes a non-padded comparison.
 

大体意思就是说采用CHAR类型,是固定类型,如果长度不够会用空格补齐,因此采用PreparedStatement动态参数绑定查询时,要采用 OraclePreparedStatement 的setFixedCHAR() 设置char类型的字段。

解决办法:

Hibernate底层是基于PrepardStatement的,但是设置参数是没办法指定setFixedCHAR(),常用的时采用如下方式 query.setParameter(key, map.get(key)); 因此使用setFixedCHAR()的方式行不太通。

1)将字段trim化,去除空格(不推荐,如果在该字段上有索引的化,索引会不起作用)。

 if (StringUtils.isNotEmpty(ym)) {
            sql += " and trim(mapp.YM)=:YM";
            params.put("YM", ym);
        }

2)将字段类型改为varchar2类型 (项目中使用,推荐使用)。

上一篇:【USACO19Jan-S】山景Mountain View


下一篇:【Luogu P3124】【USACO15OPEN】Trapped in the Haybales S