关于MySQL中存储类型为Float,使用jdbc查询时丢失精度,或者自动四舍五入的问题

一.   mysql表结构:

member_price列的数据类型是float(20,2)(注: 表示最多20位浮点数,精度为2位)

插入记录:

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘1‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.8745120‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘2‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.8743120‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘3‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.874‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘4‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.879‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘5‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.871‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘6‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.87‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘7‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.8‘, ‘1450078966586‘);

INSERT INTO `member_price` (`id`, `data_type`, `month`, `member_count`, `member_price`, `create_at`) VALUES (‘8‘, ‘1‘, ‘2015-11‘, ‘5864‘, ‘1765910.1‘, ‘1450078966586‘);

查询:

添加条件查询:

注意:

mysql中的float: 借此例说明float(20,2),虽然设置的精度为2位,但是每次插入值时会保存三位,但保存的这三位数是不精确的,如上所示。

查询时

  1. 如果插入是一位小数,但精度是两位,此时插入的数通过相等是查不出来的(除了第一位小数是0和5),因为mysql会将其补全到三位,最终保存的精度也是不准确的

  2. 如过插入是两位小数,并且精度是两位,此时插入的数通过相等也并不一定能查出来

  3. 对于三位小数的查询,同上

所以在mysql中的数值类型,float是不精确的,尽量避免使用,可使用double或者decimal,两者的差别是double是浮点计算,decimal是定点计算,会得到更精确的数据。

二.  jdbc中查询float类型的数据

java代码:

 1 public class Main {
 2     public static void main(String[] args){
 3         Connection connection = null;
 4         PreparedStatement preparedStatement = null;
 5         ResultSet resultSet = null;
 6         try {
 7             Class.forName("com.mysql.jdbc.Driver");
 8             connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user", "root", "123456a");
 9             String sql = "SELECT * from member_price WHERE `month` = ‘2015-11‘ and data_type = 1";
10             preparedStatement = connection.prepareStatement(sql);
11             resultSet = preparedStatement.executeQuery();
12             while(resultSet.next()){
13                 System.out.println("string: " + resultSet.getString("member_price"));  //通过String类型获取
14                 System.out.println("float: " + resultSet.getFloat("member_price"));    //通过Long类型获取
15                 System.out.println("============>next");
16             }
17         }catch (Exception e){
18             e.printStackTrace();
19         }finally {
20             try {
21                 resultSet.close();
22                 preparedStatement.close();
23                 connection.close();
24             } catch (SQLException e) {
25                 e.printStackTrace();
26             }
27         }
28
29     }
30 }

(代码不太规范,只为了演示)

截取一部分输出:

string: 1765910.88
float: 1765910.9
============>next
string: 1765910.75
float: 1765910.8
============>next
string: 1765910.12
float: 1765910.1
============>next
string: 1765910.25
float: 1765910.2
============>next
string: 1765910.00
float: 1765910.0
============>next
string: 1765910.38
float: 1765910.4
============>next
string: 1765910.50
float: 1765910.5
============>next
string: 1765910.62
float: 1765910.6
============>next

通过上变测试可以发现:

  1. 数据库中精度设置为2位,通过resultSet.getString()拿到的值是两位(和mysql中查到的是一致的),但通过resultSet.getLong()拿到的值是一位(这一位数是四舍五入的结果(但25最后拿到的是2,不知道为何))

  2. 使用FORMAT(member_price,10),TRUNCATE(member_price,10),ROUND(member_price,10)等函数来查询时,如果通过resultSet.getLong()来获取查询的值,最后也只能获取一位小数,需使用resultSet.getString()获取精确的查询结果。

结论: 最好在mysql中不要使用float类型, 对于浮点数的查询,jdbc中最好使用resultSet.getString()获取查询的结果值,resultSet.getLong()只会拿到一位小数

若有错误,欢迎批评指正^_^

时间: 2024-08-24 10:23:31

关于MySQL中存储类型为Float,使用jdbc查询时丢失精度,或者自动四舍五入的问题的相关文章

MySQL中int类型的字段使用like查询方法

方法参考自: http://stackoverflow.com/questions/8422455/performing-a-like-comparison-on-an-int-field 也就是使用CAST转换指定字段,然后进行比较.具体样例代码如下: SELECT ProductID, ProductName FROM Products WHERE CAST(ProductID as CHAR) LIKE '%15%' 但是这样做的话,MySQL不能使用对应int字段索引,而且like本身就

Java学习篇之---Mysql中varchar类型总结

Mysql中varchar类型总结 今天新做一个项目,需要自己进行数据库设计,发现自己对varchar的用法还不是很熟悉,所以查阅资料总结若下: 1.varchar类型的变化 MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0~255或1~255(根据不同版本数据库来定).在 MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了3个字 节,也就是说,在4.1或以

如何在mysql中存储音乐和图片文件

如何在mysql中存储音乐和图片文件? 果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的! 我将告诉你怎样通过HTML表单来储存这些文件,怎样访问和使用这些文件. 本文概述: 在mysql中建立一个新的数据库 一个怎样储存文件的例子程序 一个怎样访问文件的例子程序 在mysql中建立一个新的database 首先,你必须在你的mysql中建立一个新的数据库,我们将会把那些二进制文件储存在这个数据库里.在例子中我会使用下列结构,为了建立

MYSQL中TIMESTAMP类型的默认值

MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 表: —————————————————————————————————————— t1      CREATE TABLE `t1` (                                                                             `p_c` int(11) NOT NULL,                                              

MYSQL中TIMESTAMP类型的默认值理解

MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 1.自动UPDATE 和INSERT 到当前的时间:表:——————————— Table   Create Table                                                                         —— ————————————————————————————-t1      CREATE TABLE `t1` (                       

MySQL中不允许使用列别名作为查询条件

在MySQL中有个特殊的规定,即不允许使用列别名作为查询条件.比如有下面一个表: select     ID,     title,     concept,     conceptLength,     addUserId,     modifyTimefrom collections_wisdom 将SQL修改如下: select     ID+1 as newID,     title,     concept,     conceptLength,     addUserId,    

Mysql中使用FIND_IN_SET解决IN条件为字符串时只有第一个数据可用的问题

今天在使用Mysql的存储过程处理数据的批量删除时,遇到了WHERE条件中使用IN(strlist)时(strlist为逗号分隔的字符串),只有strlist的第一个元素才有效的问题,现在将问题和解决方法做下记录. 我们首先创建两张表userinfo(用户信息表)和userextinfo(用户扩展信息表),其中userextinfo表的UserID字段为外键对应userinfo表中的UserID字段 用户信息表userinfo 初始数据 用户扩展信息表userextinfo 初始数据 现在表中有

mysql 字段存储类型

摘自:http://zuo.ai.xiao.blog.163.com/blog/static/6079155320121293750732/ 1.数字类型                                          有符号                         无符号                                  存储(bytes)tinyint                            -128到127              

Sqlite3中存储类型和数据类型结合文档解析。

sqlite3是个很小的数据库,运行在手机,机顶盒上....那它就不可能像musql,sqlserver那么规范,有很多的数据类型,之前我也以为它定义了很多数据类型,其实不是他就5个存储类,那么多数据类型是根据一整套严谨的规则映射的!!还有什么char,varchar其实都是没有的..下面将结合文档详细讲解,相信看完你会了解更多,其实主要就是翻译文档.... sqlite官网:http://www.sqlite.org/ Sqlite3数据类型 大多数的数据库引擎(到现在据我们所知的除了sqli