springboot系列十一 Spring-Data-MongoDB

mongodb

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

數據存儲格式相似於jsonhtml

{ 
    "_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.1543901385java

官方示例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並無提供鏈接池配置。如須要本身配置,參考linux

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

翟永超 Spring Boot中加強對MongoDB的配置(鏈接池等)spring

使用MongoTemplate

mongoTemplate能夠靈活的操做mongodb,如基本的CRUD、統計、聚合等mongodb

簡單CURD

實體類docker

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);
    }
}

測試json

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

查看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

相關文章
相關標籤/搜索