Skip to content

Instantly share code, notes, and snippets.

@junlincao
Created August 18, 2017 02:54
Show Gist options
  • Save junlincao/b82d6b1aa1cec218b0e3df2073f7acdb to your computer and use it in GitHub Desktop.
Save junlincao/b82d6b1aa1cec218b0e3df2073f7acdb to your computer and use it in GitHub Desktop.
Somthing about cursor.getText() and cursor.getDouble()
UserCharge imoney为double类型:
cursor.getText() 和 cursor.getDouble()效果不能保证为一致!
getText()方法可能丢失精度,getDouble()方法结果正确
UserCharge imoney 为 text类型:
查询cursor.getText() 和 cursor.getDouble()效果一致!而且text类型并不影响sql对字段查询统计求和等操作
而且由于cursor代码是系统代码无法修改,ORM 将UserCharge的imoney字段改为String 或者 BigDecimal都只是按text读取,反而用double能保证读取结果正确
因此,sql查询结果中所有列为text可以保证结果正确
或者cursor获取数字列采用getDouble也可以保证结果正确
有个简单办法,强行将表中所有字段改为text类型存储,这样不管按text读字段还是double读字段都没问题。
sqlite不允许改字段类型,旧版本数据库升级的时候,变相改字段类型方法有下面2种:
1.可以先创建一个临时表,再删除原表,将临时表表名改为原表表名
比如:
create table tmp_charge as select * from bk_user_charge;
drop table bk_user_charge;
alter table tmp_charge rename to bk_user_charge;
这种会丢失主键外键索引等一堆信息
2.将数据复制到临时表,再删除原表,创建新的字段为text的表(同时处理好主键外键等信息),将临时表数据copy过来。这个需要处理所有字段,sql类似上面的,只是更麻烦
跑通代码一看,统计查询结果仍然不精确!
因为即使imoney字段为text,如果sql中做了运算,比如sum(imoney),则这列结果又会变成double
cursor.getText()很有可能又会丢失精度了,这种方式走不通。
根据上面分析,解决问题方法有2种,一种是金额全部按double读取,一种是将查询结果字段改为text
1、按double读取,OrmLite提供的queryRaw()查询方法需要制定DataType 对金额的字段指定为DataType.DOUBLE,其它指定为DataType.STRING即可。
然而,queryRaw有个方法是指定RawRowMapper,这个本来是为了简便操作,可以直接将查询结果映射为java对象的。可是这个方法默认获取字段全为getString()
需要指定其DataType,这映射对象就没有一点方便性了。。。因此,下边的方案更好用
2、将查询结果中数字字段强行转为text类型!根据上面的分析,这样不管采用getText()还是getDouble()都没问题了。将结果强制转换为text类型有2种方法,一种是采用sqlite 的cast方法,另一种简单,类似于java将数字转为字符串,将数字拼接一个字符串即可
select cast(uc.imoney as text) as imoney from bk_user_charge;
select uc.imoney || '' as imoney from bk_user_charge;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment