SpringBoot 整合 MongoDB 實戰解說

2022-08-31 18:01:39

一、介紹

在前面的文章中,我們詳細的介紹了 MongoDB 的設定和使用,如果你對 MongoDB 還不是很瞭解,也沒關係,在 MongoDB 中有三個比較重要的名詞:資料庫、集合、檔案

  • 資料庫(Database):和關係型資料庫一樣,每個資料庫中有自己的使用者許可權,不同的專案組可以使用不同的資料庫
  • 集合(Collection): 集合指的是檔案組(類似於 Mysql 中的表的概念),裡面可以儲存許多檔案
  • 檔案(Document): 檔案是 MongoDB 中最基本的資料單元,由鍵值對組成,類似於 JSON 格式,可以儲存不同欄位,欄位的值可以包括其他檔案、陣列和檔案陣列

搞懂這三個名詞,基本就可以上手了,今天我們以 Java 語言為例,詳細的介紹 Java 使用者端改如何操作 MongoDB !

話不多說,直接開擼!

二、Java 使用者端

2.1、MongoDB 連線

Java 連線 MongoDB 伺服器,與我們常用的連線關係型資料庫方式類似!

標準 URI 連線語法:

mongodb://username:password@host1:port1,host2:port2,...,hostN:portN/database?options

引數說明:

  • mongodb://:這是固定的格式,必須要指定
  • username:password@:可選項,如果設定,在連線資料庫伺服器之後,驅動都會嘗試登入這個資料庫
  • host1:port1:主機IP和埠號,必須指定至少一個host。如果要連線複製集,請指定多個主機地址
  • /database:如果指定了username:password@,連線時會驗證並登入指定資料庫。若不指定,預設開啟 test 資料庫
  • ?options:連線可選項,例如connectTimeoutMS=5000ms,表示連線等待時間最長 5 秒

例如,無密碼連線 MongoDB

mongodb://127.0.0.1:27017

使用使用者名稱test,密碼test登入 MongoDB 的test_db資料庫

mongodb://test:[email protected]:27017/test_db

無密碼連線指定三臺伺服器 (埠 27017, 27018, 和27019)

mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019

2.2、新增依賴包

和關係型資料庫操作一樣,在 Java 程式中如果要使用 MongoDB,先要新增對應的 MongoDB JDBC 驅動器,然後才能繼續操作!

在選擇的版本號的時候,注意需要和伺服器中的安裝版本匹配,具體的版本號選擇可以從如下地址中獲取到最新的版本:mongo-java-driver

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.12.7</version>
</dependency>

2.3、連線資料庫

連線資料庫的 Java 程式碼如下:

private static MongoClient mongoClient;

static {
    try {
        //連線到MongoDB服務 如果是遠端連線可以替換「localhost」為伺服器所在IP地址
        mongoClient = MongoClients.create("mongodb://test:[email protected]:27017/test_db");
        System.out.println("Connect to database successfully");
    } catch (Exception e) {
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
    }
}

上文中採用的是使用者名稱和密碼方式登入資料庫,因為資料庫已經開啟了許可權驗證,因此需要通過使用者名稱和密碼才能登入。

2.4、建立集合

com.mongodb.client包裡面都幫我們整合好了大部分常用的 api,我們可以通過MongoDatabase類中的createCollection()方法來建立集合。

建立一個tb_role集合,程式碼片段如下:

/**
 * 建立集合
 * @param args
 */
public static void main(String[] args) {
    // 連線到資料庫
    MongoDatabase mongoDatabase = mongoClient.getDatabase("test_db");
    System.out.println("Connect to database successfully");
    mongoDatabase.createCollection("tb_role");
    System.out.println("集合建立成功");
}

如果想刪除集合,操作也很簡單!

/**
 * 刪除集合
 * @param args
 */
