Spring訪問MongoDB

簡介

通過Spring我們可以很方便的使用非關係型數據庫-MongoDB,包括增、刪、查、改等操作。爲實現整個操作,我們首先在Windows環境上搭建MongoDB,具體安裝過程可參考Windows環境安裝MongoDB

host: localhost
port:27017

訪問MongoDB

通過Spring訪問搭建好的mongodb,以Repository爲例,主要有幾個步驟

  • 加載依賴
  • Document定義
  • Repository接口定義
  • MongoDbFactory和MongoTemplate定義
  • 啓用MongoDB

加載依賴

我們選擇springboot提供的mongo依賴,這個依賴比較全面,我們以gradle爲例,更新build.gradle文件。

dependencies {
    // 其他依賴
    ...
   
    // mongodb依賴
   	compile("org.springframework.boot:spring-boot-starter-data-mongodb:1.2.5.RELEASE")
}

Document定義

MongoDB屬於非關係型數據庫,每張數據表中存儲的記錄爲一個Document,對Document的數據類型並不進行強制限制。

Document定義是一條記錄中包含的字段信息,有以下幾點說明:

  • @Document註解,定義一個Document,可指定collection名字,即MongoDB中存儲的數據表的名稱,默認是class的名字。
  • @Id註解,標識Document的ID
  • @Field註解,自定義數據表存儲的字段名稱,默認是變量的名稱
  • @Indexed註解,索引標識,unique=true表示爲唯一索引
package com.notepad.springnote.nosql.mongo.domain;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

/**
 * Description: 實體定義
 * <p>
 * Create:      2018/12/2 14:45
 *
 * @author Marvin Yang
 */
@Document(collection = "entity")
public class Entity {

    @Id
    private String id;

    @Indexed(unique = true)
    @Field("name")
    private String name;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Repository接口定義

利用MongoRepository接口實現Document Repository接口的定義。我們這裏只是定義了一個接口,Repository機制會自動構建一個默認的實現類,當然MongoRepository中實現的都是一些基本的方法,如:

  • save(S entity) 存儲一條記錄, 可用於數據的插入和更新操作
  • save(Iterable<S> entities) 存儲多條記錄
  • insert(S entity) 存儲一條記錄,前提是記錄在數據表中不存在
  • findOne(ID id) 根據id查詢一條記錄
  • fiindAll() 查詢全部記錄
  • count() 統計個數
  • delete(ID id) 根據id刪除一條記錄
  • deleteAll() 刪除一張數據表的全部記錄

當然我們也可以自定義一些操作, 自定義方式可參考 Spring Data MongoDB - Reference Documentation, 這裏自定義一個根據name查詢的方法。

package com.notepad.springnote.nosql.mongo.repository;

import com.notepad.springnote.nosql.mongo.domain.Entity;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Description:
 * <p>
 * Create:      2018/12/2 14:46
 *
 * @author Marvin Yang
 */
@Repository
public interface EntityRepository extends MongoRepository<Entity, String> {
     /**
     * 根據name搜索entity
     *
     * @param name 實體名稱
     * @return 記錄
     */
    Entity findByName(String name);
}

MongoDbFactory和MongoTemplate定義

Document和Repository接口定義完成之後,我們定義MongoDbFactory關聯MongoDB,定義MongoTemplate可實現對於Mongo數據庫的操作。此處需說明,我們這裏顯示的定義是爲了去掉"_class"字段,如果無特殊需求可以不必顯示定義MongoDbFactory和MongoTemplate,Spring會幫我們用默認的實現。

我們使用Java配置實現。

package com.notepad.springnote.config;

import com.mongodb.MongoClientURI;
import com.notepad.springnote.aspects.StringAspect;
import com.notepad.springnote.inject.EncodeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import java.net.UnknownHostException;

/**
 * Description: Spring依賴注入Config(Java8)
 * <p>
 * Create:       2018/6/24 10:58
 *
 * @author Marvin Yang
 */

@Configuration
@ComponentScan(basePackages = "com.notepad.springnote")
public class InjectConfig {

    @Bean
    public MongoDbFactory mongoDbFactory() throws UnknownHostException {
        return new SimpleMongoDbFactory(new MongoClientURI(mongoDbUri));
    }

    /**
     * 定義mongo template
     *
     * @param mongoDbFactory a MongoDbFactory
     * @return a MongoOperations
     */
    @Bean
    public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory) {
        // 去掉_class字段:DefaultMongoTypeMapper的typeKey爲null
        MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory),
                new MongoMappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return new MongoTemplate(mongoDbFactory, converter);
    }

    @Value("${spring.data.mongodb.uri}")
    private String mongoDbUri;

}

applicatin.properties中mongoDB配置如下,monogDbUri的更多細節請參考 Connection String URI Format.

#mongo配置
spring.data.mongodb.uri=mongodb://localhost:27017/KnowledgeGraph?connectTimeoutMS=10000&socketTimeoutMS=10000

啓用MongoDB

上述的定義已滿足MongoDB操作的基本需要, 但是爲了使之生效需要啓動MongoDB,利用@EnableMongoRepositories 在Config類聲明掃描package。

@Configuration
@ComponentScan(basePackages = "com.notepad.springnote")
@EnableMongoRepositories(basePackages = "com.notepad.springnote")
public class InjectConfig {
    ...
}

單元測試

package com.notepad.springnote.nosql.mongo.repository;

import com.notepad.springnote.config.InjectConfig;
import com.notepad.springnote.nosql.mongo.domain.Entity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;

import java.util.List;

/**
 * Description: Entity實例化測試
 * <p>
 * Create:      2018/12/2 14:48
 *
 * @author Marvin Yang
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = InjectConfig.class)
public class EntityRepositoryTest {

    @Autowired
    private EntityRepository entityRepository;

    @Test
    public void init() throws Exception {
        Assert.notNull(entityRepository);
    }

    @Test
    public void save() throws Exception {
        String name = "thing";
        Entity entity = new Entity();
        entity.setName(name);
        if (entityRepository.findByName(name) == null) {
            entityRepository.save(entity);
        }
        System.out.println("insert a entity name of: " + name);
    }

    @Test
    public void count() throws Exception {
        Long count = entityRepository.count();
        System.out.println("entity count is : " + count);
    }

    @Test
    public void find() throws Exception {
        List<Entity> entities = entityRepository.findAll();
        for (Entity e : entities) {
            System.out.println(e.getName());
        }
    }
}

數據庫中查詢結果如下:

> use KnowledgeGraph
switched to db KnowledgeGraph
> db.entity.find()
{ "_id" : ObjectId("5c29cb229cac1749f0236063"), "name" : "thing" }

總結

本文主要介紹了通過Spring訪問mongoDB操作,實現的基本的數據插入,查詢,統計計數等功能。

MongoRepository的自定義操作包含很多細節,還需要更多的使用纔可以。另外,如果自定義操作無法滿足要求時,可直接通過monogTemplate實現操作, 如構造Query,Criteria 等,相關細節均可以在參考文獻4中找到。

參考文獻

[1] MongoDbUri格式 https://docs.mongodb.com/manual/reference/connection-string/

[2] springboot配置 https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

[3] springboot訪問monogdb示例 https://spring.io/guides/gs/accessing-data-mongodb/

[4] mongdb自定義操作 https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章