Spring Data MongoDB

欢迎光临我的博客[http://poetize.cn],前端使用Vue2,聊天室使用Vue3,后台使用Spring Boot

依赖

<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);
    }
}
posted @ 2019-08-23 09:31  LittleDonkey  阅读(827)  评论(0)    收藏  举报