文档章节

MongoDB —— 使用Spring Data MongoDB操作数据库

哼_哼
 哼_哼
发布于 01/10 09:41
字数 2188
阅读 6946
收藏 4

本文代码示例参见:https://gitee.com/imlichao/MongoDB-example

 

我们使用Spring Data MongoDB可以方便的在Spring boot项目中操作MongoDB

文档地址:https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-mongodb

加载包

在pom文件中加入spring-boot-starter-data-mongodb配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

 

配置参数

# user - 用户名、secret - 密码、mongo1.example.com - 数据库地址、27017- 端口号、teat - 库名 
spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:27017/test

 

实体映射

我们可以通过实体类来进行关系映射,从而能够方便的使用对象进行数据操作。

Spring Data MongoDB提供了一些方便的映射注释供我们使用,下面列出官方说明地址以供参考

官方说明文档:https://docs.spring.io/spring-data/mongodb/docs/2.1.3.RELEASE/reference/html/#mapping-usage

  • @Id:用于标记id字段,没有标记此字段的实体也会自动生成id字段,但是我们无法通过实体来获取id。id建议使用ObjectId类型来创建。

  • @Document:用于标记此实体类是mongodb集合映射类。可以使用collection参数指定集合名称。特别需要注意的是如果实体类没有为任何字段创建索引将不会自动创建集合。

  • @Indexed:用于标记为某一字段创建索引。direction参数可以指定排序方向,升或降序。

  • @CompoundIndex:用于创建复合索引。def参数可以定义复合索引的字段及排序方向。

  • @Transient:被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性。

  • @PersistenceConstructor:用于声明构造函数,作用是把从数据库取出的数据实例化为对象。

  • @Field:用于指定某一个字段映射到数据库中的名称。

  • @DBRef:用于指定与其他集合的级联关系,但是需要注意的是并不会自动创建级联集合。

 

一个简单的例子:

//注释此类将被映射到数据库的一个集合(collection为集合名称)
@Document(collection = "ex_entity_test")

//创建联合索引
@CompoundIndexes({
        //联合索引 name 索引名称 、def 索引字段、parameter1升序、parameter3降序
        @CompoundIndex(name = "compound_index", def = "{'parameter1': 1, 'parameter3': -1}")
})

public class EntityTest implements Serializable {
    //标记id字段
    @Id
    private ObjectId id;
    //创建单字段索引(默认ASCENDING 升序、DESCENDING 降序)
    @Indexed(direction = DESCENDING)
    private Long parameter1;
    //修改映射到数据库中的名称
    @Field("parameter2_")
    private String parameter2;

    private Date parameter3;

    private Integer parameter4;

    //关联其他集合(不添加此注释时List将会保存具体的实体值,而添加了此注释List保存的是关联集合的id)
    @DBRef
    private List<EntityTest1> parameter5;
    //此字段不映射到数据库
    @Transient
    private Integer parameter6;

    public EntityTest(){

    }
    //声明构造函数,用于实例化查询结果数据
    @PersistenceConstructor
    public EntityTest(Long parameter1, String parameter2, Date parameter3, Integer parameter4, List<EntityTest1> parameter5) {
        this.parameter1 = parameter1;
        this.parameter2 = parameter2;
        this.parameter3 = parameter3;
        this.parameter4 = parameter4;
        this.parameter5 = parameter5;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    ......

    public Integer getParameter6() {
        return parameter6;
    }

    public void setParameter6(Integer parameter6) {
        this.parameter6 = parameter6;
    }
}

上例关联的集合

//注释此类将被映射到数据库的一个集合(collection为集合名称)
@Document(collection = "ex_entity_test1")

public class EntityTest1 implements Serializable {
    //标记id字段
    @Id
    private ObjectId id;

    //如果实体类没有为任何字段创建索引将不会自动创建集合
    @Indexed
    private Long parameter1;

    public EntityTest1(){

    }

    public EntityTest1(Long parameter1) {
        this.parameter1 = parameter1;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public Long getParameter1() {
        return parameter1;
    }

    public void setParameter1(Long parameter1) {
        this.parameter1 = parameter1;
    }
}

 

数据操作

当完成一系列的配置与准备工作后,我们就可以使用MongoTemplate来操作数据库了。

MongoTemplate为我们提供了全面的增删改查等操作数据库的方法,详情可查看官方说明文档和API文档

官方说明文档:https://docs.spring.io/spring-data/mongodb/docs/2.1.3.RELEASE/reference/html/#mongo-template

API文档:https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/MongoTemplate.html

一个简单的例子:

@Controller
public class MongoController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @GetMapping(value = "/")
    public String index(){
        return "redirect:/find";
    }

    //新增文档
    @GetMapping(value = "/insert")
    public String insert(){
        //insert方法并不提供级联类的保存,所以级联类需要先自己先保存
        EntityTest1 entityTest1_1 = new EntityTest1(1000L);
        //执行完insert后对象entityTest1将会获得保存后的id
        mongoTemplate.insert(entityTest1_1);
        //再添加一条
        EntityTest1 entityTest1_2 = new EntityTest1(1001L);
        mongoTemplate.insert(entityTest1_2);
        //创建列表并将保存后的关联对象添加进去
        ArrayList<EntityTest1> entityTest1List = new ArrayList<EntityTest1>();
        entityTest1List.add(entityTest1_1);
        entityTest1List.add(entityTest1_2);

        //新增主体对象
        EntityTest entityTest = new EntityTest(100L,"test",new Date(),10,entityTest1List);
        //新增数据的主键已经存在,则会抛DuplicateKeyException异常
        mongoTemplate.insert(entityTest);
        return "redirect:/find";
    }

