Money工具类

公司做的电商项目所用的Money类,支持金额的加减乘除.

public class Money implements Serializable, Comparable {
 
 
    /**
     * 缺省的币种代码,为CNY(人民币)。
     */
    public static final String DEFAULT_CURRENCY_CODE = "CNY";
 
    /**
     * 缺省的取整模式,为<code>BigDecimal.ROUND_HALF_EVEN
     * (四舍五入,当小数为0.5时,则取最近的偶数)。
     */
    public static final int    DEFAULT_ROUNDING_MODE = BigDecimal.ROUND_HALF_EVEN;
 
    /**
     * 一组可能的元/分换算比例。
     *
     * <p>
     * 此处,“分”是指货币的最小单位,“元”是货币的最常用单位,
     * 不同的币种有不同的元/分换算比例,如人民币是100,而日元为1。
     */
    private static final int[] centFactors  = new int[] { 1, 10, 100, 1000 };
 
    /**
     * 金额,以分为单位。
     */
    private long  cent;
 
    /**
     * 币种。
     */
    private Currency currency;
 
   
 
    /**
     * 缺省构造器。
     *
     * <p>
     * 创建一个具有缺省金额(0)和缺省币种的货币对象。
     */
    public Money() {
        this(0);
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>yuan</code>元<code>cent</cent>分和缺省币种的货币对象。
     *
     * @param yuan 金额元数。
     * @param cent 金额分数。
     */
    public Money(long yuan, int cent) {
        this(yuan, cent, Currency.getInstance(DEFAULT_CURRENCY_CODE));
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>yuan</code>元<code>cent</code>分和指定币种的货币对象。
     *
     * @param yuan 金额元数。
     * @param cent 金额分数。
     */
    public Money(long yuan, int cent, Currency currency) {
        this.currency = currency;
 
        this.cent = (yuan * getCentFactor()) + (cent % getCentFactor());
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>元和缺省币种的货币对象。
     *
     * @param amount 金额,以元为单位。
     */
    public Money(String amount) {
        this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE));
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>元和指定币种<code>currency</code>的货币对象。
     *
     * @param amount 金额,以元为单位。
     * @param currency 币种。
     */
    public Money(String amount, Currency currency) {
        this(new BigDecimal(amount), currency);
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>元和指定币种<code>currency</code>的货币对象。
     * 如果金额不能转换为整数分,则使用指定的取整模式<code>roundingMode</code>取整。
     *
     * @param amount 金额,以元为单位。
     * @param currency 币种。
     * @param roundingMode 取整模式。
     */
    public Money(String amount, Currency currency, int roundingMode) {
        this(new BigDecimal(amount), currency, roundingMode);
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有参数<code>amount</code>指定金额和缺省币种的货币对象。
     * 如果金额不能转换为整数分,则使用四舍五入方式取整。
     *
     * <p>
     * 注意:由于double类型运算中存在误差,使用四舍五入方式取整的
     * 结果并不确定,因此,应尽量避免使用double类型创建货币类型。
     *
     * @param amount 金额,以元为单位。
     *
     */
    public Money(double amount) {
        this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE));
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>和指定币种的货币对象。
     * 如果金额不能转换为整数分,则使用四舍五入方式取整。
     *
     * <p>
     * 注意:由于double类型运算中存在误差,使用四舍五入方式取整的
     * 结果并不确定,因此,应尽量避免使用double类型创建货币类型。
     *
     * @param amount 金额,以元为单位。
     * @param currency 币种。
     */
    public Money(double amount, Currency currency) {
        this.currency = currency;
        this.cent = Math.round(amount * getCentFactor());
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>和缺省币种的货币对象。
     * 如果金额不能转换为整数分,则使用缺省取整模式<code>DEFAULT_ROUNDING_MODE</code>取整。
     *
     * @param amount 金额,以元为单位。
     */
    public Money(BigDecimal amount) {
        this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE));
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有参数<code>amount</code>指定金额和缺省币种的货币对象。
     * 如果金额不能转换为整数分,则使用指定的取整模式<code>roundingMode</code>取整。
     *
     * @param amount 金额,以元为单位。
     * @param roundingMode 取整模式
     *
     */
    public Money(BigDecimal amount, int roundingMode) {
        this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE), roundingMode);
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>和指定币种的货币对象。
     * 如果金额不能转换为整数分,则使用缺省的取整模式<code>DEFAULT_ROUNDING_MODE</code>进行取整。
     *
     * @param amount 金额,以元为单位。
     * @param currency 币种
     */
    public Money(BigDecimal amount, Currency currency) {
        this(amount, currency, DEFAULT_ROUNDING_MODE);
    }
 
    /**
     * 构造器。
     *
     * <p>
     * 创建一个具有金额<code>amount</code>和指定币种的货币对象。
     * 如果金额不能转换为整数分,则使用指定的取整模式<code>roundingMode</code>取整。
     *
     * @param amount 金额,以元为单位。
     * @param currency 币种。
     * @param roundingMode 取整模式。
     */
    public Money(BigDecimal amount, Currency currency, int roundingMode) {
        this.currency = currency;
        this.cent = rounding(amount.movePointRight(currency.getDefaultFractionDigits()),
                roundingMode);
    }
 
    // Bean方法 ====================================================
 
    /**
     * 获取本货币对象代表的金额数。
     *
     * @return 金额数,以元为单位。
     */
    public BigDecimal getAmount() {
        return BigDecimal.valueOf(cent, currency.getDefaultFractionDigits());
    }
 
    /**
     * 设置本货币对象代表的金额数。
     *
     * @param amount 金额数,以元为单位。
     */
    public void setAmount(BigDecimal amount) {
        if (amount != null) {
            cent = rounding(amount.movePointRight(2), BigDecimal.ROUND_HALF_EVEN);
        }
    }
 
    /**
     * 获取本货币对象代表的金额数。
     *
     * @return 金额数,以分为单位。
     */
    public long getCent() {
        return cent;
    }
 
    /**
     * 获取本货币对象代表的币种。
     *
     * @return 本货币对象所代表的币种。
     */
    public Currency getCurrency() {
        return currency;
    }
 
    /**
     * 设置本货币对象代表的币种码.
     *
     * @param currencyCode 币种, 如果为<code>null</null>, 设置为默认币种
     * @throws IllegalArgumentException 所设置的币种码非ISO 4217标准支持的币种
     * @see #DEFAULT_CURRENCY_CODE
     */
    public void setCurrencyCode(String currencyCode) {
        if (null != currencyCode) {
            this.currency = Currency.getInstance(currencyCode);
        } else {
            this.currency = Currency.getInstance(DEFAULT_CURRENCY_CODE);
        }
    }
 
    /**
     * 获取本货币对象代码的币种码.
     *
     * @return 币种码
     */
    public String getCurrencyCode() {
        if (null == currency) {
            return DEFAULT_CURRENCY_CODE;
        } else {
            return currency.getCurrencyCode();
        }
    }
 
    /**
     * 获取本货币币种的元/分换算比率。
     *
     * @return 本货币币种的元/分换算比率。
     */
    public int getCentFactor() {
        return centFactors[currency.getDefaultFractionDigits()];
    }
 
    // 基本对象方法 ===================================================
 
    /**
     * 判断本货币对象与另一对象是否相等。
     *
     * <p>
     * 本货币对象与另一对象相等的充分必要条件是:<br>
     *  <ul>
     *   <li>另一对象也属货币对象类。
     *   <li>金额相同。
     *   <li>币种相同。
     *  </ul>
     *
     * @param other 待比较的另一对象。
     * @return <code>true</code>表示相等,<code>false</code>表示不相等。
     *
     * @see Object#equals(Object)
     */
    public boolean equals(Object other) {
        return (other instanceof Money) && equals((Money) other);
    }
 
    /**
     * 判断本货币对象与另一货币对象是否相等。
     *
     * <p>
     * 本货币对象与另一货币对象相等的充分必要条件是:<br>
     *  <ul>
     *   <li>金额相同。
     *   <li>币种相同。
     *  </ul>
     *
     * @param other 待比较的另一货币对象。
     * @return <code>true</code>表示相等,<code>false</code>表示不相等。
     */
    public boolean equals(Money other) {
        return currency.equals(other.currency) && (cent == other.cent);
    }
 
    /**
     * 计算本货币对象的杂凑值。
     *
     * @return 本货币对象的杂凑值。
     *
     * @see Object#hashCode()
     */
    public int hashCode() {
        return (int) (cent ^ (cent >>> 32));
    }
 
    // Comparable接口 ========================================
 
    /**
     * 对象比较。
     *
     * <p>
     * 比较本对象与另一对象的大小。
     * 如果待比较的对象的类型不是<code>Money</code>,则抛出<code>java.lang.ClassCastException</code>。
     * 如果待比较的两个货币对象的币种不同,则抛出<code>java.lang.IllegalArgumentException</code>。
     * 如果本货币对象的金额少于待比较货币对象,则返回-1。
     * 如果本货币对象的金额等于待比较货币对象,则返回0。
     * 如果本货币对象的金额大于待比较货币对象,则返回1。
     *
     * @param other 另一对象。
     * @return -1表示小于,0表示等于,1表示大于。
     *
     * @exception ClassCastException 待比较货币对象不是<code>Money</code>。
     *            IllegalArgumentException 待比较货币对象与本货币对象的币种不同。
     *
     * @see Comparable#compareTo(Object)
     */
    public int compareTo(Object other) {
        return compareTo((Money) other);
    }
 
    /**
     * 货币比较。
     *
     * <p>
     * 比较本货币对象与另一货币对象的大小。
     * 如果待比较的两个货币对象的币种不同,则抛出<code>java.lang.IllegalArgumentException</code>。
     * 如果本货币对象的金额少于待比较货币对象,则返回-1。
     * 如果本货币对象的金额等于待比较货币对象,则返回0。
     * 如果本货币对象的金额大于待比较货币对象,则返回1。
     *
     * @param other 另一对象。
     * @return -1表示小于,0表示等于,1表示大于。
     *
     * @exception IllegalArgumentException 待比较货币对象与本货币对象的币种不同。
     */
    public int compareTo(Money other) {
        assertSameCurrencyAs(other);
 
        if (cent < other.cent) {
            return -1;
        } else if (cent == other.cent) {
            return 0;
        } else {
            return 1;
        }
    }
 
    /**
     * 货币比较。
     *
     * <p>
     * 判断本货币对象是否大于另一货币对象。
     * 如果待比较的两个货币对象的币种不同,则抛出<code>java.lang.IllegalArgumentException</code>。
     * 如果本货币对象的金额大于待比较货币对象,则返回true,否则返回false。
     *
     * @param other 另一对象。
     * @return true表示大于,false表示不大于(小于等于)。
     *
     * @exception IllegalArgumentException 待比较货币对象与本货币对象的币种不同。
     */
    public boolean greaterThan(Money other) {
        return compareTo(other) > 0;
    }
 
    // 货币算术 

    /**
     * 货币加法。
     *
     * <p>
     * 如果两货币币种相同,则返回一个新的相同币种的货币对象,其金额为
     * 两货币对象金额之和,本货币对象的值不变。
     * 如果两货币对象币种不同,抛出<code>java.lang.IllegalArgumentException</code>。
     *
     * @param other 作为加数的货币对象。
     *
     * @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
     *
     * @return 相加后的结果。
     */
    public Money add(Money other) {
        assertSameCurrencyAs(other);
 
        return newMoneyWithSameCurrency(cent + other.cent);
    }
 
    /**
     * 货币累加。
     *
     * <p>
     * 如果两货币币种相同,则本货币对象的金额等于两货币对象金额之和,并返回本货币对象的引用。
     * 如果两货币对象币种不同,抛出<code>java.lang.IllegalArgumentException</code>。
     *
     * @param other 作为加数的货币对象。
     *
     * @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
     *
     * @return 累加后的本货币对象。
     */
    public Money addTo(Money other) {
        assertSameCurrencyAs(other);
 
        this.cent += other.cent;
 
        return this;
    }
 
    /**
     * 货币减法。
     *
     * <p>
     * 如果两货币币种相同,则返回一个新的相同币种的货币对象,其金额为
     * 本货币对象的金额减去参数货币对象的金额。本货币对象的值不变。
     * 如果两货币币种不同,抛出<code>java.lang.IllegalArgumentException</code>。
     *
     * @param other 作为减数的货币对象。
     *
     * @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
     *
     * @return 相减后的结果。
     */
    public Money subtract(Money other) {
        assertSameCurrencyAs(other);
 
        return newMoneyWithSameCurrency(cent - other.cent);
    }
 
    /**
     * 货币累减。
     *
     * <p>
     * 如果两货币币种相同,则本货币对象的金额等于两货币对象金额之差,并返回本货币对象的引用。
     * 如果两货币币种不同,抛出<code>java.lang.IllegalArgumentException</code>。
     *
     * @param other 作为减数的货币对象。
     *
     * @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
     *
     * @return 累减后的本货币对象。
     */
    public Money subtractFrom(Money other) {
        assertSameCurrencyAs(other);
 
        this.cent -= other.cent;
 
        return this;
    }
 
    /**
     * 货币乘法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
     * 本货币对象的值不变。
     *
     * @param val 乘数
     *
     * @return 乘法后的结果。
     */
    public Money multiply(long val) {
        return newMoneyWithSameCurrency(cent * val);
    }
 
    /**
     * 货币累乘。
     *
     * <p>
     * 本货币对象金额乘以乘数,并返回本货币对象。
     *
     * @param val 乘数
     *
     * @return 累乘后的本货币对象。
     */
    public Money multiplyBy(long val) {
        this.cent *= val;
 
        return this;
    }
 
    /**
     * 货币乘法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
     * 本货币对象的值不变。如果相乘后的金额不能转换为整数分,则四舍五入。
     *
     * @param val 乘数
     *
     * @return 相乘后的结果。
     */
    public Money multiply(double val) {
        return newMoneyWithSameCurrency(Math.round(cent * val));
    }
 
    /**
     * 货币累乘。
     *
     * <p>
     * 本货币对象金额乘以乘数,并返回本货币对象。
     * 如果相乘后的金额不能转换为整数分,则使用四舍五入。
     *
     * @param val 乘数
     *
     * @return 累乘后的本货币对象。
     */
    public Money multiplyBy(double val) {
        this.cent = Math.round(this.cent * val);
 
        return this;
    }
 
    /**
     * 货币乘法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
     * 本货币对象的值不变。如果相乘后的金额不能转换为整数分,使用缺省的取整模式
     * <code>DEFUALT_ROUNDING_MODE</code>进行取整。
     *
     * @param val 乘数
     *
     * @return 相乘后的结果。
     */
    public Money multiply(BigDecimal val) {
        return multiply(val, DEFAULT_ROUNDING_MODE);
    }
 
    /**
     * 货币累乘。
     *
     * <p>
     * 本货币对象金额乘以乘数,并返回本货币对象。
     * 如果相乘后的金额不能转换为整数分,使用缺省的取整方式
     * <code>DEFUALT_ROUNDING_MODE</code>进行取整。
     *
     * @param val 乘数
     *
     * @return 累乘后的结果。
     */
    public Money multiplyBy(BigDecimal val) {
        return multiplyBy(val, DEFAULT_ROUNDING_MODE);
    }
 
    /**
     * 货币乘法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
     * 本货币对象的值不变。如果相乘后的金额不能转换为整数分,使用指定的取整方式
     * <code>roundingMode</code>进行取整。
     *
     * @param val 乘数
     * @param roundingMode 取整方式
     *
     * @return 相乘后的结果。
     */
    public Money multiply(BigDecimal val, int roundingMode) {
        BigDecimal newCent = BigDecimal.valueOf(cent).multiply(val);
 
        return newMoneyWithSameCurrency(rounding(newCent, roundingMode));
    }
 
    /**
     * 货币累乘。
     *
     * <p>
     * 本货币对象金额乘以乘数,并返回本货币对象。
     * 如果相乘后的金额不能转换为整数分,使用指定的取整方式
     * <code>roundingMode</code>进行取整。
     *
     * @param val 乘数
     * @param roundingMode 取整方式
     *
     * @return 累乘后的结果。
     */
    public Money multiplyBy(BigDecimal val, int roundingMode) {
        BigDecimal newCent = BigDecimal.valueOf(cent).multiply(val);
 
        this.cent = rounding(newCent, roundingMode);
 
        return this;
    }
 
    /**
     * 货币除法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额除以除数。
     * 本货币对象的值不变。如果相除后的金额不能转换为整数分,使用四舍五入方式取整。
     *
     * @param val 除数
     *
     * @return 相除后的结果。
     */
    public Money divide(double val) {
        return newMoneyWithSameCurrency(Math.round(cent / val));
    }
 
    /**
     * 货币累除。
     *
     * <p>
     * 本货币对象金额除以除数,并返回本货币对象。
     * 如果相除后的金额不能转换为整数分,使用四舍五入方式取整。
     *
     * @param val 除数
     *
     * @return 累除后的结果。
     */
    public Money divideBy(double val) {
        this.cent = Math.round(this.cent / val);
 
        return this;
    }
 
    /**
     * 货币除法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额除以除数。
     * 本货币对象的值不变。如果相除后的金额不能转换为整数分,使用缺省的取整模式
     * <code>DEFAULT_ROUNDING_MODE</code>进行取整。
     *
     * @param val 除数
     *
     * @return 相除后的结果。
     */
    public Money divide(BigDecimal val) {
        return divide(val, DEFAULT_ROUNDING_MODE);
    }
 
    /**
     * 货币除法。
     *
     * <p>
     * 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额除以除数。
     * 本货币对象的值不变。如果相除后的金额不能转换为整数分,使用指定的取整模式
     * <code>roundingMode</code>进行取整。
     *
     * @param val 除数
     * @param roundingMode 取整
     *
     * @return 相除后的结果。
     */
    public Money divide(BigDecimal val, int roundingMode) {
        BigDecimal newCent = BigDecimal.valueOf(cent).divide(val, roundingMode);
 
        return newMoneyWithSameCurrency(newCent.longValue());
    }
 
    /**
     * 货币累除。
     *
     * <p>
     * 本货币对象金额除以除数,并返回本货币对象。
     * 如果相除后的金额不能转换为整数分,使用缺省的取整模式
     * <code>DEFAULT_ROUNDING_MODE</code>进行取整。
     *
     * @param val 除数
     *
     * @return 累除后的结果。
     */
    public Money divideBy(BigDecimal val) {
        return divideBy(val, DEFAULT_ROUNDING_MODE);
    }
 
    /**
     * 货币累除。
     *
     * <p>
     * 本货币对象金额除以除数,并返回本货币对象。
     * 如果相除后的金额不能转换为整数分,使用指定的取整模式
     * <code>roundingMode</code>进行取整。
     *
     * @param val 除数
     *
     * @return 累除后的结果。
     */
    public Money divideBy(BigDecimal val, int roundingMode) {
        BigDecimal newCent = BigDecimal.valueOf(cent).divide(val, roundingMode);
 
        this.cent = newCent.longValue();
 
        return this;
    }
 
    /**
     * 货币分配。
     *
     * <p>
     * 将本货币对象尽可能平均分配成<code>targets</code>份。
     * 如果不能平均分配尽,则将零头放到开始的若干份中。分配
     * 运算能够确保不会丢失金额零头。
     *
     * @param targets 待分配的份数
     *
     * @return 货币对象数组,数组的长度与分配份数相同,数组元素
     *         从大到小排列,所有货币对象的金额最多只相差1分。
     */
    public Money[] allocate(int targets) {
        Money[] results = new Money[targets];
 
        Money lowResult = newMoneyWithSameCurrency(cent / targets);
        Money highResult = newMoneyWithSameCurrency(lowResult.cent + 1);
 
        int remainder = (int) cent % targets;
 
        for (int i = 0; i < remainder; i++) {
            results[i] = highResult;
        }
 
        for (int i = remainder; i < targets; i++) {
            results[i] = lowResult;
        }
 
        return results;
    }
 
    /**
     * 货币分配。
     *
     * <p>
     * 将本货币对象按照规定的比例分配成若干份。分配所剩的零头
     * 从第一份开始顺序分配。分配运算确保不会丢失金额零头。
     *
     * @param ratios 分配比例数组,每一个比例是一个长整型,代表
     *               相对于总数的相对数。
     *
     * @return 货币对象数组,数组的长度与分配比例数组的长度相同。
     */
    public Money[] allocate(long[] ratios) {
        Money[] results = new Money[ratios.length];
 
        long total = 0;
 
        for (int i = 0; i < ratios.length; i++) {
            total += ratios[i];
        }
 
        long remainder = cent;
 
        for (int i = 0; i < results.length; i++) {
            results[i] = newMoneyWithSameCurrency((cent * ratios[i]) / total);
            remainder -= results[i].cent;
        }
 
        for (int i = 0; i < remainder; i++) {
            results[i].cent++;
        }
 
        return results;
    }
 
    // 格式化方法 
 
    /**
     * 生成本对象的缺省字符串表示
     */
    public String toString() {
        return getAmount().toString();
    }
 
    // 内部方法 
 
    /**
     * 断言本货币对象与另一货币对象是否具有相同的币种。
     *
     * <p>
     * 如果本货币对象与另一货币对象具有相同的币种,则方法返回。
     * 否则抛出运行时异常<code>java.lang.IllegalArgumentException</code>。
     *
     * @param other 另一货币对象
     *
     * @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
     */
    protected void assertSameCurrencyAs(Money other) {
        if (!currency.equals(other.currency)) {
            throw new IllegalArgumentException("Money math currency mismatch.");
        }
    }
 
    /**
     * 对BigDecimal型的值按指定取整方式取整。
     *
     * @param val 待取整的BigDecimal值
     * @param roundingMode 取整方式
     *
     * @return 取整后的long型值
     */
    protected long rounding(BigDecimal val, int roundingMode) {
        return val.setScale(0, roundingMode).longValue();
    }
 
    /**
     * 创建一个币种相同,具有指定金额的货币对象。
     *
     * @param cent 金额,以分为单位
     *
     * @return 一个新建的币种相同,具有指定金额的货币对象
     */
    protected Money newMoneyWithSameCurrency(long cent) {
        Money money = new Money(0, currency);
 
        money.cent = cent;
 
        return money;
    }
 
    // 调试方式 
    /**
     * 生成本对象内部变量的字符串表示,用于调试。
     *
     * @return 本对象内部变量的字符串表示。
     */
    public String dump() {
        String lineSeparator = System.getProperty("line.separator");
 
        StringBuffer sb = new StringBuffer();
 
        sb.append("cent = ").append(cent).append(lineSeparator);
        sb.append("currency = ").append(currency);
 
        return sb.toString();
    }
 
    /**
     * 设置货币的分值。
     *
     * @param l
     */
    public void setCent(long l) {
        cent = l;
    }
}

操作MySQL,项目中使用mybaties需要配置MoneyTypeHandler和mybaties-config.xml,否则mybaties无法识别Money类.

MoneyTypeHandler:

public class MoneyTypeHandler extends BaseTypeHandler<Money> {
    private static final Logger logger = LoggerFactory.getLogger(MoneyTypeHandler.class);

    public MoneyTypeHandler() {
    }

    public void setNonNullParameter(PreparedStatement ps, int i, Money parameter, JdbcType jdbcType) throws SQLException {
        ps.setBigDecimal(i, parameter.getAmount());
    }

    public Money getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return this.convertMoney(rs.getBigDecimal(columnName), "");
    }

    public Money getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.convertMoney(rs.getBigDecimal(columnIndex), "");
    }

    public Money getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.convertMoney(cs.getBigDecimal(columnIndex), "");
    }

    private Money convertMoney(BigDecimal value, String currencyCode) {
        return StringUtils.isEmpty(currencyCode) ? new Money(value == null ? new BigDecimal(0.0D) : value) : new Money(value == null ? new BigDecimal(0.0D) : value, currencyCode);
    }
}

mybaties-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC
        "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="cn.xxx.rights.po"/>
    </typeAliases>

    <typeHandlers>
        <typeHandler handler="cn.xxx.miracle.shardingsphere.money.MoneyTypeHandler"/>
    </typeHandlers>

</configuration>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值