`
liulanghan110
  • 浏览: 1064204 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Mybatis的Date类型不走索引的问题

阅读更多

该问题出现在ORACLE 数据库,其他数据库没有试过。

如果JAVA中的属性为DATE,而数据库中是DATE类型的话。mybatis会默认将JAVA中DATE属性映射到数据库的

Timestamp类型。这时就会有这样的查询

where create_time >= v_time

左边为DATE右边为Timestamp.类型不一致,ORACLE会隐式将小的转成大的。

也就是变成这样

where to_Timestamp(create_time) >= v_time

这样导致左边的列用到函数的。索引列上使用函数后会导致索引失效。

 

 

开始想的解决办法是指定handle,或指定jdbcType

 

typeHandler=org.apache.ibatis.type.DateOnlyTypeHandler
或者指定
jdbcType=DATE
 
但这两种办法都有一个缺点,会将时间分截取掉,只留年月日
这样带时分秒的查询就不行了。
 
带时分秒的查询有如下三种解决办法:
 
1.将数据库字段改成Timestamp类型
 
2.将JAVA的属性改成字符串,然后mybatis这样写
 
where create_time >=  to_date(#{v_time},'YYYY-MM-DD HH24:MI:SS')  
3.利用一个小技巧timestamp+0会直接强转成date类型
where create_time >=  #{v_time} + 0 
 
4.使用一个下面这样的自定义handle,将JAVA的DATE类型转成字符串,然后在mybatis中将字符串转成DATE
HANDLE代码如下:
public class DateTimeTypeHandler extends BaseTypeHandler<Date> {
public void setNonNullParameter(PreparedStatement ps, int i,
        Date parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, dateToString(parameter));
}
public Date getNullableResult(ResultSet rs, String columnName)
        throws SQLException {
java.sql.Timestamp sqlTimestamp = rs.getTimestamp(columnName);
if (sqlTimestamp != null) {
return new java.util.Date(sqlTimestamp.getTime());
}
return null;
}
public Date getNullableResult(CallableStatement cs, int columnIndex)
        throws SQLException {
java.sql.Timestamp sqlTimestamp = cs.getTimestamp(columnIndex);
if (sqlTimestamp != null) {
return new java.util.Date(sqlTimestamp.getTime());
}
return null;
}
public String dateToString(Date date){
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
return df.format(date);
}
}
 
mybatis中代码如下:
where create_time >=  to_date(#{v_time,typeHandler=com.mybatisTypehandle.DateTimeTypeHandler},'yyyy-mm-dd hh24:mi:ss') 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics