关注我,更多精彩文章第一时间推送给你
货币类中封装了货币金额和币种。目前金额在内部是long类型表示, 单位是所属币种的最小货币单位(对人民币是分)。
目前,货币实现了以下主要功能:
- 支持货币对象与double(float)/long(int)/String/BigDecimal之间相互转换。
- 货币类在运算中提供与JDK中的BigDecimal类似的运算接口, BigDecimal的运算接口支持任意指定精度的运算功能,能够支持各种 可能的财务规则。
- 货币类在运算中也提供一组简单运算接口,使用这组运算接口,则在 精度处理上使用缺省的处理规则。
- 推荐使用Money,不建议直接使用BigDecimal的原因之一在于, 使用BigDecimal,同样金额和币种的货币使用BigDecimal存在多种可能 的表示,例如:new BigDecimal("10.5")与new BigDecimal("10.50") 不相等,因为scale不等。使得Money类,同样金额和币种的货币只有 一种表示方式,new Money("10.5")和new Money("10.50")应该是相等的。
- 不推荐直接使用BigDecimal的另一原因在于, BigDecimal是Immutable, 一旦创建就不可更改,对BigDecimal进行任意运算都会生成一个新的 BigDecimal对象,因此对于大批量统计的性能不够满意。Money类是 mutable的,对大批量统计提供较好的支持。
- 提供基本的格式化功能。
- Money类中不包含与业务相关的统计功能和格式化功能。业务相关的功能 建议使用utility类来实现。
- Money类实现了Serializable接口,支持作为远程调用的参数和返回值。
- Money类实现了equals和hashCode方法。
使用步骤与前提
1.推荐数据库使用bigint(20)类型存储金额
2.实体类使用Money类型
3.引入Hutool依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.2</version>
</dependency>
4.这里主要针对mybatis plus使用进行讲解
分析mybatis 的BaseTypeHandler类
BaseTypeHandler是类型处理器的基类。
MyBatis 中的 TypeHandler 类型处理器用于 JavaType 与 JdbcType 之间的转换,用于 PreparedStatement 设置参数值和从 ResultSet 或 CallableStatement 中取出一个值。
jdbc中bigint对应java的是long,所以需要做一层long到Money的转换,这时候就需要使用mybatis提供的BaseTypeHandler了。我们需要实现一个MoneyTypeHandler继承自BaseTypeHandler完成这个转换。
/**
* @author yunqing
* @since 2020/9/17 21:15
*/
public class MoneyTypeHandler extends BaseTypeHandler<Money> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Money money, JdbcType jdbcType) throws SQLException {
ps.setLong(i, money.getCent());
}
@Override
public Money getNullableResult(ResultSet rs, String s) throws SQLException {
return new Money(rs.getString(s));
}
@Override
public Money getNullableResult(ResultSet rs, int i) throws SQLException {
return new Money(rs.getString(i));
}
@Override
public Money getNullableResult(CallableStatement cs, int i) throws SQLException {
return new Money(cs.getString(i));
}
}
结合mybatis plus的字段类型处理器
类型处理器,用于 JavaType 与 JdbcType 之间的转换,用于 PreparedStatement 设置参数值和从 ResultSet 或 CallableStatement 中取出一个值,主要用于 mybaits-plus 内置常用类型处理器如何通过TableField注解快速注入到 mybatis 容器中。
/**
* 注意我这这里开启了映射注解
*/
@TableName(value = "mmall_product", autoResultMap = true)
@ApiModel(value="Product对象", description="")
public class Product extends Model<Product> {
/**
* 必须开启映射注解
* @TableName(autoResultMap = true)
*/
@TableField(typeHandler = MoneyTypeHandler.class)
@ApiModelProperty(value = "价格,单位-元")
private Money price;
}
返回结果金额包括,金额分表示、金额元表示、货币币种(CNY代表人民币)、货币币种的元/分换算比率
注:
毕竟跟钱相关,以上代码并未经系统测试,所以慎用,有任何指正欢迎提出。