    //保存文档
    //保存与新增的主要区别在于,如果主键已经存在,新增抛出异常,保存修改数据
    @GetMapping(value = "/save")
    public String 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);
        return "redirect:/find";
    }

    //删除文档
    @GetMapping(value = "/delete")
    public String 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);

        return "redirect:/find";
    }

    //更新文档
    @GetMapping(value = "/update")
    public String update(){
        //将查询条件符合的全部文档更新
        Query query = new Query();
        Update update = Update.update("parameter2_","update");
        mongoTemplate.updateMulti(query,update,EntityTest.class);
        return "redirect:/find";
    }

    //查询文档
    @GetMapping(value = "/find")
    public String 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);
        model.addAttribute("findTestList",findTestList);

        //使用findOne查询如果结果极为多条,则返回排序在最上面的一条
        EntityTest findOneTest = mongoTemplate.findOne(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort) ,EntityTest.class);
        model.addAttribute("findOneTest",findOneTest);

        //模糊查询
        List<EntityTest> findTestList1 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date()).and("parameter2").regex("es")) ,EntityTest.class);
        model.addAttribute("findTestList1",findTestList1);

        //分页查询(每页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);
        model.addAttribute("page",page);

        //分页查询(通过起始行和数量也可以自己实现分页逻辑)
        List<EntityTest> findTestList3 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort).skip(3).limit(3) ,EntityTest.class);
        model.addAttribute("findTestList3",findTestList3);

        return "/index";
    }
}

 

查询

由于查询相对于其他增删改的操作要复杂一些,所以在这里单独说一下查询。还看上面的例子就可以。

首先我们先介绍一下几个和查询有关的类Query、Criteria、Sort、PageRequest、PageImpl

Query

查询对象定义一个查询的所有要素,其中包括筛选条件、排序、起始行、返回条数等内容

API文档:https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/query/Query.html

常用方法介绍:

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

查询条件类,使用此类定义查询时的查询条件相当于SQL的where。

API文档:https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/query/Criteria.html

常用方法介绍:

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) 创建或操作

 

Sort

查询排序类,使用此类可以创建查询排序。

API文档:https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Sort.html?is-external=true

常用方法介绍:

Sort(Sort.Direction direction, String... properties) 构造方法创建一个排序。direction为排序方向的枚举类型,properties为排序字段数组
and(Sort sort) 多个排序条件链接
ascending() 返回升序排列对象
descending() 返回降序排列对象

 

PageRequest和PageImpl

这两个类都是分页相关的封装类,与其他数据库的使用方法一样。PageRequest分页请求类,PageImpl为页面封装类。

API文档:https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/PageRequest.html

               https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/PageImpl.html

 

© 著作权归作者所有

哼_哼

哼_哼

粉丝 14
博文 68
码字总数 93484
作品 0
哈尔滨
私信 提问
使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南

1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库。本文介绍使用Spring Data MongoDB来访问mongodb数据库的几种方法: 使用Query和Criteria类 ...

xiaomin0322
2018/06/28
386
0
基于云数据库MongoDB版进行应用开发

MongoDB是一个基于分布式文件存储的数据库,在互联网、物联网、游戏、金融等领域被广泛采用。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是当前最流行的Nosql...

mcy0425
2018/09/14
33
0
MongoDB系列三(Spring集成方案).

一、前言 MongoDB是最为流行的开源文档数据库之一。Spring Data MongoDB提供了三种方式在Spring应用中使用MongoDB: 通过注解实现对象-文档映射; 使用MongoTemplate实现基于模板的数据库访问...

jmcui
2018/03/31
0
0
使用MongoDB和Spring Data创建一个简单的Java 的CRUD应用

MongoDB 是一个可扩展的、高性能的、开源的NoSQL数据库,跟传统的数据库不一样,MongoDB并不是将数据存储在表中,他将数据结构化为一个类似于JSON的文档中。这篇文章就是展示如何使用Java基于...

王振威
2012/07/21
8.5K
8
mongodb无法远程访问

问题如下: 我使用robomongo也无法登陆远程mongdb,使用spring data -mongo也是一样,具体配置如下 mongo.conf ////////////////////////////////////////// dbpath=/data/mongodb/db logpat......

小陌哥
2015/07/20
1K
5

没有更多内容

加载失败,请刷新页面

加载更多

高速PCB设计软件allegro中与网络有关的约束规则设置

在allegro pcb的设计过程中,设计约束规则包括时序规则、间距规则、信号完整性规则以及物理规则等,本期主要详细讲解与物理、间距与电气约束中的线宽、线间距物理规则的设置。 一、线宽设置 ...

demyar
10分钟前
1
0
Linux 启动停止SpringBoot jar 程序部署Shell 脚本

#!/bin/bash #这里可替换为你自己的执行程序,其他代码无需更改 APP_NAME=algorithm.jar #使用说明,用来提示输入参数 usage() { echo "Usage: sh 执行脚本.sh [start|stop|restart|status]...

草庐过客
12分钟前
2
0
mysql-connector-java驱动升级到8.0后数据库保存时间出现时差

1.问题:在一个新项目中用到了新版的mysql jdbc 驱动后,发现保存到数据库的时间出现了时差 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId>......

ValSong
13分钟前
2
0
好程序员大数据教程Scala系列之隐式转换和隐式参数

5.1. 概念 隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,你可以提供优雅的类库,对类库的使用者隐匿掉那些枯燥乏味的细节。 5.2. 作用 隐式的对类的方法进行增强...

好程序员官网
17分钟前
1
0
多线程必备

初次接触线程,可能有很多初学者搞不明白,始终云里雾里,那么本篇文章直接带大家介绍多线程必须知道的几个点 接下来没有多余,直接上干货 1. 进程和线程的区别是什么? 进程是执行着的应用程序,...

理性思考
20分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部