public static void main(String[] args) {
    // 連線到資料庫
    MongoDatabase mongoDatabase = mongoClient.getDatabase("test_db");
    System.out.println("Connect to database successfully");
    mongoDatabase.getCollection("tb_role").drop();
    System.out.println("集合 tb_role 刪除成功");
}

2.5、建立檔案

我們可以通過MongoCollection類中的insertMany()方法來插入一個檔案。

tb_role集合中插入檔案,程式碼片段如下:

/**
 * 插入檔案
 * @param args
 */
public static void main(String[] args) {
    // 連線到資料庫
    MongoDatabase mongoDatabase = mongoClient.getDatabase("test_db");
    System.out.println("Connect to database successfully");
    //獲取集合
    MongoCollection<Document> collection = mongoDatabase.getCollection("tb_role");

    //向集合中插入檔案
    Document document = new Document("name", "管理員").
            append("code", "manager").
            append("sort", 100);
    List<Document> documents = new ArrayList<>();
    documents.add(document);
    collection.insertMany(documents);
    System.out.println("檔案插入成功");
}

2.6、更新檔案

我們可以通過MongoCollection類中的updateMany()方法來更新集合中的檔案。

更新tb_role集合中的指定檔案資訊,程式碼片段如下:

/**
 * 更新檔案
 * @param args
 */
public static void main(String[] args) {
    // 連線到資料庫
    MongoDatabase mongoDatabase = mongoClient.getDatabase("test_db");
    System.out.println("Connect to database successfully");
    //獲取集合
    MongoCollection<Document> collection = mongoDatabase.getCollection("tb_role");

    //更新檔案
    collection.updateMany(Filters.eq("code", "manager"), new Document("$set",new Document("name","經理")));

    //遍歷所有檔案
    FindIterable<Document> findIterable = collection.find();
    MongoCursor<Document> mongoCursor = findIterable.iterator();
    while(mongoCursor.hasNext()){
        System.out.println(mongoCursor.next());
    }
}

上文操作類似於 SQL語句中的update tb_role set name = '經理' where code = 'manager'

2.7、刪除檔案

我們可以通過MongoCollection類中的deleteOne()或者deleteMany方法來刪除集合中的檔案。

刪除tb_role集合中的指定檔案資訊,程式碼片段如下:

/**
 * 刪除檔案
 * @param args
 */
public static void main(String[] args) {
    // 連線到資料庫
    MongoDatabase mongoDatabase = mongoClient.getDatabase("test_db");
    System.out.println("Connect to database successfully");
    //獲取集合
    MongoCollection<Document> collection = mongoDatabase.getCollection("tb_role");

    //刪除符合條件的第一個檔案
    collection.deleteOne(Filters.eq("code", "manager"));
    //刪除所有符合條件的檔案
    collection.deleteMany (Filters.eq("code", "manager"));

    //遍歷所有檔案
    FindIterable<Document> findIterable = collection.find();
    MongoCursor<Document> mongoCursor = findIterable.iterator();
    while(mongoCursor.hasNext()){
        System.out.println(mongoCursor.next());
    }
}

在這裡需要注意一下,在刪除的時候,官方推薦儘可能先查詢一下這個資料是否存在,如果存在,然後在執行刪除操作,可以呼叫findOneAndDelete()方法進行刪除!

2.8、查詢檔案

MongoCollection類中提供了非常豐富的檢索檔案的方法,例如,我們可以通過find()方法來獲取集合中的所有檔案。

檢索tb_role集合中的檔案資訊,程式碼片段如下:

/**
 * 查詢檔案
 * @param args
 */
