Joda-Money提供了一个存储金额的类库
通常的做法就是数据库设计成bigint类型,单位是分,入库扩大 100 倍 ,出库缩小 100 倍
schema.sql
drop table goods if exists; create table goods ( id bigint auto_increment, name varchar(255), price bigint, create_time timestamp, update_time timestamp, primary key (id) ); insert into goods (name, price, create_time, update_time) values ('bag', 2000, now(), now()); insert into goods (name, price, create_time, update_time) values ('bottole', 2500, now(), now());
依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <dependency> <groupId>org.joda</groupId> <artifactId>joda-money</artifactId> <version>1.0.1</version> </dependency> <dependency> <groupId>org.jadira.usertype</groupId> <artifactId>usertype.core</artifactId> <version>6.0.1.GA</version> </dependency>
注:
配置了 joda-money和usertype.core
配置
server.port=8080 spring.application.name=abc spring.jpa.database=h2 spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=none spring.jpa.open-in-view=false spring.datasource.url=jdbc:h2:./data/test spring.datasource.username=sa spring.datasource.password=123456 spring.datasource.driverClassName=org.h2.Driver spring.h2.console.path=/h2-console spring.h2.console.enabled=true
持久化类
package com.example.demo.model; import lombok.*; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import org.joda.money.Money; import org.hibernate.annotations.Type; import javax.persistence.*; import java.util.Date; @Entity @Table(name = "goods") @Data @Builder @ToString(callSuper = true) @NoArgsConstructor @AllArgsConstructor public class Goods { @Id @GeneratedValue(strategy= GenerationType.AUTO) private Long id; private String name; @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyMinorAmount", parameters = {@org.hibernate.annotations.Parameter(name = "currencyCode", value = "CNY")}) private Money price; @Column(updatable = false) @CreationTimestamp private Date createTime; @UpdateTimestamp private Date updateTime; }
数据访问层接口
package com.example.demo.repository; import com.example.demo.model.Goods; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface GoodsRepository extends JpaRepository<Goods, Integer> { }
控制器类
package com.example.demo.controller; import com.example.demo.core.Result; import com.example.demo.repository.GoodsRepository; import com.example.demo.repository.UsersRepository; import com.example.demo.model.Goods; import com.example.demo.model.Users; import lombok.extern.slf4j.Slf4j; import org.joda.money.CurrencyUnit; import org.joda.money.Money; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @Slf4j @RestController public class DemoController { @Autowired GoodsRepository goodsRepository; @RequestMapping("/goods/add") public Result goodsAdd(String name,double price) { Goods good = Goods.builder().name(name).price(Money.of(CurrencyUnit.of("CNY"), price)).build(); log.info("Goods {}",good); goodsRepository.save(good); return Result.success(200, good); } @RequestMapping("/goods/find") public Result goodsFind() { List<Goods> goods = goodsRepository.findAll(); log.info("Goods {}",goods); return Result.success(200, goods); } }
启动项目
postman执行 http://127.0.0.1:8080/goods/add?name=aaa&price=11
结果
{ "code": 200, "message": null, "data": { "id": 34, "name": "aaa", "price": { "negative": false, "zero": false, "currencyUnit": { "code": "CNY", "numericCode": 156, "decimalPlaces": 2, "symbol": "¥", "numeric3Code": "156", "countryCodes": [ "CN" ], "pseudoCurrency": false }, "amount": 11.00, "amountMajor": 11, "amountMinor": 1100, "minorPart": 0, "positiveOrZero": true, "negativeOrZero": false, "positive": true, "scale": 2, "amountMajorLong": 11, "amountMajorInt": 11, "amountMinorLong": 1100, "amountMinorInt": 1100 }, "createTime": "2020-03-27T03:24:23.432+0000", "updateTime": "2020-03-27T03:24:23.432+0000" } }
H2数据的存储内容为