在按照 springboot整合mongodb 写好一个基础的 MongoTemplate 使用示例之后,我很好奇数据到底写到 MongoDB 的哪个“集合” 中?
比如,我们在我们项目中调用 findAll 方法来查询 MongoDB 中的数据:
public List<Student> findAll() {
return mongoTemplate.findAll(Student.class);
}
而跟踪一下 MongoTemplate#findAll
的源码:
MongoTemplate#getCollectionName
获取集合名称的源码:
成员变量 operations 是类型为 EntityOperations 的实例对象。EntityOperations#determineCollectionName
的源码:
这边有两个问题:
- getRequiredPersistentEntity 返回的对象是什么类型;
- 该类型的 getCollection 返回的值是怎么创建的?
上面这两个问题的答案都在 org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity
的构造函数中。
BasicMongoPersistentEntity
构造函数源代码如下:
public BasicMongoPersistentEntity(TypeInformation<T> typeInformation) {
super(typeInformation, MongoPersistentPropertyComparator.INSTANCE);
Class<?> rawType = typeInformation.getType();
String fallback = MongoCollectionUtils.getPreferredCollectionName(rawType); // 根据实体类类型生成“集合”名称
if (this.isAnnotationPresent(Document.class)) {
Document document = this.getRequiredAnnotation(Document.class);
this.collection = StringUtils.hasText(document.collection()) ? document.collection() : fallback;
this.language = StringUtils.hasText(document.language()) ? document.language() : "";
this.expression = detectExpression(document.collection());
this.collation = document.collation();
this.collationExpression = detectExpression(document.collation());
} else {
this.collection = fallback;
this.language = "";
this.expression = null;
this.collation = null;
this.collationExpression = null;
}
this.shardKey = detectShardKey();
}
@Document指定collection
根据上面的注解,如果实体类包含 @Document
注解,且指定了 collection
属性:
import lombok.Data;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Data
@Document(collection = "t_student")
public class Student{
private String id;
private String name;
private Integer age;
private Integer sex;
private Integer height;
private List<Hobby> hobbies;
}
比如上述代码这样写,那么集合名称取值为 t_student
。
默认collection命名规则——实体类名+首字母小写
如果没有特别指定,那么就会用 MongoCollectionUtils.getPreferredCollectionName(rawType)
返回的字符串:
首先 getSimpleName,那么原来实体类 org.coderead.entity.Student 将返回字符串 Student。
org.springframework.util.StringUtils#uncapitalize
作用就是首字母小写!