1.Decimal128的了解

由于mongodb4.3以上新加了Decimal128类型。Decimal128类型对小数给了最好的支持,而double类型对小数存在精度的问题。个人觉得Decimal128还是不错的。但是我测试发现spring-data-mongodb 1.*和现在的spring-data-mongodb2.0.5目前不支持Decimal128自动转换为java的BigDecimal类型。
异常: No converter found capable of converting from type [org.bson.types.Decimal128] to type [java.math.BigDecimal]
大概就是描述:没有Decimal128转换成BigDecimal的转换器。

2.访问mongodb方式:spring-data-mongodb的MongoTemplate。

目前先以spring-data-mongodb的MongoTemplate方式为案例。之后我会增加mongodb原始的dom处理方式,以及spring-boot-starter-data-mongodb下开启了对Repository的支持方式进行测试一下。(进行了测试)

代码:https://github.com/topsnowwolf/mongodbit

3.如何解决Decimal128,BigDecimal的类型转换问题呢?

思路:没有转换器我们新加一个转换。如何新加呢?增加之后如何配置呢?这就是重点了。

首先spring增加类型转换器有 三种方式。

1.实现GenericConverter接口

2.实现ConverterFactory接口

3.实现Converter接口

这三种方式分别如何实现类型转换器,我就不多说了。网上很多例子。

下面我就以实现Converter接口方式的来实现。

自定义类型转换器:

package com.wolf.mongodbit.converter;import org.bson.types.Decimal128;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;import java.math.BigDecimal;@ReadingConverter
@WritingConverter
public class BigDecimalToDecimal128Converter implements Converter<BigDecimal, Decimal128> {public Decimal128 convert(BigDecimal bigDecimal) {return new Decimal128(bigDecimal);}}
package com.wolf.mongodbit.converter;import org.bson.types.Decimal128;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;import java.math.BigDecimal;@ReadingConverter
@WritingConverter
public class Decimal128ToBigDecimalConverter implements Converter<Decimal128, BigDecimal> {public BigDecimal convert(Decimal128 decimal128) {return decimal128.bigDecimalValue();}}

下面我就分析一下MongoTemplate的源码。

我们先带着问题去看。我们增加了转换器,这个转换器是给访问mongodb用的,那肯定是给MongoTemplate设置新的转换器了。

