说明:
这个demo是学习极客时间丁雪丰老师的课程《玩转Spring全家桶》时记录下来的,使用SpringBoot 整合 mongodb,使用 maven 构建工具。
版本依赖:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
其中
- joda-money 一个专门处理金额的jar包,在金融领域运用的比较多
- lombok 可以简化 pojo 类的 get/set/builder 等方法,如果使用 idea/eclipse 需要安装插件才可以
接下来就是代码:
model 类:
@Data
@AllArgsConstructor // 构造方法
@NoArgsConstructor // 无参构造方法
@Builder // Builder 方法
@Document
public class Coffee implements Serializable {
private static final long serialVersionUID = 5199200306752426433L;
@Id
private String id;
private String name;
private Money price;
private Date createTime;
private Date updateTime;
}
其中 @Document 注解,标注 Coffee 对应 MongoDB 中的一个 document,@Id 标注每条记录的 id,这个id类型为String。如果是Long类型会报错。
Convert 类:负责 Money 的转换
public class MoneyReadConverter implements Converter<Document, Money> {
@Override
public Money convert(Document source) {
Document money = (Document) source.get("money");
double amount = Double.parseDouble(money.getString("amount"));
String currency = ((Document) money.get("currency")).getString("code");
return Money.of(CurrencyUnit.of(currency), amount);
}
}
启动类Application:
@SpringBootApplication
@Slf4j
public class Application implements ApplicationRunner {
@Autowired
private MongoTemplate mongoTemplate;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MongoCustomConversions mongoCustomConversions() {
return new MongoCustomConversions(Arrays.asList(new MoneyReadConverter()));
}
@Override
public void run(ApplicationArguments args) throws Exception {
Coffee espresso = Coffee.builder().name("espresso").price(Money.of(CurrencyUnit.of("CNY"), 20.0))
.createTime(new Date()).updateTime(new Date()).build();
Coffee saved = mongoTemplate.save(espresso);
log.info("Coffee {}", saved);
List<Coffee> list = mongoTemplate.find(Query.query(Criteria.where("name").is("espresso")), Coffee.class);
log.info("Find {} Coffee", list.size());
list.forEach(c -> log.info("Coffee {}", c));
Thread.sleep(1000); // 为了看更新时间
UpdateResult result = mongoTemplate.updateFirst(Query.query(Criteria.where("name").is("espresso")),
new Update().set("price", Money.ofMajor(CurrencyUnit.of("CNY"), 30)).currentDate("updateTime"),
Coffee.class);
log.info("Update Result: {}", result.getModifiedCount());
Coffee updateOne = mongoTemplate.findById(saved.getId(), Coffee.class);
log.info("Update Result: {}", updateOne);
mongoTemplate.remove(updateOne);
}
}
因为只是一个 demo,所以没有建立分层的结构,直接在 Application 中进行编码。
1. 通过实现 ApplicationRunner 类,通过重写 public void run(ApplicationArguments args) 方法,可以在项目启动后运行你的逻辑代码
2. 在 springboot 1.x 依赖中 mongoTemplate.save(espresso) 是没有返回值得,所以要使用 springboot-2.1.2,试用 2.0.0 发现也没有
3. Money 类在 MongoDB 中的存储格式
{
"_id" : ObjectId("5cf3f1c31b3c2cbe48412fc2"),
"name" : "espresso",
"price" : {
"money" : {
"currency" : {
"code" : "CNY",
"numericCode" : 156,
"decimalPlaces" : 2
},
"amount" : "30.00"
}
},
"createTime" : ISODate("2019-06-02T23:56:51.115+08:00"),
"updateTime" : ISODate("2019-06-03T07:43:04.150+08:00"),
"_class" : "com.okbeng.model.Coffee"
}
application.properties
spring.data.mongodb.uri=mongodb://olddog:olddog@localhost:27017/olddog