springboot系列十一 Spring-Data-MongoDB

mongodb

MongoDB 是一個基於分佈式文件存儲的NoSQL數據庫。由 C++ 語言編寫。旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。
MongoDB 是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。

數據存儲格式類似於json

{ 
    "_id" : ObjectId("5c061052f94458c11e167a5a"), 
    "name" : "test", 
    "age" : NumberInt(13), 
    "createTime" : ISODate("2018-12-04T05:27:46.633+0000")
}

官方文檔

https://docs.mongodb.com/manual/?_ga=2.34252649.996507481.1543901385-1321775126.1543901385

官方示例java代碼

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import java.util.ArrayList;
import java.util.List;

import com.mongodb.client.model.Indexes;

import static com.mongodb.client.model.Accumulators.sum;
import static com.mongodb.client.model.Aggregates.group;
import static com.mongodb.client.model.Aggregates.match;
import static com.mongodb.client.model.Filters.eq;
import static java.util.Arrays.asList;

public class MongoDBExamples {

   public static void main(final String[] args) {

       // 1. Connect to MongoDB instance running on localhost
       MongoClient mongoClient = new MongoClient();

       // Access database named 'test'
       MongoDatabase database = mongoClient.getDatabase("test");

       // Access collection named 'restaurants'
       MongoCollection<Document> collection = database.getCollection("restaurants");

       // 2. Insert 
       List<Document> documents = asList(
               new Document("name", "Sun Bakery Trattoria")
                       .append("stars", 4)
                       .append("categories", asList("Pizza", "Pasta", "Italian", "Coffee", "Sandwiches")),
               new Document("name", "Blue Bagels Grill")
                       .append("stars", 3)
                       .append("categories", asList("Bagels", "Cookies", "Sandwiches")),
               new Document("name", "Hot Bakery Cafe")
                       .append("stars", 4)
                       .append("categories", asList("Bakery", "Cafe", "Coffee", "Dessert")),
               new Document("name", "XYZ Coffee Bar")
                       .append("stars", 5)
                       .append("categories", asList("Coffee", "Cafe", "Bakery", "Chocolates")),
               new Document("name", "456 Cookies Shop")
                       .append("stars", 4)
                       .append("categories", asList("Bakery", "Cookies", "Cake", "Coffee")));

       collection.insertMany(documents);


       // 3. Query 
       List<Document> results = collection.find().into(new ArrayList<>());


       // 4. Create Index 
       collection.createIndex(Indexes.ascending("name"));
       // 5. Perform Aggregation
       collection.aggregate(asList(match(eq("categories", "Bakery")),
               group("$stars", sum("count", 1))));


        mongoClient.close();

   }

}

支持語言

安裝方法

客戶端選擇

springboot集成mongodb

依賴

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

配置

spring:
  data:
    mongodb:
      #uri配置
      #  如果有密碼 mongodb://user:pass@localhost:27017/test
      #  如果集羣 mongodb://user:pass@ip1:port1,ip2:port2/database
      uri: mongodb://localhost:27017/test

目前spring-data-starter-mongo並沒有提供連接池配置。如需要自己配置,參考

王靜茜 Spring Boot中使用MongoDB的連接池配置

翟永超 Spring Boot中增強對MongoDB的配置(連接池等)

使用MongoTemplate

mongoTemplate可以靈活的操作mongodb,如基本的CRUD、統計、聚合等

簡單CURD

實體類

public class User {
    private String id;
    private String name;
    private int age = 18;
    private LocalDateTime createTime = LocalDateTime.now();
}

接口測試類

@RestController
public class UserResource {

    @Autowired
    private MongoTemplate mongoTemplate;
    //添加
    @PostMapping("/template/user")
    public User save(@RequestBody User user){
        return mongoTemplate.save(user);
    }
    //查詢所有
    @GetMapping("/template/user")
    public List<User> findAll(){
        return mongoTemplate.findAll(User.class);
    }
    //根據姓名查詢
    @GetMapping("/template/user/{name}")
    public User findOne(@PathVariable String name){
        return mongoTemplate.findOne(Query.query(Criteria.where("name").is(name)), User.class);
    }
}

