MongoDB基础篇-08-spring-boot-starter-data-mongodb玩法

2023-10-30

0. 简述

使用Spring Data 框架都是按照面向对象思想操作用于的工具。
使用Spring Data Mongodb 也是使用面向对象的方式进行操作MongoDB,省略了使用Mongodb的Java客户端API把Document转换为实体类的过程;

1. 依赖

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

2. yaml

spring:
  data:
    mongodb:
      database: ccc             # 操作的库
      host: 192.168.2.138
      username: readWrite01
      password: readWrite01
      port: 27017
      authentication-database: ccc  #认证的库

我演示是在ccc库下的ccc集合操作

3. MongoTemplate的使用

  1. 创建实体类
@Document("ccc")
public class User implements Serializable {

    private static final long serialVersionUID = -2979380902844853046L;


    /**
     * 主键 主键可以叫做id也能映射上_id
     */
    @Id
    String id;
    
    /**
     * key
     */
    String name;
    
    /**
     * value
     */
    String value;
  • @Document 参数表示操作的集合名称,如果没有@Document表示操作的集合名为实体类名首字母变小写(由大驼峰变成小驼峰)。
  • @Id 标识主键。当主键叫做_id或id时可以省略此属性
  • @Field 放在普通属性上,如果希望对属性改名或其他限制需要此注解。可以省略,表示实体类属性名为Mongodb集合中field名称

3.1 添加文档

insert方法返回值是新增的Document对象,里面包含了新增后_id的值

如果集合不存在会自动创建集合。
通过Spring Data MongoDB还会给集合中多加一个_class的属性,存储新增时Document对应Java中类的全限定路径。这么做为了查询时能把Document转换为Java中类类型。

  • 测试代码
@Autowired
    MongoTemplate mongoTemplate;

    @Test
    public void test(){

        User user = new User();
        user.setName("张三");
        user.setValue("张三");

        User insert = mongoTemplate.insert(user);

        System.out.println("insert = " + insert.toString());

    }

在这里插入图片描述

3.2 修改文档

在Mongodb中无论是使用客户端API还是使用Spring Data,更新返回结果一定是受影响行数。如果更新后的结果和更新前的结果是相同,返回0。

如果使用对象方式进行修改(save方法)必须要保证对象中所有属性都是有值,否则只能使用update方法

3.2.1 使用save修改

使用save时,如果主键值已经存在,则表示修改操作

 @Test
    public void saveUser(){
        //当明确给定主键时,如果主键值已经存在save表示修改(全量替换)

        User user = new User();
        user.setId("61ac7634dae9b51c4c658e39");
        user.setName("张三01");
//        user.setValue("张三01");

        User save = mongoTemplate.save(user);
        System.out.println("save = " + save.toString());


    }

在这里插入图片描述

在这里插入图片描述
所以使用save时,必须保证全部有值,因为他是全量替换,没给值的会赋null

3.2.2 使用特定运算符进行更新

底层使用mongodb更新运算符完成。
Update的set方法底层就是$set.可以通过set方法更新特定的属性值

有两个更新方法:

  • updateFirst() 只更新满足条件的第一个值
    @Test
    public void updateOneUser() {

        //设置查询体,查询条件具体内容
        Criteria criteria = Criteria.where("name").is("张三01");

        // query设置查询条件
        Query query = new Query(criteria);
        // 设置修改哪些属性
        Update update = new Update();
        update.set("name", "张三02");
        update.set("value", "张三02");

        // User.class 告诉Spring Data MognoDB 上面的属性是哪个类
        // 类对应集合,就知道具体操作集合的哪个属性
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, User.class);

        // 修改数量,如果修改前后相同,则返回0
        long modifiedCount = updateResult.getModifiedCount();
        System.out.println("modifiedCount = " + modifiedCount);

