1. 程式人生 > 其它 >[MongoDB筆記]Spring Data MongoDB的使用

[MongoDB筆記]Spring Data MongoDB的使用

技術標籤:mongodbnosqljava

文章目錄

Spring Data MongoDB

Spring Data MongoDB是Spring使用面向物件的方式操作MongoDB,省略了使用MongoDB的Java客戶端API把Document轉換成實體類的過程

環境搭建

  1. 建立maven專案並配置pom檔案

    <
    dependencyManagement
    >
    <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.5.PELEASE</version> <
    type
    >
    pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <
    artifactId
    >
    spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
  2. 配置application.yml

    spring:
      data:
        mongodb:
          host: 10.11.82.28
          port: 27017
          database: test
          username: root
          password: root
          authentication-database: admin # 進行認證的資料庫
    
  3. 實體類

    /**
     * Document:
     *  指定當前實體類對應哪一個集合,不傳遞引數則預設為類名首字母轉小寫
     */
    @Document("ego_user")
    @Data
    public class User implements Serializable {
    
        /**
         * Id:
         *  Spring Data提供的公共註解,用來描述主鍵
         *  在Spring Data MongoDB環境中,如果實體類的屬性命名為id或_id,且這個屬性為主鍵屬性時,可以省略@Id註解
         */
        @Id
        @Field("_id")
        private Long id;
    
        /**
         * Field:
         *  描述類中屬性與集合欄位的對映關係
         *  不指定則預設為屬性名
         */
        @Field("username")
        private String username;
    
        private String password;
    
        private String email;
    
        private List<String> courses;
    }
    

下面就可以使用Spring Data MongoDB提供的MongoTemplate進行資料操作了

資料新增

/**
 * Spring Data MongoDB提供的通用客戶端型別
 * 使用這個Template可以快速事項資料的讀寫操作
 * 這個型別物件建立需要配置檔案提供spring.data.mongodb相關配置
 */
@Autowired
private MongoTemplate mongoTemplate;

//新增資料
@Test
public void testInsert() {
    //建立實體物件
    User user = new User();
    user.setId(100L);
    user.setUsername("testUsername");
    user.setPassword("testPassword");
    user.setEmail("[email protected]");
    user.setCourses(Arrays.asList("Spring Data", "SpringBoot"));

    //新增資料
    mongoTemplate.insert(user);
}

在這裡插入圖片描述

主鍵只有String型別和Objectld(org.bson.types包下)型別可以自動建立,其他型別只能手動建立

資料儲存

@Autowired
private MongoTemplate mongoTemplate;

//儲存資料, 主鍵存在則覆蓋,主鍵不存在則新增
@Test
public void testSave() {
    User user = new User();
    user.setId(101L);
    user.setUsername("張三");
    user.setPassword("testSave");
    user.setEmail("[email protected]");
    user.setCourses(Arrays.asList("Spring Data", "SpringBoot"));

    mongoTemplate.save(user);
}

資料更新

只更新第一個匹配的資料

//資料更新,只有表示式更新,沒有覆蓋更新
@Test
public void testUpdate() {
    /**
         * 只更新匹配的第一個資料
         */
    Query query = new Query();
    query.addCriteria(Criteria.where("username").is("張三"));

    Update update = new Update();
    //各種更新表示式都做成了方法
    update.set("password", "1234").inc("age", 1);

    UpdateResult updateResult = mongoTemplate.updateFirst(query, update, User.class);
    System.out.println("匹配的行數" + updateResult.getMatchedCount());
    System.out.println("修改的行數" + updateResult.getModifiedCount());
}

這是面向MongoDB的,因此Key都是欄位名而不是實體類的屬性

更新所有匹配資料

@Test
public void testUpdateMulti() {

    Query query = new Query();
    query.addCriteria(Criteria.where("_id").lt(200L));

    //相當於new Update().set("courses", Arrays.asList("Java", "C++"));
    Update update = Update.update("courses", Arrays.asList("Java", "C++"));

    UpdateResult updateResult = mongoTemplate.updateMulti(query, update, User.class);

    System.out.println("匹配的行數" + updateResult.getMatchedCount());
    System.out.println("修改的行數" + updateResult.getModifiedCount());
}

匹配到則修改,沒有匹配到則新增

//沒有匹配到則新增
@Test
public void testUpsert() {

    Query query = new Query().addCriteria(Criteria.where("username").is("王五"));

    //相當於new Update().set("courses", Arrays.asList("Java", "C++"));
    Update update = Update.update("courses", Arrays.asList("Java", "C++"));

    UpdateResult upsert = mongoTemplate.upsert(query, update, User.class);
    System.out.println("匹配的行數" + upsert.getMatchedCount());
    System.out.println("修改的行數" + upsert.getModifiedCount());
    System.out.println("新增資料ID" + upsert.getUpsertedId());
}