public static void main(String[] args) {
    // 連線到資料庫
    MongoDatabase mongoDatabase = mongoClient.getDatabase("test_db");
    System.out.println("Connect to database successfully");
    //獲取集合
    MongoCollection<Document> collection = mongoDatabase.getCollection("tb_role");

    //遍歷所有檔案
    FindIterable<Document> findIterable = collection.find();
    MongoCursor<Document> mongoCursor = findIterable.iterator();
    while(mongoCursor.hasNext()){
        System.out.println(mongoCursor.next());
    }

    //查詢當前集合所有檔案數量
    long count = collection.countDocuments();
    System.out.println("當前檔案數量:" + count);

    //帶條件遍歷檔案
    FindIterable<Document> documentFindIterable = collection.find(Filters.eq("code", "manager"));
    MongoCursor<Document> documentMongoCursor = documentFindIterable.iterator();
    while(documentMongoCursor.hasNext()){
        System.out.println(documentMongoCursor.next());
    }
}

三、SpringBoot 整合 MongoDB

採用 SpringBoot 來對接 MongoDB,可以說極其簡單,下面就以常用的幾個操作為例來介紹,過程如下!

3.1、建立 SpringBoot 工程,新增 MongoDB 依賴包

<!-- 引入springboot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.RELEASE</version>
</parent>

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

3.2、新增組態檔

application.properties檔案中新增mongodb設定

#設定資料庫連線地址
spring.data.mongodb.uri=mongodb://test123:[email protected]:27017/test_db

3.3、建立實體類

建立用於範例中測試的實體類Person

其中註解@Document(collection="persons")用於指定當前檔案屬於集合persons

註解@Id表示當前id欄位屬於主鍵型別。

/**
 * 使用@Document註解指定集合名稱
 */
@Document(collection="persons")
public class Person implements Serializable {
    private static final long serialVersionUID = -3258839839160856613L;

    /**
     * 使用@Id註解指定MongoDB中的 _id 主鍵
     */
    @Id
    private Long id;

    private String userName;

    private String passWord;

    private Integer age;

    private Date createTime;

    //...get/set

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", passWord='" + passWord + '\'' +
                ", age=" + age +
                ", createTime=" + createTime +
                '}';
    }
}

3.4、操作 MongoDB

Springboot 操作 MongoDB 有兩種方式。

  • 第一種方式是採用 Springboot 官方推薦的 JPA 方式,這種操作方式,使用簡單但是靈活性比較差。

  • 第二種方式是採用 Spring Data MongoDB 封裝的 MongoDB 官方 Java 驅動 MongoTemplate 對 MongoDB 進行操作,這種方式非常靈活,能滿足絕大部分需求。

本文將採用第二種方式進行介紹!

3.5、插入檔案

MongoTemplate提供了insert()方法,用於插入檔案,範例程式碼如下:

  • 用於插入檔案

沒指定集合名稱時,會取@Document註解中的集合名稱

@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 插入檔案
     * @throws Exception
     */
    @Test
    public void insert() throws Exception {
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());
        mongoTemplate.insert(person);
    }
}
  • 自定義集合名稱,插入檔案
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 自定義集合,插入檔案
     * @throws Exception
     */
    @Test
    public void insertCustomCollection() throws Exception {
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());
        mongoTemplate.insert(person, "custom_person");
    }
}
  • 自定義集合,批次插入檔案

如果採用批次插入檔案,必須指定集合名稱

@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 自定義集合,批次插入檔案
     * @throws Exception
     */
    @Test
    public void insertBatch() throws Exception {
        List<Person> personList = new ArrayList<>();
        Person person1 =new Person();
        person1.setId(10l);
        person1.setUserName("張三");
        person1.setPassWord("123456");
        person1.setCreateTime(new Date());
        personList.add(person1);

        Person person2 =new Person();
        person2.setId(11l);
        person2.setUserName("李四");
        person2.setPassWord("123456");
        person2.setCreateTime(new Date());
        personList.add(person2);

        mongoTemplate.insert(personList, "custom_person");
    }
}

3.6、儲存檔案

MongoTemplate提供了save()方法,用於儲存檔案。