        // 匹配数量,最多返回1
        long matchedCount = updateResult.getMatchedCount();
        System.out.println("matchedCount = " + matchedCount);


    }
  • updateMulti () 更新所有满足条件的值
    @Test
    public void updateMultiUser() {

        //设置查询体,查询条件具体内容
        Criteria criteria = Criteria.where("name").is("张三02");

        // query设置查询条件
        Query query = new Query(criteria);
        // 设置修改哪些属性
        Update update = new Update();
        update.set("name", "张三03");
        update.set("value", "张三03");

        // User.class 告诉Spring Data MognoDB 上面的属性是哪个类
        // 类对应集合,就知道具体操作集合的哪个属性
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, User.class);

        // 修改数量,如果修改前后相同,则返回0
        long modifiedCount = updateResult.getModifiedCount();
        System.out.println("modifiedCount = " + modifiedCount);

        // 匹配数量,最多返回1
        long matchedCount = updateResult.getMatchedCount();
        System.out.println("matchedCount = " + matchedCount);


    }

3.3 删除文档

3.3.1 根据主键删除

使用remove(Object)实现根据主键进行删除。
只判断对象的主键,其他属性是否有值没有影响。但是主键必须不能是null的

 @Test
    public void removeUser() {
        User user = new User();
        user.setId("61ac7634dae9b51c4c658e39");

        // 根据id主键删除,其他值无所谓
        DeleteResult remove = mongoTemplate.remove(user);
        long deletedCount = remove.getDeletedCount();
        System.out.println("deletedCount = " + deletedCount);

    }

3.3.2 根据条件进行删除

只要是Spring Data MongoDB中涉及到条件都提供了两种方式:

  • 一种根据POJO中属性名进行匹配
  • 另一种是根据集合中属性名进行匹配。

比如下面的name ,实体属性名为name ,但是field为 username

@Document("ccc")
public class User implements Serializable {

    private static final long serialVersionUID = -2979380902844853046L;


    /**
     * 主键 主键可以叫做id也能映射上_id
     */
    @Id
    String id;

    /**
     * key
     */
    @Field("username")
    String name;

  • 通过实体类属性名设置条件
    里面where方法参数name是User类的属性名。
Query query = new Query(Criteria.where("name").is("张三"));
// 第二个参数告诉Spring Data Mongodb ,name属性对应的类类型。
DeleteResult result = mongoTemplate.remove(query, User.class);
System.out.println(result.getDeletedCount());
  • 通过集合属性名设置条件
    其中where方法参数username是集合User的属性名;
    remove第二个参数是MongoDB中集合名称
Query query = new Query(Criteria.where("username").is("张三"));
// 第二个参数告诉Spring Data Mongodb ,name属性对应的类类型。
DeleteResult result = mongoTemplate.remove(query,"ccc");
System.out.println(result.getDeletedCount());

3.4 查询文档

Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在一起,就可以轻松地将多个方法标准和查询连接起来,方便我们操作查询语句。

3.4.1 单个条件查询时:

 @Test
    public void  queryUser(){

        Criteria criteria = Criteria.where("name").is("张三");
        Query query = new Query(criteria);
        List<User> users = mongoTemplate.find(query,User.class);
        System.out.println("users = " + users);

    }

3.4.2 多个条件组合查询时:

@Test
    public void  queryUsers(){

        Criteria criteria = new Criteria().orOperator(Criteria.where("name").is("张三"), Criteria.where("value").is("张三"));

        Query query = new Query(criteria);

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

        System.out.println("users = " + users);


    }

在这里插入图片描述

3.4.3 查询全部文档

  @Test
    public void  queryAllUsers(){
        List<User> users = mongoTemplate.findAll(User.class);
        System.out.println("users = " + users);
    }

3.4.4查询单个文档

    @Test
    public void  queryOneUser(){
        //获取到结果中第一条数据
        // new Query() 表示没有条件
        User one = mongoTemplate.findOne(new Query(), User.class);
        System.out.println("one = " + one);
    }

3.4.5 根据主键进行查询

  @Test
    public void  queryById(){
        //获取到结果中第一条数据
        // new Query() 表示没有条件
        User one = mongoTemplate.findById("61ab981e19453644a04231ff", User.class);
        System.out.println("one = " + one);
    }

3.4.6 根据字段是否为空进行查询

 @Test
    public void  exists(){
        Query query = new Query(Criteria.where("name").exists(true));
        List<User> list = mongoTemplate.find(query, User.class);
        System.out.println(list);
    }

3.4.7 根据大于并且小于查询