測試

添加一個用戶 POST http://localhost:8080/template/user

查看mongodb

調用查詢接口 GET http://localhost:8080/template/user

[
    {
        "id": "5c061052f94458c11e167a5a",
        "name": "test",
        "age": 13,
        "createTime": "2018-12-04T13:27:46.633"
    }
]

根據姓名查詢 GET http://localhost:8080/template/user/test

{
    "id": "5c061052f94458c11e167a5a",
    "name": "test",
    "age": 13,
    "createTime": "2018-12-04T13:27:46.633"
}

mongotemplate聚合統計

新建一個實體

@Data
public class Stu {
    private String id;
    private String name;
    private int sex = 1;//1男 2女
    private int age;
    private String grade;//年級
    private String school;//學校
}

添加單元測試,來添加測試數據

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MongoApp.class)
public class StuTest {
    @Autowired private MongoTemplate mongoTemplate;


    Random random = new Random();
    @Test
    public void addStus(){
        List<Stu> list = new ArrayList<>(20);
        for(int i = 0; i<20;i++){
            Stu stu = new Stu();
            stu.setName("學生" + i);
            stu.setSex(i%2 == 0 ? 1 : 2);
            stu.setAge(random.nextInt(20) + 5);
            stu.setGrade((random.nextInt(4) + 1) + "年級");
            stu.setSchool("第" + (random.nextInt(4) + 1) + "學校");
            list.add(stu);
        }
        mongoTemplate.insertAll(list);
    }
}

執行單元測試後,查看mongo的數據

統計的測試接口

/**------------ MongoTemplate 聚合統計 -------------*/

    /**根據自定義字段分組統計*/
    @GetMapping("/template/group/{groupFiled}")
    public Iterator<BasicDBObject> groupBase(@PathVariable String groupFiled){
        Aggregation agg = Aggregation.newAggregation(Aggregation.group(groupFiled).count().as("總人數"));
        AggregationResults<BasicDBObject> res = mongoTemplate.aggregate(agg, "stu", BasicDBObject.class);
        Iterator<BasicDBObject> iterator = res.iterator();
        return iterator;
    }

    /**按條件,根據多個字段分組*/
    @GetMapping("/template/group")
    public Iterator<BasicDBObject> groupWithQueryCondition(){
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("age").gte(10)),
                Aggregation.group("school", "grade").count().as("總人數"),
                Aggregation.project("總人數").and("分組字段").previousOperation()//顯示分組字段,不顯示_id
        );
        AggregationResults<BasicDBObject> res = mongoTemplate.aggregate(agg, "stu", BasicDBObject.class);
        Iterator<BasicDBObject> iterator = res.iterator();
        return iterator;
    }

測試

  • 根據年級統計 GET http://localhost:8080/template/group/grade

  • 根據學校統計 GET http://localhost:8080/template/group/school

  • 多條件多字段統計 GET http://localhost:8080/template/group

MongoRepository使用

定義一個接口,繼承MongoRepository,然後可以使用基於JPA的mongo操作了

public interface UserRepository extends MongoRepository<User, String> {

    User findByName(String name);
}

使用

    /**------------ MongoRepository -------------*/
    @Autowired private UserRepository userRepository;
	
    @PostMapping("/repository/user")
    public User save1(@RequestBody User user){
        return userRepository.save(user);
    }

    @GetMapping("/repository/user")
    public List<User> findAll1(){
        return userRepository.findAll();
    }

    @GetMapping("/repository/user/{name}")
    public User findOne1(@PathVariable String name){
        return userRepository.findByName(name);//自定義方法
    }

項目源碼

https://gitee.com/yimingkeji/springboot/tree/master/mongo

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