添加 Maven 依赖
org.springframework.boot
spring-boot-starter-data-mongodb
${springboot.version}
去除自动化配置
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
MybatisAutoConfiguration.class,
MapperAutoConfiguration.class,
PageHelperAutoConfiguration.class,
RabbitAutoConfiguration.class,
MongoAutoConfiguration.class,
// SecurityAutoConfiguration.class
})
- 配置
MongoDbFactory
@Bean
public MongoDbFactory mongoDbFactory() throws UnknownHostException {
MongoClientURI mongoClientURI = new MongoClientURI(mongoDbProperties.getUri());
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
return mongoDbFactory;
}
- 配置模板方法
MongoTemplate
@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException {
// MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
return mongoTemplate;
}
-
spring-data-mongodb
的TypeConverter
将domain objects
映射为DBObject
时会自动给Document
添加一个_class
spring-data-mongodb
是为了在把Document
转换成Java
对象时能够转换到具体的子类
/**
* 调用 mongoTemplate 的save方法时
* spring-data-mongodb 的 TypeConverter 会自动给 Document 添加一个 _class
* spring-data-mongodb 是为了在把 Document 转换成 Java 对象时能够转换到具体的子类
* @return
* @throws UnknownHostException
*/
@Bean
public MappingMongoConverter mappingMongoConverter() throws UnknownHostException {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setApplicationContext(applicationContext);
MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
// CustomConversions conversions = new CustomConversions(null);
// mappingMongoConverter.setCustomConversions(conversions);
// 设置为 null,防止添加 _class
mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return mappingMongoConverter;
}
完整 MongoConfiguration
配置如下
@Configuration
@EnableMongoRepositories(basePackages = {MongoConfiguration.BASE_PACKAGES})
public class MongoConfiguration {
public static final String BASE_PACKAGES = "com.magic.platform.**.mongo.dao";
@Autowired
private MongoDbProperties mongoDbProperties;
@Autowired
private ApplicationContext applicationContext;
@Bean
public MongoDbFactory mongoDbFactory() throws UnknownHostException {
MongoClientURI mongoClientURI = new MongoClientURI(mongoDbProperties.getUri());
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
return mongoDbFactory;
}
/**
* 调用 mongoTemplate 的save方法时
* spring-data-mongodb 的 TypeConverter 会自动给 Document 添加一个 _class
* spring-data-mongodb 是为了在把 Document 转换成 Java 对象时能够转换到具体的子类
* @return
* @throws UnknownHostException
*/
@Bean
public MappingMongoConverter mappingMongoConverter() throws UnknownHostException {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setApplicationContext(applicationContext);
MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
// CustomConversions conversions = new CustomConversions(null);
// mappingMongoConverter.setCustomConversions(conversions);
mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return mappingMongoConverter;
}
@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException {
// MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
return mongoTemplate;
}
/**
* 设置 mongodb page helper 工具类
* @return
* @throws UnknownHostException
*/
@Bean
public MongoPageHelper mongoPageHelper() throws UnknownHostException {
return new MongoPageHelper(mongoTemplate());
}
}
MongoDbProperties
配置
@Data
@Configuration
@ConfigurationProperties(prefix = "mongo")
@PropertySource(value = "classpath:env/mongodb.properties", ignoreResourceNotFound = true, encoding = "UTF-8")
public class MongoDbProperties {
private String uri = "mongodb://localhost/test";
}
mongodb.properties
配置
mongodb.uri=mongodb://localhost/test
附录:MongoPageHelper
分页工具
@Component
public class MongoPageHelper {
public static final int FIRST_PAGE_NUM = 1;
public static final String ID = "_id";
private final MongoTemplate mongoTemplate;
@Autowired
public MongoPageHelper(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
/**
* 分页查询,直接返回集合类型的结果.
*/
public MongoPageResult pageQuery(Query query, Class entityClass, Integer pageNum, Integer pageSize) {
return pageQuery(query, entityClass, Function.identity(), pageNum, pageSize, null);
}
/**
* 分页查询,不考虑条件分页,直接使用skip-limit来分页
*/
public MongoPageResult pageQuery(Query query, Class entityClass, Function mapper, Integer pageNum, Integer pageSize) {
return pageQuery(query, entityClass, mapper, pageNum, pageSize, null);
}
/**
*
* @param query Mongo Query对象,构造你自己的查询条件
* @param entityClass Mongo collection 定义的 entity class,用来确定查询哪个集合
* @param mapper 映射器,你从db查出来的list的元素类型是entityClass, 如果你想要转换成另一个对象,比如去掉敏感字段等,可以使用mapper来决定如何转换
* @param pageSize 分页的大小
* @param pageNum 当前页
* @param lastId 条件分页参数, 区别于skip-limit,采用find(_id>lastId).limit分页.
* * 如果不跳页,像朋友圈,微博这样下拉刷新的分页需求,需要传递上一页的最后一条记录的ObjectId。 如果是null,则返回pageNum那一页
* @param collection定义的class类型
* @param 最终返回时,展现给页面时的一条记录的类型
* @return 一个封装page信息的对象
*/
public MongoPageResult pageQuery(Query query, Class entityClass, Function mapper, Integer pageNum, Integer pageSize, String lastId) {
//分页逻辑
long total = mongoTemplate.count(query, entityClass);
final Integer pages = (int) Math.ceil(total / (double) pageSize);
if (pageNum <= 0 || pageNum > pages) {
pageNum = FIRST_PAGE_NUM;
}
final Criteria criteria = new Criteria();
if (!StringUtils.isEmpty(lastId)) {
if (pageNum != FIRST_PAGE_NUM) {
criteria.and(ID).gt(new ObjectId(lastId));
}
query.limit(pageSize);
} else {
int skip = pageSize * (pageNum - 1);
query.skip(skip).limit(pageSize);
}
final List entityList = mongoTemplate.find(query.addCriteria(criteria).with(new Sort(Lists.newArrayList(new Order(Direction.ASC, ID)))), entityClass);
final MongoPageResult pageResult = new MongoPageResult<>();
pageResult.setTotal(total);
pageResult.setPages(pages);
pageResult.setPageSize(pageSize);
pageResult.setPageNum(pageNum);
pageResult.setList(entityList.stream().map(mapper).collect(Collectors.toList()));
return pageResult;
}
}