 @Test
    public void  exists(){
        Query query = new Query(Criteria.where("age").gte(1).lte(19));
        List<User> list = mongoTemplate.find(query, User.class);
        System.out.println(list);
    }

3.4.8 根据正则查询(模糊查询)

   @Test
    public void  regex(){
        // java中正则不需要有//
        Query query = new Query(Criteria.where("name").regex("张"));
        List<User> list = mongoTemplate.find(query, User.class);
        System.out.println(list);
    }

3.4.9 查询去重复结果

findDistinct() 参数说明:

  • 第一个参数: 查询条件query
  • 第二个参数: 根据哪个属性去重复。是POJO的属性名称。返回值为此属性去重后的集合。
  • 第三个参数: 属性所在实体类。
  • 第四个参数: 属性的类型,此类型作为结果中List集合的泛型。
  @Test
    public void findDistinct() {
        List<String> list = mongoTemplate.findDistinct(new Query(), "name", User.class, String.class);
        System.out.println(list);
    }

3.4.10 结果排序

Sort只有私有构造,但是提供给了静态的by方法
Direction是Sort内部枚举。
age按照那个属性进行排序。属性一定是find方法第二个参数类中的属性。

   @Test
    public void Sort() {
        Query query = new Query(Criteria.where("age").gte(2));
        query.with(Sort.by(Sort.Direction.DESC,"age"));
        List<User> list = mongoTemplate.find(query, User.class);
        System.out.println(list);
    }

3.4.11 分页查询

PageRequest是Pageable接口的实现类。里面有protected的构造方法和名称为of的静态方法。

  • PageRequest.of(page,size)
  • PageRequest.of(page,size,Sort) 先排序后分页
  • PageRequest.of(page,size,Direction,properties) 排序后分页
    • page表示第几页,0表示第一页
    • size表示一页显示几页
    • direction(正序倒序)
    • properties(排序字段)
    @Test
    public void PageRequest() {
        Query query = new Query();
//        query.with(PageRequest.of(0,2));
        query.with(PageRequest.of(0,2, Sort.Direction.DESC,"age"));
        List<User> list = mongoTemplate.find(query, User.class);
        System.out.println(list);
    }

3.4.12 聚合操作

  • 查询文档总数
  • Aggregation.group(String …)设置分组条件,如果没有分组,参数省略。
  • count() 取总条数
  • as() 给查询出来的总条数起别名
  • aggregate() 执行聚合命令,第二个参数Map表示返回结果放入到Map中。
  • result.getUniqueMappedResult() 获取到返回结果。
    @Test
    public void TypedAggregation() {
        TypedAggregation<User> aggregation  = TypedAggregation.newAggregation(User.class,
                Aggregation.group().count().as("count"));
        AggregationResults<Map> result = mongoTemplate.aggregate(aggregation, Map.class);
        System.out.println(result.getUniqueMappedResult());
        System.out.println(result.getUniqueMappedResult().get("count"));
    }
  • 分组计算每组总数
    此处要求group()参数必须是在People类中存在。
    设置group参数,表示按照哪个属性进行分组。
    getMappedResults() 当执行聚合函数返回结果为多行时使用此方法。
    @Test
    public void TypedAggregation() {
        TypedAggregation<User> aggregation  = TypedAggregation.newAggregation(User.class,
                Aggregation.group("name").count().as("count"));
        AggregationResults<Map> result = mongoTemplate.aggregate(aggregation, Map.class);
        List<Map> list = result.getMappedResults();
        for(Map map : list){
            System.out.println(map.get("count")+"---"+map.get("_id"));
        }
    }
  • 带有查询条件的分组计算
    Aggregation.match写在group前面表示先过滤条件在分组。写在后面表示先分组在过滤条件
  @Test
    public void TypedAggregation() {
        TypedAggregation<User> aggregation  = TypedAggregation.newAggregation(User.class,
                Aggregation.match(Criteria.where("name").is("张三")), Aggregation.group("name").count().as("count"));
        AggregationResults<Map> result = mongoTemplate.aggregate(aggregation, Map.class);
        List<Map> list = result.getMappedResults();
        for(Map map : list){
            System.out.println(map.get("count")+"---"+map.get("_id"));
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoDB基础篇-08-spring-boot-starter-data-mongodb玩法 的相关文章

随机推荐