依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
注解
注解 |
描述 |
示例 |
---|
@Document |
对应于MongoDB中的Collection(默认类名小写) |
@Document(collection="user") |
@Id |
主键,默认生成的名称是“_id”。在MongoDB中数据的主键通常为自动生成的复杂字符串,不需要我们手动设置 |
|
@Field |
对应于collection中自定义的字段,不手动添加该注解时MongoDB中的数据字段跟Entity的属性名一致 |
@Field("name") |
@DBRef |
引用其他的文档,这个文档有可能位于其他数据库中(级联关系) |
|
@Transient |
该字段不保存到 mongodb |
|
@Indexed |
声明该字段需要索引,建索引可以大大的提高查询效率。direction参数可以指定排序方向,升或降序。 |
@Indexed(direction = DESCENDING) |
@PersistenceConstructor |
用于声明构造函数,作用是把从数据库取出的数据实例化为对象。 |
|
//声明构造函数,用于实例化查询结果数据
@PersistenceConstructor
public Entity(Long parameter1, String parameter2) {
this.parameter1 = parameter1;
this.parameter2 = parameter2;
}
复合索引,指的是将多个键组合到一起创建索引,这样可以加速匹配多个键的查询。
复合索引可以支持要求匹配多个键的查询
复合索引每一个键的顺序非常重要,这将决定该索引在查询过程中能否被使用到
复合索引查询时先按 userid 升序 再按 score 降序{'userid:1','score':-1}。
索引键列的排序方法影响查询在排序时候的操作,方向一致或相反的才能被匹配
{ "item": 1, "location": 1, "stock": 1 } //索引
在MongoDB中,下列查询过滤条件情形中,索引将会被使用到
item字段
item字段 + location字段(尽管索引被使用,但不高效)
item字段 + location字段 + stock字段
创建联合索引(用于类,以声明复合索引)
@CompoundIndexes({
//联合索引 name 索引名称 、def 索引字段、parameter1升序、parameter2降序
@CompoundIndex(name = "compound_index", def = "{'parameter1': 1, 'parameter2': -1}")
})
执行语句db.Example.find({"userId":"1"}).explain();
@DBRef关联其他集合(不添加此注释时List将会保存具体的实体值,而添加了此注释List保存的是关联集合的id和表名)
只保存了Entity的id和表名,同时仍然没有创建Entity的collection(等同于mysql的表)。
不会处理级联保存,你必须单独处理关联的对象
先储存关联对象,再储存主体对象,查询主体对象可以将关联对象一并查出。
@DBRef
private List<Entity> parameter;
Query常用方法介绍
query(CriteriaDefinition criteriaDefinition)
静态方法,通过注入一个CriteriaDefinition条件对象获得Query查询对象。在简单查询时使用此方法将非常的方便。
例如:mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())
addCriteria(CriteriaDefinition criteriaDefinition)
添加一个CriteriaDefinition查询条件类到本次查询
skip(long skip)
跳过文档的数量,可以与limit配合使用实现分页效果。
limit(int limit)
查询返回的文档数量。
with(Sort sort)
添加一个Sort排序对象
with(Pageable pageable)
添加一个Pageable分页对象。Pageable可以注入一个Sort,所以分页和排序可以一起添加。
例如:Pageable pageable = new PageRequest(1,3,sort);
Criteria 查询条件类
where(String key)
静态方法,用它可以很方便的定义查询条件
例如:mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date()).and("parameter2").regex("es"))
语法 |
描述 |
---|
and(String key) |
与操作 |
gt(Object o) |
大于 |
gte(Object o) |
大于等于 |
in(Object... o) |
包含 |
is(Object o) |
等于 |
lt(Object o) |
小于 |
lte(Object o) |
小于等于 |
not() |
非 |
regex(String re) |
正则表达式 |
andOperator(Criteria... criteria) |
创建与操作 |
orOperator(Criteria... criteria) |
创建或操作 |
基本使用
public class MongoController {
@Autowired
private MongoTemplate mongoTemplate;
//新增文档
public void insert() {
//insert方法并不提供级联类的保存,所以级联类需要先自己先保存
EntityTest1 entityTest1_1 = new EntityTest1(1000L);
//执行完insert后对象entityTest1将会获得保存后的id
mongoTemplate.insert(entityTest1_1);
//创建列表并将保存后的关联对象添加进去
ArrayList<EntityTest1> entityTest1List = new ArrayList<EntityTest1>();
entityTest1List.add(entityTest1_1);
//新增主体对象
EntityTest entityTest = new EntityTest(100L, "test", new Date(), 10, entityTest1List);
//新增数据的主键已经存在,则会抛DuplicateKeyException异常
mongoTemplate.insert(entityTest);
}
//保存文档
//保存与新增的主要区别在于,如果主键已经存在,新增抛出异常,保存修改数据
public void save() {
//查询最后一条数据并更新
Sort sort = new Sort(Sort.Direction.DESC, "parameter3");
EntityTest entityTest = mongoTemplate.findOne(Query.query(Criteria.where("")).with(sort), EntityTest.class);
entityTest.setParameter4(3000);
//保存数据的主键已经存在,则会对已经存在的数据修改
mongoTemplate.save(entityTest);
}
//删除文档
public void delete() {
//查询第一条数据并删除
EntityTest entityTest = mongoTemplate.findOne(Query.query(Criteria.where("")), EntityTest.class);
//remove方法不支持级联删除所以要单独删除子数据
List<EntityTest1> entityTest1List = entityTest.getParameter5();
for (EntityTest1 entityTest1 : entityTest1List) {
mongoTemplate.remove(entityTest1);
}
//删除主数据
mongoTemplate.remove(entityTest);
}
//更新文档
public void update() {
//将查询条件符合的全部文档更新
Query query = new Query();
Update update = Update.update("parameter2", "update");
mongoTemplate.updateMulti(query, update, EntityTest.class);
}
//查询文档
public void find(Model model) {
//查询小于当前时间的数据,并按时间倒序排列
Sort sort = new Sort(Sort.Direction.DESC, "parameter3");
List<EntityTest> findTestList = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort), EntityTest.class);
//使用findOne查询如果结果极为多条,则返回排序在最上面的一条
EntityTest findOneTest = mongoTemplate.findOne(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort), EntityTest.class);
//模糊查询
List<EntityTest> findTestList1 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date()).and("parameter2").regex("es")), EntityTest.class);
//分页查询(每页3行第2页)
Pageable pageable = new PageRequest(1, 3, sort);
List<EntityTest> findTestList2 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(pageable), EntityTest.class);
//共多少条
Long count = mongoTemplate.count(Query.query(Criteria.where("parameter3").lt(new Date())), EntityTest.class);
//返回分页对象
Page<EntityTest> page = new PageImpl<EntityTest>(findTestList2, pageable, count);
//分页查询(通过起始行和数量也可以自己实现分页逻辑)
List<EntityTest> findTestList3 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort).skip(3).limit(3), EntityTest.class);
}
}