[转帖]MySQL的sum函数返回的类型

原帖地址: http://bylijinnan.iteye.com/blog/1984472?utm_source=tuicool

摘要 : 

  1. The SUM() and AVG() functions return a DECIMAL value for exact-value arguments (integer or DECIMAL), and a DOUBLE value for approximate-value arguments (FLOAT or DOUBLE). (Before MySQL 5.0.3, SUM() and AVG() return DOUBLE for all numeric arguments.)  



原文:

今天项目切换数据库时,出错 

访问数据库的代码大概是这样: 

Java代码   收藏代码
  1. String sql =  "select sum(number) as sumNumberOfOneDay from tableName";  
  2. List<Map> rows = getJdbcTemplate().queryForList(sql);  
  3. for (Map row : rows) {  
  4.     SomeBean item = new SomeBean();  
  5.     item.setSumNumberOfOneDay(objectToInt(row.get("sumNumberOfOneDay")));  
  6.   
  7. }  
  8.       
  9. private int objectToInt(Object obj) {  
  10.     return Integer.parseInt("" + obj);  
  11. }  


表字段“number”的类型是int(10) unsigned 
        
连接数据库DataBaseA,测试运行正常;切换到另一数据库DataBaseB(数据库表,表名,表结构一样)时,发现报错: 
java.lang.NumberFormatException: For input string: "10.0" 

把sql语句拷贝到MySQL命令行窗口里面直接执行,sum(number)返回的值是10; 
但在Spring的getJdbcTemplate().queryForList(sql)返回,则变成了10.0, 
打印row.get("sumNumberOfOneDay").getClass()的结果是:class java.lang.Double 

切回DataBaseA,打印结果是java.math.BigDecimal 

两个数据库的查询结果在MySQL命令行窗口返回整数,但在Java程序中返回浮点数 

那不用Spring,直接操作JDBC: 
Java代码   收藏代码
  1. Connection conn = getJdbcTemplate().getDataSource().getConnection();  
  2.            Statement st = conn.createStatement();  
  3.            ResultSet rs = st.executeQuery(sql);  
  4.            ResultSetMetaData rsmd = rs.getMetaData();  
  5.            for (int i = 1; i <= rsmd.getColumnCount(); i++) {  
  6.                String name = rsmd.getColumnName(i);  
  7.                String type = rsmd.getColumnTypeName(i);  
  8.                System.out.println(name + ", " + type);  
  9.            }  

DataBaseA打印的结果: 
sumNumberOfOneDay, DECIMAL 

DataBaseB打印的结果: 
sumNumberOfOneDay, DOUBLE 

基本可判断是MySQL的问题 

网上搜索一下,果然: 
Java代码   收藏代码
  1. The SUM() and AVG() functions return a DECIMAL value for exact-value arguments (integer or DECIMAL), and a DOUBLE value for approximate-value arguments (FLOAT or DOUBLE). (Before MySQL 5.0.3, SUM() and AVG() return DOUBLE for all numeric arguments.)  

http://stackoverflow.com/questions/10592481/what-is-the-return-type-of-sum-in-mysql  

原来MySQL 5.0.3之前的版本,sum函数返回的是DOUBLE类型 

回头检查一下MySQL的版本: 

DataBaseA: 
5.1.44 Source distribution 

DataBaseB: 
4.1.7-standard-log 

果然是这样 

解决办法: 
1.笨方法,就是重写objectToInt方法: 
Java代码   收藏代码
  1. if (obj instanceof Double) {  
  2.            return ((Double)obj).intValue();  
  3.        }  
  4.        if (obj instanceof BigDecimal) {  
  5.            return ((BigDecimal)obj).intValue();  
  6.        }  
  7.        return Integer.parseInt(obj.toString());  
  8.           

2.利用Spring的BeanPropertyRowMapper: 
Java代码   收藏代码
  1. List<SomeBean> list = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(SomeBean.class));  

应该尽量采用方法2,避免自己处理 

查看一下Spring的getJdbcTemplate().query(sql, new BeanPropertyRowMapper(SomeBean.class))方法, 
发现它的大体思路是这样: 
1.通过SomeBean.class得到所有property 
2.根据property的类型,调用ResultSet.getXXX()得到对应的值 
在ResultSet.getXXX()方法里面,就实现了类型转换 
例如com.mysql.jdbc.Result的getInt方法(关键部分的代码): 
Java代码   收藏代码
  1. val = getString(columnIndex);  
  2.         if ((val != null) && (val.length() != 0)) {  
  3.             if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)  
  4.                     && (val.indexOf(".") == -1)) {  
  5.                 return Integer.parseInt(val);  
  6.             } else {  
  7.                 // Convert floating point  
  8.                 return (int) (Double.parseDouble(val));  
  9.             }  
  10.         } else {  
  11.             return 0;  
  12.         }  

猜你喜欢

转载自blog.csdn.net/ranweizheng/article/details/45825449
今日推荐