在儲存檔案的時候會通過主鍵ID進行判斷,如果存在就更新,否則就插入,範例程式碼如下:

  • 儲存檔案,如果沒有插入,否則通過主鍵ID更新
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 儲存檔案,如果沒有插入,否則更新
     * @throws Exception
     */
    @Test
    public void save() throws Exception {
        Person person =new Person();
        person.setId(13l);
        person.setUserName("八八");
        person.setPassWord("123456");
        person.setAge(40);
        person.setCreateTime(new Date());
        mongoTemplate.save(person);
    }
}
  • 自定義集合,儲存檔案
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 自定義集合,儲存檔案
     * @throws Exception
     */
    @Test
    public void saveCustomCollection() throws Exception {
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());
        mongoTemplate.save(person, "custom_person");
    }
}

3.7、更新檔案

MongoTemplate提供了updateFirst()updateMulti()方法,用於更新檔案,範例程式碼如下:

  • 更新檔案,匹配查詢到的檔案資料中的第一條資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 更新檔案,匹配查詢到的檔案資料中的第一條資料
     * @throws Exception
     */
    @Test
    public void updateFirst() throws Exception {
        //更新物件
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三123");
        person.setPassWord("123456");
        person.setCreateTime(new Date());

        //更新條件
        Query query= new Query(Criteria.where("id").is(person.getId()));

        //更新值
        Update update= new Update().set("userName", person.getUserName()).set("passWord", person.getPassWord());
        //更新查詢滿足條件的檔案資料(第一條)
        UpdateResult result =mongoTemplate.updateFirst(query,update, Person.class);
        if(result!=null){
            System.out.println("更新條數:" + result.getMatchedCount());
        }
    }
}
  • 更新檔案,匹配查詢到的檔案資料中的所有資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 更新檔案,匹配查詢到的檔案資料中的所有資料
     * @throws Exception
     */
    @Test
    public void updateMany() throws Exception {
        //更新物件
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());

        //更新條件
        Query query= new Query(Criteria.where("id").is(person.getId()));

        //更新值
        Update update= new Update().set("userName", person.getUserName()).set("passWord", person.getPassWord());
        //更新查詢滿足條件的檔案資料(全部)
        UpdateResult result = mongoTemplate.updateMulti(query, update, Person.class);
        if(result!=null){
            System.out.println("更新條數:" + result.getMatchedCount());
        }
    }
}

3.8、刪除檔案

MongoTemplate提供了remove()findAndRemove()findAllAndRemove()方法,用於刪除檔案,範例程式碼如下:

  • 刪除符合條件的所有檔案
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 刪除符合條件的所有檔案
     * @throws Exception
     */
    @Test
    public void remove() throws Exception {
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());

        Query query = new Query(Criteria.where("userName").is(person.getUserName()));
        DeleteResult result = mongoTemplate.remove(query, Person.class);
        System.out.println("刪除條數:" + result.getDeletedCount());
    }
}
  • 刪除符合條件的單個檔案,並返回刪除的檔案
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 刪除符合條件的單個檔案,並返回刪除的檔案
     * @throws Exception
     */
    @Test
    public void findAndRemove() throws Exception {
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());

        Query query = new Query(Criteria.where("id").is(person.getId()));
        Person result = mongoTemplate.findAndRemove(query, Person.class);
        System.out.println("刪除的檔案資料:" + result.toString());
    }
}
  • 刪除符合條件的所有檔案,並返回刪除的檔案
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 刪除符合條件的所有檔案,並返回刪除的檔案
     * @throws Exception
     */
    @Test
    public void findAllAndRemove() throws Exception {
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());

        Query query = new Query(Criteria.where("id").is(person.getId()));
        List<Person> result = mongoTemplate.findAllAndRemove(query, Person.class);
        System.out.println("刪除的檔案資料:" + result.toString());
    }
}

3.9、查詢檔案

