# Mango DB

# 实际项目应用

  • 操作日志(转账记录、权限变动的日志)
  • 电商产品详情页的评论信息和商品规格参数(参数数量多,不同的商品参数字段变化很大)

# 使用场景

  • 社交产品:用户信息、朋友圈信息
  • 视频直播:用户信息、评论
  • 物流场景:存储订单状态

# 与Spring Boot 整合

# 1.pom依赖

# version 用的是父模块的version,跟springboot版本号相同,当前是2.7.7
 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <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>
        </dependency>

    </dependencies>

# 2.yml配置

spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/demo
#      uri: mongodb://账号:密码@ip:端口/数据库名
      field-naming-strategy: org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy # 自动转驼峰

# 3.实体类和mongo注解

package org.example.mongodb.entity;

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

import java.util.Date;

@Document("good_info") //表示当前文档属于哪个集合-表名
@Data
@ToString
public class User {
 
    @Id //当前类的 id 映射文档中的 _id
    private Integer id;
    private String name;
    private Integer age;
    @Field("work_day")  //当前类的 workDay 映射文档中的 work_day
    private Date workDay;

   
}

# 4.测试类

package org.example.mongodb;

import com.mongodb.client.MongoCollection;
import org.bson.Document;
import org.example.mongodb.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Date;
import java.util.List;

@SpringBootTest
public class BaseTest {
    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 创建集合(表),默认数据库demo
     */
    @Test
    void createCollection(){

        if(!mongoTemplate.collectionExists("good_info")) {
            //不存在才能创建,如果以及存在再创建就会报错
            mongoTemplate.createCollection("good_info");
        }
    }

    /**
     * 查询集合
     */
    @Test
    void queryCollection(){
        MongoCollection<Document> goodInfo = mongoTemplate.getCollection("good_info");
        System.out.println(goodInfo.getNamespace());

    }

    /**
     * 删除集合
     */
    @Test
    void removeCollection(){
        mongoTemplate.dropCollection("good_info");

    }


    /**
     * 往集合里插入数据
     */
    @Test
    void insert(){
        User user = new User();
        user.setAge(30);
        user.setId(200156891);
        user.setWorkDay(new Date());
        user.setName("栀子花开");
        mongoTemplate.insert(user,"good_info");
        
        
        User user1 = new User();
        user1.setAge(30);
        user1.setId(200156892);
        user1.setWorkDay(new Date());
        user1.setName("周杰伦");
        mongoTemplate.insert(user1,"good_info");

        User user2 = new User();
        user2.setAge(40);
        user2.setId(200156893);
        user2.setWorkDay(new Date());
        user2.setName("薛之谦");
        mongoTemplate.insert(user2,"good_info");

        User user3 = new User();
        user3.setAge(40);
        user3.setId(200156894);
        user3.setWorkDay(new Date());
        user3.setName("凤凰传奇");
        mongoTemplate.insert(user3,"good_info");
    }

    /**
     * 查询数据
     */
    @Test
    void queryUserInfo(){

        //1.查询所有
        System.out.println("------------------------------------------------");
        List<User> users = mongoTemplate.findAll(User.class);
        users.forEach(System.out::println);

        //2.根据 id 查询指定文档
        System.out.println("------------------------------------------------");
        User byId = mongoTemplate.findById(200156891, User.class);
        System.out.println(byId);

        //3.根据查询条件进行查询(参数1: 查询条件, 参数2: 返回类型)
        System.out.println("------------------------------------------------");
//        mongoTemplate.find(new Query(), User.class);  //没有查询条件就是查询所有
        //a) 等值查询
        System.out.println("------------------------------------------------");
        List<User> users1 = mongoTemplate.find(Query.query(Criteria.where("name").is("周杰伦")), User.class);
        users1.forEach(System.out::println);

        //b) > 查询: gt()、>= 查询: gte() 、 < 查询: lt()、<= 查询 lte() 查询
        //以 > 为例
        System.out.println("------------------------------------------------");
        List<User> users2 = mongoTemplate.find(Query.query(Criteria.where("age").gt(30)), User.class);
        users2.forEach(System.out::println);

        //4.and 查询
        System.out.println("------------------------------------------------");
        List<User> users3 = mongoTemplate.find(Query.query(Criteria.where("name").is("薛之谦").and("age").is(40)), User.class);
        users3.forEach(System.out::println);

        //5.or 查询
        System.out.println("------------------------------------------------");
        Criteria criteria = new Criteria();
        criteria.orOperator(
                Criteria.where("name").is("周杰伦"),
                Criteria.where("name").is("薛之谦")
        );
        List<User> users4 = mongoTemplate.find(Query.query(criteria), User.class);
        users4.forEach(System.out::println);

        //6.and 和 or
        System.out.println("------------------------------------------------");
        Criteria criteria1 = new Criteria();
        criteria1.and("age").is(40)
                .orOperator(
                        Criteria.where("name").is("周杰伦"),
                        Criteria.where("name").is("薛之谦")
                );
        List<User> users5 = mongoTemplate.find(Query.query(criteria1), User.class);
        users5.forEach(System.out::println);

        //7.sort
        System.out.println("------------------------------------------------");
        Query query = new Query();
        query.with(Sort.by(Sort.Order.desc("age"))); //desc 降序, asc 升序
        mongoTemplate.find(query, User.class);

        //8.分页: skip limit
        System.out.println("------------------------------------------------");
        Query queryPage = new Query();
        queryPage.with(Sort.by(Sort.Order.desc("age"))) //desc 降序, asc 升序
                .skip(0)
                .limit(3);
        mongoTemplate.find(queryPage, User.class);

        //9.总数
        System.out.println("------------------------------------------------");
        mongoTemplate.count(new Query(), User.class);

        //10.去重 distinct(参数1: 查询条件, 参数2: 去重字段, 参数3: 操作集合, 参数4: 返回类型)
        System.out.println("------------------------------------------------");
        List<String> name = mongoTemplate.findDistinct(new Query(), "name", User.class, String.class);

        //11.json 字符串查询
        System.out.println("------------------------------------------------");
        Query queryJson = new BasicQuery("{name: '周杰伦', age: '20'}");
        List<User> users6 = mongoTemplate.find(queryJson, User.class);

    }

    /**
     * 删除数据
     */
    @Test
    void deleteUserInfo(){

        //1.查询所有
        List<User> users = mongoTemplate.findAll(User.class);
        users.forEach(System.out::println);
        //1.删除所有
//        mongoTemplate.remove(new Query(), User.class);
        //2.条件删除
        mongoTemplate.remove(Query.query(Criteria.where("name").is("栀子花开")), User.class);

        System.out.println("====================");
        //1.查询所有
        List<User> user2 = mongoTemplate.findAll(User.class);
        user2.forEach(System.out::println);
    }
}