Spring Boot数据访问:使用MongoDB

一、介绍

Mongodb是一款性能优良,功能丰富,易于扩展的文档型非关系型数据库。

二、优势

  1. 易用性

MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库。
不采用关系型主要是为了获得更好得扩展性。当然还有一些其他好处,与关系数据库相比,面向文档的数据库不再有“行“(row)的概念取而代之的是更为灵活的“文档”(document)模型。
通过在文档中嵌入文档和数组,面向文档的方法能够仅使用一条记录来表现复杂的层级关系,这与现代的面向对象语言的开发者对数据的看法一致。
另外,不再有预定义模式(predefined schema):文档的键(key)和值(value)不再是固定的类型和大小。由于没有固定的模式,根据需要添加或删除字段变得更容易了。通常由于开发者能够进行快速迭代,所以开发进程得以加快。而且,实验更容易进行。开发者能尝试大量的数据模型,从中选一个最好的。

  1. 容器级特性的支持

应用程序数据集的大小正在以不可思议的速度增长。随着可用带宽的增长和存储器价格的下降,即使是一个小规模的应用程序,需要存储的数据量也可能大的惊人,甚至超出
了很多数据库的处理能力。过去非常罕见的T级数据,现在已经是司空见惯了。
由于需要存储的数据量不断增长,开发者面临一个问题:应该如何扩展数据库,分为纵向扩展和横向扩展,纵向扩展是最省力的做法,但缺点是大型机一般都非常贵,而且
当数据量达到机器的物理极限时,花再多的钱也买不到更强的机器了,此时选择横向扩展更为合适,但横向扩展带来的另外一个问题就是需要管理的机器太多。
MongoDB的设计采用横向扩展。面向文档的数据模型使它能很容易地在多台服务器之间进行数据分割。MongoDB能够自动处理跨集群的数据和负载,自动重新分配文档,以及将
用户的请求路由到正确的机器上。这样,开发者能够集中精力编写应用程序,而不需要考虑如何扩展的问题。如果一个集群需要更大的容量,只需要向集群添加新服务器,MongoDB就会自动将现有的数据向新服务器传送

  1. 丰富的功能

MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供了一系列不断扩展的独特功能。

  • 索引
    支持通用二级索引,允许多种快速查询,且提供唯一索引、复合索引、地理空间索引、全文索引
  • 聚合
    支持聚合管道,用户能通过简单的片段创建复杂的集合,并通过数据库自动优化
  • 特殊的集合类型
    支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话session。类似地,MongoDB也支持固定大小的集合,用于保存近期数据,如日志
  • 文件存储
    支持一种非常易用的协议,用于存储大文件和文件元数据。MongoDB并不具备一些在关系型数据库中很普遍的功能,如链接join和复杂的多行事务。省略
    这些的功能是处于架构上的考虑,或者说为了得到更好的扩展性,因为在分布式系统中这两个功能难以高效地实现
  1. 卓越的性能

MongoDB的一个主要目标是提供卓越的性能,这很大程度上决定了MongoDB的设计。MongoDB把尽可能多的内存用作缓存cache,视图为每次查询自动选择正确的索引。
总之各方面的设计都旨在保持它的高性能
虽然MongoDB非常强大并试图保留关系型数据库的很多特性,但它并不追求具备关系型数据库的所有功能。只要有可能,数据库服务器就会将处理逻辑交给客户端。这种精简方式的设计是MongoDB能够实现如此高性能的原因之一。

三、代码实战

1. POM添加相关依赖

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

2. 数据源配置,application.properties增加配置

spring.data.mongodb.uri=mongodb://localhost:27017/springboot-db
#有密码配置
#spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/dbname

3. 实体类

  • 文章Article
@Data //get/set/toString
@NoArgsConstructor //lombok无参数构造方法
@AllArgsConstructor //lombok全部参数构造方法
public class Article {

    @Id
    public String id;
    public String title;
    public String content;
    public Integer praiseCount;
    public Integer commentCount;
    public Integer visitCount;
    private Author author;
}
  • 作者Author
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Author {
    private String name;
    private String avatar;
}

4. 数据库操作类DAO

JpaRepository泛型,T为实体类, ID为类型
springboot jpa已经实现常用CRUD操作,也支持自定义属性查询, 只需要提供对应属性名一致的参数

public interface ArticleRepository extends MongoRepository<Article, String> {
    List<Article> findByTitle(String title);
    List<Article> findByContent(String content);
}

5. Junit测试类

@SpringBootTest
@Slf4j
class ArticleRepositoryTest {

    @Autowired
    ArticleRepository repository;

    @Test
    void save(){
        for (int i = 1; i <= 5; i++){
            Article article = new Article();
            article.setId("docker-" + i);
            article.setTitle("docker部署第" + i + "篇");
            article.setContent("部署nginx");
            article.setPraiseCount(0);
            article.setCommentCount(0);
            article.setVisitCount(0);
            Author author = new Author("张三疯", "http://xxx/avatar.png");
            article.setAuthor(author);
            repository.save(article);
        }
    }

    @Test
    void update(){
        Article article = new Article();
        article.setId("docker-1");
        article.setTitle("docker部署第1篇");
        article.setContent("部署apache");
        Author author = new Author("张三疯", "http://xxx/avatar.png");
        article.setAuthor(author);
        repository.save(article);
    }

    /**
     * 点赞
     */
    @Test
    void increPraise(){
        repository.findById("docker-1").ifPresent(article -> {
            article.setPraiseCount(article.getPraiseCount() + 1);
            article.setVisitCount(article.getVisitCount() + 1);
            repository.save(article);
            log.info("【标题】= {}, 【点赞数】= {},【访客数】= {}", article.getTitle(), article.getPraiseCount(), article.getVisitCount());

        });
    }

    @Test
    void findAll(){
        List<Article> list = repository.findAll();
        log.info("findAll - >  {} ", list );
    }

    @Test
    void findById(){
        Optional<Article> optional = repository.findById("docker-1");
        log.info("findById -> {}", optional.get());
    }

    @Test
    void findByTitle() {
        List<Article> list = repository.findByTitle("docker部署第1篇");
        log.info("findByTitle - >  {} ", list );
    }

    @Test
    void findByContent() {
        List<Article> list = repository.findByContent("部署nginx");
        log.info("findByContent - >  {} ", list );
    }
}

四、资料下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值