Joda-Money介绍
- Joda-Money提供了一个存储金额的类库。
- JDK提供标准货币类,但不是货币的标准表示。Joda-Money填补了这一空白,提供了代表金钱的价值类型。
- Joda-Money需要Java SE 8或更高版本,并且没有依赖项。
(ps: 对于金钱,通常最好的做法就是数据库设计成bigint类型,单位是分,入库扩大 100 倍 ,出库缩小 100 倍)
在springboot中使用Joda-Money
引入依赖
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>1.0.1</version>
</dependency>
创建MoneyTypeHandler
BaseTypeHandler类是MyBatis为我们提供来应对Java和jdbc字段类型不匹配的情况。也就是说你model声明的字段和数据库不匹配时需要在这个环节处理,在我们启用了我们自定义的这个TypeHandler之后,数据的读写都会被这个类所过滤。写入通过setNonNullParameter方法过滤,读通过getNullableResult方法过滤,parseMoney方法读作用是读取金额从分转成元。
/**
* @ClassName MoneyTypeHandler
* @Description 在 Money 与 long 之间转换的 TypeHandler, 处理 CNY 人民币
* @Author ninghq
* @Date 2020/10/26 1:47
* @Version 1.0.0
**/
public class MoneyTypeHandler extends BaseTypeHandler<Money> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Money parameter, JdbcType jdbcType) throws SQLException {
ps.setLong(i, parameter.getAmountMinorLong());
}
@Override
public Money getNullableResult(ResultSet rs, String columnName) throws SQLException {
return parseMoney(rs.getLong(columnName));
}
@Override
public Money getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return parseMoney(rs.getLong(columnIndex));
}
@Override
public Money getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return parseMoney(cs.getLong(columnIndex));
}
private Money parseMoney(long value) {
return Money.of(CurrencyUnit.of("CNY"), value / 100.00);
}
}
application.properties配置类
# 指定handler包位置
mybatis.type-handlers-package=com.example.demo.handler
# 开启实体里和数据库对于下划线的处理
mybatis.configuration.map-underscore-to-camel-case=true
关于MoneyTypeHandler说明
上面使用的MoneyTypeHandler作用是全局的,如果需要转换的字段是指定的某个字段,需要修改成以下的:
1、修改application.properties配置类,注释掉指定handler位置的配置
# 指定handler包位置
# mybatis.type-handlers-package=com.example.demo.handler
# 开启实体里和数据库对于下划线的处理
mybatis.configuration.map-underscore-to-camel-case=true
2、在mapper中,需要转换的字段,指定typeHandler属性
@Insert("insert into goods (name, create_time, update_time, price, price1)"
+ "values (#{name}, now(), now(), #{price, typeHandler=com.example.demo.handler.MoneyTypeHandler}, " +
" #{price1, typeHandler=com.example.demo.handler.MoneyTypeHandler})")
@Options(useGeneratedKeys = true)
int save(Goods goods);
@Select("select * from goods where id = #{id}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "price", property = "price", typeHandler = MoneyTypeHandler.class),
@Result(column = "price1", property = "price1", typeHandler = MoneyTypeHandler.class)
})
Goods findById(@Param("id") Long id);