打开MongoTemplate这个类,果然如此。MongoTemplate的构造方法中就有一个参数是设置类型转换器的。看到希望了。哈哈!

    public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) {this.writeConcernResolver = DefaultWriteConcernResolver.INSTANCE;this.writeResultChecking = WriteResultChecking.NONE;Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null!");this.mongoDbFactory = mongoDbFactory;this.exceptionTranslator = mongoDbFactory.getExceptionTranslator();this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter(mongoDbFactory) : mongoConverter;this.queryMapper = new QueryMapper(this.mongoConverter);this.updateMapper = new UpdateMapper(this.mongoConverter);this.mappingContext = this.mongoConverter.getMappingContext();if (null != this.mappingContext && this.mappingContext instanceof MongoMappingContext) {this.indexCreator = new MongoPersistentEntityIndexCreator((MongoMappingContext)this.mappingContext, mongoDbFactory);this.eventPublisher = new MongoMappingEventPublisher(this.indexCreator);if (this.mappingContext instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware)this.mappingContext).setApplicationEventPublisher(this.eventPublisher);}}}

最终发现MongoConverter是一个接口。那一定有实现它的类。查一下api发现,抽象的类AbstractMongoConverter,最后是MappingMongoConverter类。此时就会发现AbstractMongoConverter类中有setCustomConversions设置自定义类型转换器的set方法。现在兴奋了吧!!!

现在大概的思路就是通过创建一个MappingMongoConverter对象,将定义的类型转换器调用setCustomConversions方法进行注册。最后调用MongoTemplate的构造方法得到MongoTemplate对象。

废话不多说上代码:

自定义一个配置类:

package com.wolf.mongodbit.config;import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.wolf.mongodbit.converter.BigDecimalToDecimal128Converter;
import com.wolf.mongodbit.converter.Decimal128ToBigDecimalConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;import java.util.ArrayList;
import java.util.List;
@Configuration
public class MongodbConfig extends AbstractMongoConfiguration{private String dbName = "wolf";@Overridepublic MongoClient mongoClient() {MongoClient mongoClient = new MongoClient();return mongoClient;}@Overrideprotected String getDatabaseName() {return dbName;}@Beanpublic MappingMongoConverter mappingMongoConverter() throws Exception {DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(this.dbFactory());MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, this.mongoMappingContext());List<Object> list = new ArrayList<>();list.add(new BigDecimalToDecimal128Converter());//自定义的类型转换器list.add(new Decimal128ToBigDecimalConverter());//自定义的类型转换器converter.setCustomConversions(new MongoCustomConversions(list));return converter;}@Beanpublic MongoDbFactory dbFactory() throws Exception {return new SimpleMongoDbFactory(new MongoClientURI("mongodb://localhost:27017/wolf"));}@Beanpublic MongoMappingContext mongoMappingContext() {MongoMappingContext mappingContext = new MongoMappingContext();return mappingContext;}@Beanpublic MongoTemplate mongoTemplate() throws Exception {return new MongoTemplate(this.dbFactory(), this.mappingMongoConverter());}
}

实体类:

package com.wolf.mongodbit.entity.mongodb;import lombok.Data;@Data
public class Address {private String aCode;private String add;
}
package com.wolf.mongodbit.entity.mongodb;import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;@Document(collection="blacklist")
@Data
public class Blacklist {private ObjectId objectId;private String username;private String userid;private String blacktype;private String status;private Date update;private Date indate;private Address address;private Comments comments;
}
package com.wolf.mongodbit.entity.mongodb;import lombok.Data;import java.math.BigDecimal;
@Data
public class Comments {private String cause;private String desc;private BigDecimal money;
}

测试的controller:

package com.wolf.mongodbit.controller;import com.wolf.mongodbit.entity.mongodb.Blacklist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;@RestController
@RequestMapping("/mongodb")
public class BlackListController {private final static Logger logger = LoggerFactory.getLogger(BlackListController.class);@Autowiredprivate MongoTemplate mongoTemplate;@PostMapping("/check")private Blacklist checkBlack(Blacklist blackList){List<Blacklist> list = mongoTemplate.find(query(where("userid").is(blackList.getUserid())), Blacklist.class);logger.info("springboot+mongodb:size={}",list.size());if(list.size()>0)return list.get(0);return null;}
}

pom配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.wolf</groupId><artifactId>mongodbit</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>mongodbit</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--lombok自动生成实体类get/set方法 start--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--lombok自动生成实体类get/set方法 end--><!--mongodb引入 start --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-mongodb</artifactId></dependency><!--<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>--><!--mongodb引入 end --></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

yml配置文件:

#访问项目的url前缀
server:servlet:context-path: /mongodb

mongodb的测试数据:

var blacklist1 = {"username" : "snowwolf","userid" : "2018001014344","address" : {"aCode" : "0020","add" : "广州"},"certificate":{"certificateid":"20018554111134","certificatetype":"01","desc":"学生证"},"blacktype" : "01","comments":{"cause":"01","desc":"逾期欠费","money":NumberDecimal("18889.09")},"status":"01","update" : ISODate("2017-12-06T04:26:18.354Z"),"indate" : ISODate("2017-12-06T04:26:18.354Z")};
var blacklist2 = {"username" : "lison","userid" : "2018001014345","address" : {"aCode" : "0075","add" : "深圳"},"certificate":{"certificateid":"20018554111134","certificatetype":"02","desc":"护照"},"blacktype" : "01","comments":{"cause":"02","desc":"恶意欠费","money":NumberDecimal("188890.00")},"status":"01","update" : ISODate("2016-01-06T04:26:18.354Z"),"indate" : ISODate("2015-12-06T04:26:18.354Z")};
var blacklist3 = {"username":"tom","userid":"2018001014346","address":{"aCode" : "0020","add" : "广州"},"certificate":{"certificateid":"20018554111136","certificatetype":"01","desc":"学生证"},"blacktype":"01","comments":{"cause":"03","desc":"公安机关确定的涉嫌短信欺诈、诈骗等犯罪行为的用户"},"status":"01","update":ISODate("2017-12-06T04:26:18.354Z"),"indate":ISODate("2017-12-06T04:26:18.354Z")};db.blacklist.insert(blacklist1);
db.blacklist.insert(blacklist2);
db.blacklist.insert(blacklist3);

在postman中测试:

结果完美!

时间有限,有些地方可能不是很完美!不足之处请大牛指出,谢谢!

有需要代码的我之后将会发布到git上!

https://github.com/topsnowwolf/mongodbit

菜鸟入坑》springboot整合mongodb问题1-Decimal128和BigDecimal的转换相关推荐

  1. SpringBoot整合Mongodb(三) 使用MongoTemplate进行连表查询

    SpringBoot整合Mongodb(三) 使用MongoTemplate进行连表查询 由于在实际开发项目中,突然涉及到了需要Mongodb 进行连表操作的业务,所以我在私下进行了一波学习. 服务器 ...

  2. 直接裂开!京东二面被问SpringBoot整合MongoDB,我不会啊

    开始进入正题 一.技术介绍 SpringBoot整合MongoDB的实现步骤 一.技术介绍 1.MongoDB是什么? 二.使用步骤 1.MongoDB是什么? MongoDB(来自于英文单词&quo ...

  3. SpringBoot整合MongoDB 及 基本使用

    目录 1.MongoDB基本介绍 2.MongoDB的特点 3.MongoDB的体系结构 4.MongoDB的数据类型 5.SpringBoot整合MongoDB ** 1.导入依赖 2.启动Mong ...

  4. SpringBoot整合MongoDB数据库并实现基础CRUD

    MongoDB安装教程:MongoDB数据库安装以及将MongoDB设置为系统服务 MongoDB简介 MongoDB是一个基于分布式文件存储的数据库,由C++语言编写.旨为WEB应用提供可扩展的高性 ...

  5. 开发工具篇第九讲:菜鸟入坑指南

    摘要:本文是开发工具篇第九讲:菜鸟入坑指南.针对新人上手慢的问题,写了这篇入坑指南,方便自己回顾,总结.本文分为四个部分,分别为jenkins使用技巧:常用软件操作命令:开发手册:调试手册.主要材料来 ...

  6. 【ReactJs+springBoot项目——租房】第6章:MongoDB入门+SpringBoot整合MongoDB+搭建微聊系统+实现微聊功能

    MongoDB入门 MongoDB的java api的使用 SpringBoot整合MongoDB使用 搭建微聊系统 实现微聊功能 分布式WebSocket解决方案分析 1.MongoDB入门 1.1 ...

  7. Spring-Boot 整合MongoDB

    Spring-Boot 整合MongoDB 一.引入MongoDB依赖 <dependency><groupId>org.springframework.boot</gr ...

  8. springboot 整合 mongodb Criteria类 查询条件大全

    关于springboot整合mongodb,可查看博文 https://blog.csdn.net/qq_41712271/article/details/116062611 import cn.hu ...

  9. SpringBoot 整合mongoDB实现文章存储

    本项目展示了 SpringBoot 整合mongoDB进行文章存储,并实现简单增删改查,关于docker安装MongoDB:Docker 安装 MongoDB_Michael-DYZ的博客-CSDN博 ...

  10. SpringBoot第八篇:springboot整合mongodb

    这篇文章主要介绍springboot如何整合mongodb. 准备工作 安装 MongoDB jdk 1.8 maven 3.0 idea 环境依赖 在pom文件引入spring-boot-start ...

最新文章

  1. 学python需要英语基础吗-学python需要英语基础吗
  2. suse linux mysql下载_SUSE Linux安装MySQL
  3. Akka并发编程——第三节:Actor模型(二)
  4. 《Java程序设计》 第五周学习总结
  5. 前端和后端哪个工资高_前端、后端、全栈都是干嘛的?哪个薪资高?
  6. php中urlencode使用
  7. python使用print语句时显示特殊字符
  8. 说实话,写了这么多程序了,还从来没有用JUnit作为单元测试工具测试过,今天就来学习一下
  9. vsftp tomcat jdk
  10. [react-native]react-native填坑笔记
  11. 简历是这样选出来的!
  12. Caused by: java.lang.ClassNotFoundException: org.jaxen.JaxenException
  13. 模板匹配人眼---OpenCV-Python开发指南(33)
  14. 计算机在环境工程专业中的应用,计算机在环境科学与工程方向的应用.pdf
  15. NPR——卡通渲染(二)
  16. UI设计色彩模式选择
  17. (原创)直观了解通道混和器的校色作用
  18. 《推荐系统实践》- 项亮
  19. h3c怎么设置虚拟服务器,h3c虚拟服务器设置
  20. 台式计算机无法开机原因,台式电脑无法启动的原因和解决方法_电脑不能启动的原因与解决方法...

热门文章

  1. 魔百盒CM201-2_YS(易视腾代工)_MV300/300H芯片_蓝牙语音版_卡刷通刷_刷机固件
  2. php实现文件下载,提示压缩包损坏解决方法
  3. linux添加jetdirect协议,如何设置 HP JetDirect 设备的网络安全性?
  4. pixi 小游戏_使用 Pixi.js 开发微信小游戏
  5. Excel和WPS 下设置多种不同条件的条件格式
  6. Android 去掉Power键屏保功能,但保留长按关机功能。
  7. 转 研发团队绩效评定机制细则。
  8. 外贸独立站卖家如何借势营销?
  9. c语言 long double 输出格式,c++ 什么是`long double`的格式说明符
  10. vivado中实现VGA驱动学习笔记