由於這是面向MongoDB的,因此新增資料時不會產生如_class這樣的SpringDataMongoDB相關資訊,以後使用實體類操作可能會出現問題,因此不推薦使用

刪除資料

根據主鍵刪除

//刪除資料, 根據Java物件刪除資料,SpringDataMongoDB會找到這個物件型別對應的集合,使用主鍵作為條件刪除
@Test
public void removeObject() {
    User user = new User();
    user.setId(100L);

    DeleteResult remove = mongoTemplate.remove(user);
    System.out.println("刪除的行數" + remove.getDeletedCount());
}

根據查詢條件刪除

//根據條件刪除
@Test
public void removeQuery() {
    Query query = new Query().addCriteria(Criteria.where("username").is("張三"));
    DeleteResult remove = mongoTemplate.remove(query, User.class);
    System.out.println("刪除的行數" + remove.getDeletedCount());
}

資料查詢

查詢全部資料

//查詢所有資料
@Test
public void findAll() {

    List<User> users = mongoTemplate.findAll(User.class);

    for (User user : users) {
        System.out.println(user);
    }

}

查詢單個數據

//查詢單個數據
@Test
public void findOne() {

    //根據主鍵查詢單個數據
    User userById = mongoTemplate.findById(100L, User.class);
    System.out.println(userById);

    //根據查詢條件查詢第一條資料
    Query query = new Query().addCriteria(Criteria.where("username").is("李四"));
    User userOne = mongoTemplate.findOne(query, User.class);
    System.out.println(userOne);
}

單條件查詢

//單條件查詢
@Test
public void findQuery() {

    //        Query query = new Query().addCriteria(Criteria.where("_id").lt(102L).gte(100L));//範圍查詢
    //        Query query = new Query().addCriteria(Criteria.where("username").exists(true));//根據欄位是否存在查詢
    //        Query query = new Query().addCriteria(Criteria.where("username").type(JsonSchemaObject.Type.STRING));//根據欄位型別查詢
    Query query = new Query().addCriteria(Criteria.where("password").regex("t"));//正則查詢
    List<User> users = mongoTemplate.find(query, User.class);

    for (User user : users) {
        System.out.println(user);
    }

}

複合條件查詢

//複合條件查詢
@Test
public void find() {

    Criteria criteria = new Criteria();
    //        //AND查詢
    //        criteria.andOperator(
    //                Criteria.where("password").regex("t"),
    //                Criteria.where("_id").lt(101L));

    //        //OR查詢
    //        criteria.orOperator(
    //                Criteria.where("username").is("張三"),
    //                Criteria.where("_id").lt(101L)
    //        );

    //AND和OR共同查詢
    criteria.orOperator(

        new Criteria().andOperator(
            Criteria.where("password").regex("t"),
            Criteria.where("_id").lt(101L)
        ),

        new Criteria().andOperator(
            Criteria.where("username").is("張三"),
            Criteria.where("_id").lt(101L)
        )
    );


    Query query = new Query().addCriteria(criteria);

    List<User> users = mongoTemplate.find(query, User.class);

    for (User user : users) {
        System.out.println(user);
    }

}

排序

//排序
@Test
public void sort() {
    //降序
    Query query = new Query().with(Sort.by(Sort.Direction.DESC, "_id"));
    List<User> users = mongoTemplate.find(query, User.class);

    for (User user : users) {
        System.out.println(user);
    }
}

分頁

//分頁
@Test
public void pageable() {
    Query query = new Query().with(
        PageRequest.of(0, 2)
    );

    List<User> users = mongoTemplate.find(query, User.class);

    for (User user : users) {
        System.out.println(user);
    }

}

排序並分頁

@Test
public void pageable() {
    Query query = new Query().with(
        PageRequest.of(0, 2, Sort.by(Sort.Direction.DESC, "_id"))
    );

    List<User> users = mongoTemplate.find(query, User.class);

    for (User user : users) {
        System.out.println(user);
    }

}

聚合查詢

//聚合查詢
@Test
public void agg() {
    TypedAggregation<User> aggregation =
        TypedAggregation.newAggregation(
        User.class,
        Aggregation
        .group("username")//分組, 不寫引數為不分組
        .count()//聚合函式(計數)
        .as("count"));//結果的別名

    AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, Map.class);
    List<Map> mappedResults = results.getMappedResults();

    for (Map mappedResult : mappedResults) {
        System.out.println(mappedResult);
    }

}