本文讲述Java项目中对金额的处理思考及实践策略;
做电商或者具有交易类需求的项目时,一定会涉及到金额信息的模型,例如账户余额、冻结余额、可用余额、可提现余额等等,所有与钱相关的字段,都可统称为金额信息;
金额信息,至少要从几个维度来考虑设计,首先是数据库存储使用的类型,第二是运算过程如何保证精度,第三是采用何种类型进行页面显示(一般都会有四舍五入、两位小数等需求);
对于存储类型,Mysql可考虑采用Bigint存储,单位是分的整型(也可使用decimal,但是要切记,全局一定要统一,要么全是bigint,要么全是decimal),对应到java实体类是Long类型的变量,运算时全部要采用java的BigDecimal进行(切记,加减乘除任何计算都必须使用),本文的代码实例也是采用的此种方案,下面是一个实际金融项目中用到的一个金额处理工具类,现分享给各位同仁,希望能够对各位有所启发和帮助。
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
* 金额转换工具类
* @author Administrator
*
*/
public class AmountUtil {
/**
* 返回单位元的2位小数String值
* @param longVal 单位:分
* @return
*/
public static String longToString(long longVal) {
BigDecimal bdCent = new BigDecimal(StringUtil.getString(longVal));
BigDecimal bd100 = new BigDecimal("100");
BigDecimal bdYuan = bdCent.divide(bd100);
String str = formatToNumber(bdYuan);
return str;
}
/**
* 返回单位元的2位小数String值
* @param longVal
* @return
*/
public static String double2p(double doubleVal) {
String str = formatToNumber(new BigDecimal(doubleVal));
return str;
}
/**
* 1.0~1之间的BigDecimal小数,格式化后失去前面的0,则前面直接加上0。
* 2.传入的参数等于0,则直接返回字符串"0.00"
* 3.大于1的小数,直接格式化返回字符串
* @param obj传入的小数
* @return
*/
public static String formatToNumber(BigDecimal obj) {
DecimalFormat df = new DecimalFormat("#.00");
if(obj.compareTo(BigDecimal.ZERO)==0) {
return "0.00";
}else if(obj.compareTo(BigDecimal.ZERO)>0&&obj.compareTo(new BigDecimal(1))<0){
return "0"+df.format(obj).toString();
}else {
return df.format(obj).toString();
}
}
}
上述代码中用到的StringUtil类:
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串工具类,提供一些字符串相关的便捷方法
*/
public class StringUtil {
private StringUtil() {
throw new AssertionError();
}
/**
* null Object to empty string
* 空对象转化成空字符串
* <pre>
* nullStrToEmpty(null) = "";
* nullStrToEmpty("") = "";
* nullStrToEmpty("aa") = "aa";
* </pre>
*
* @param object 对象
* @return String
*/
public static String getString(Object object) {
return object == null ?
"" : (object instanceof String ? (String)object : object.toString());
}
}