MongoTemplate提供了非常多的檔案查詢方法,日常開發中用的最多的就是find()方法,範例程式碼如下:

  • 查詢集合中的全部檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 查詢集合中的全部檔案資料
     * @throws Exception
     */
    @Test
    public void findAll() throws Exception {
        List<Person> result = mongoTemplate.findAll(Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 查詢集合中指定的ID檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 查詢集合中指定的ID檔案資料
     * @throws Exception
     */
    @Test
    public void findById() {
        long id = 1l;
        Person result = mongoTemplate.findById(id, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據條件查詢集合中符合條件的檔案,返回第一條資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據條件查詢集合中符合條件的檔案,返回第一條資料
     */
    @Test
    public void findOne() {
        String userName = "張三";
        Query query = new Query(Criteria.where("userName").is(userName));
        Person result = mongoTemplate.findOne(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據條件查詢集合中符合條件的檔案
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據條件查詢集合中符合條件的檔案
     */
    @Test
    public void findByCondition() {
        String userName = "張三";
        Query query = new Query(Criteria.where("userName").is(userName));
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據【AND】關聯多個查詢條件,查詢集合中的檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據【AND】關聯多個查詢條件,查詢集合中的檔案資料
     */
    @Test
    public void findByAndCondition() {
        // 建立條件
        Criteria criteriaUserName = Criteria.where("userName").is("張三");
        Criteria criteriaPassWord = Criteria.where("passWord").is("123456");
        // 建立條件物件,將上面條件進行 AND 關聯
        Criteria criteria = new Criteria().andOperator(criteriaUserName, criteriaPassWord);
        // 建立查詢物件,然後將條件物件新增到其中
        Query query = new Query(criteria);
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據【OR】關聯多個查詢條件,查詢集合中的檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據【OR】關聯多個查詢條件,查詢集合中的檔案資料
     */
    @Test
    public void findByOrCondition() {
        // 建立條件
        Criteria criteriaUserName = Criteria.where("userName").is("張三");
        Criteria criteriaPassWord = Criteria.where("passWord").is("123456");
        // 建立條件物件,將上面條件進行 OR 關聯
        Criteria criteria = new Criteria().orOperator(criteriaUserName, criteriaPassWord);
        // 建立查詢物件,然後將條件物件新增到其中
        Query query = new Query(criteria);
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據【IN】關聯多個查詢條件,查詢集合中的檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據【IN】關聯多個查詢條件,查詢集合中的檔案資料
     */
    @Test
    public void findByInCondition() {
        // 設定查詢條件引數
        List<Long> ids = Arrays.asList(1l, 10l, 11l);
        // 建立條件
        Criteria criteria = Criteria.where("id").in(ids);
        // 建立查詢物件,然後將條件物件新增到其中
        Query query = new Query(criteria);
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據【邏輯運運算元】查詢集合中的檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據【邏輯運運算元】查詢集合中的檔案資料
     */
    @Test
    public void findByOperator() {
        // 設定查詢條件引數
        int min = 20;
        int max = 35;
        Criteria criteria = Criteria.where("age").gt(min).lte(max);
        // 建立查詢物件,然後將條件物件新增到其中
        Query query = new Query(criteria);
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據【正規表示式】查詢集合中的檔案資料
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據【正規表示式】查詢集合中的檔案資料
     */
    @Test
    public void findByRegex() {
        // 設定查詢條件引數
        String regex = "^張*";
        Criteria criteria = Criteria.where("userName").regex(regex);
        // 建立查詢物件,然後將條件物件新增到其中
        Query query = new Query(criteria);
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據條件查詢集合中符合條件的檔案,獲取其檔案列表並排序
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根據條件查詢集合中符合條件的檔案,獲取其檔案列表並排序
     */
    @Test
    public void findByConditionAndSort() {
        String userName = "張三";
        Query query = new Query(Criteria.where("userName").is(userName)).with(Sort.by("age"));
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 根據單個條件查詢集合中的檔案資料,並按指定欄位進行排序與限制指定數目
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

   /**
     * 根據單個條件查詢集合中的檔案資料,並按指定欄位進行排序與限制指定數目
     */
    @Test
    public void findByConditionAndSortLimit() {
        String userName = "張三";
        //從第一行開始,查詢2條資料返回
        Query query = new Query(Criteria.where("userName").is(userName)).with(Sort.by("createTime")).limit(2).skip(1);
        List<Person> result = mongoTemplate.find(query, Person.class);
        System.out.println("查詢結果:" + result.toString());
    }
}
  • 統計集合中符合【查詢條件】的檔案【數量】
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

   /**
     * 統計集合中符合【查詢條件】的檔案【數量】
     */
    @Test
    public void countNumber() {
        // 設定查詢條件引數
        String regex = "^張*";
        Criteria criteria = Criteria.where("userName").regex(regex);
        // 建立查詢物件,然後將條件物件新增到其中
        Query query = new Query(criteria);
        long count = mongoTemplate.count(query, Person.class);
        System.out.println("統計結果:" + count);
    }
}

4.0、建立索引

索引在所有的資料庫中,暫居的位置非常重要,例如當你檢索一張上百萬的資料表的時候,如果沒走索引,查詢效率會極其緩慢,對於 MongoDB 來說,同樣如此。

範例如下:

  • 建立升序索引
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 建立升序索引
     */
    @Test
    public void createAscendingIndex() {
        // 設定欄位名稱
        String field = "userName";
        // 建立索引
        mongoTemplate.getCollection("persons").createIndex(Indexes.ascending(field));
    }
}
  • 移除索引
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

   /**
     * 根據索引名稱移除索引
     */
    @Test
    public void removeIndex() {
        // 設定欄位名稱
        String field = "userName";
        // 刪除索引
        mongoTemplate.getCollection("persons").dropIndex(field);
    }
}
  • 查詢集合中所有的索引
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

   /**
     * 查詢集合中所有的索引
     */
    @Test
    public void getIndexAll() {
        // 獲取集合中所有列表
        ListIndexesIterable<Document> indexList = mongoTemplate.getCollection("persons").listIndexes();
        // 獲取集合中全部索引資訊
        for (Document document : indexList) {
            System.out.println("索引列表:" + document);
        }
    }
}
  • 我們還可以通過在實體類上加註解方式來建立索引
/**
 * 使用@Document註解指定集合名稱
 */
@Document(collection="persons")
public class Person implements Serializable {
    private static final long serialVersionUID = -3258839839160856613L;

    /**
     * 使用@Id註解指定MongoDB中的 _id 主鍵
     */
    @Id
    private Long id;

    private String userName;

    private String passWord;

    private Integer age;

    /**
     * 建立一個5秒之後檔案自動刪除的索引
     */
    @Indexed(expireAfterSeconds=5)
    private Date createTime;

    //...get/set

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", passWord='" + passWord + '\'' +
                ", age=" + age +
                ", createTime=" + createTime +
                '}';
    }
}

4.1、引入 MongoDB 中的事務

單節點 mongodb 不支援事務,需要搭建 MongoDB 複製集。

/**
 * 設定事務管理器
 *
 */
@Configuration
public class TransactionConfig {

    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

}

事務服務測試!

@Service
public class TransactionExample {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Transactional(rollbackFor = Exception.class)
    public Object transactionTest(){
        Person person =new Person();
        person.setId(1l);
        person.setUserName("張三");
        person.setPassWord("123456");
        person.setCreateTime(new Date());
        Person newPerson = mongoTemplate.insert(person);
        // 丟擲異常,觀察資料是否進行回滾
        if(1 == 1){
            throw new RuntimeException("異常");
        }
        return newPerson;
    }
}

四、小結

本文主要圍繞 MongoDB 的 Java 使用者端使用進行基本的增刪改查操作介紹,在實際的業務場景中,可能還需要用到聚合函數等高階查詢,大家如果有這種需求,可以存取如下地址獲取更加詳細的 api 檔案介紹:MongoDB 檔案查詢 api 介紹

五、參考

1、菜鳥教學 - mongodb

2、超級小豆丁 - MongoDB 介紹