MongoTemplate使用

3,983 阅读6分钟

DOC文档

示例类

@Data       // lombok,默认生成getter/setter方法
@Accessors(chain = true)    // lombok,按驼峰原则生成getter/setter方法
@EqualsAndHashCode(callSuper = false)   // 默认不覆写equals和hashcode方法
@TypeAlias("user")
@Document("user")
public class T_User {
    @ApiModelProperty(name = "id", value = "编号", dataType = "String", required = true)
    @Id
    private String id;

    @ApiModelProperty(name = "userPhone", value = "手机号码", dataType = "String", required = true)
    @NotBlank(message = "手机号码不能为空!")
    private String userPhone;

    @ApiModelProperty(name = "userPwd", value = "密码", dataType = "String", required = true)
    @NotBlank(message = "密码不能为空!")
    private String userPwd;

    @ApiModelProperty(name = "status", value = "状态", dataType = "String", required = true)
    private Integer status;

    @ApiModelProperty(name = "insTime", value = "插入时间", dataType = "String", required = true)
    private LocalDateTime insTime;
    
    @ApiModelProperty(name = "version", value = "版本/乐观锁", dataType = "String", required = true)
    @Version
    private Long version;
    
    @ApiModelProperty(name = "height", value = "身高(米)", dataType = "String", required = true)
    @Field(targetType = FieldType.DOUBLE)
    private BigDecimal height;

    @ApiModelProperty(name = "wealth", value = "财富", dataType = "String", required = true)
    @Field(targetType = FieldType.DECIMAL128)
    private BigDecimal wealth;
}
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@TypeAlias("book")
@Document("book")
public class T_Books {
    @ApiModelProperty(name = "id", value = "编号", dataType = "String", required = true)
    @Id
    private String id;

    @ApiModelProperty(name = "name", value = "名称", dataType = "String", required = true)
    @NotBlank(message = "名称不能为空!")
    private String name;

    @ApiModelProperty(name = "author", value = "作者", dataType = "String", required = true)
    @NotBlank(message = "作者不能为空!")
    private String author;

    @ApiModelProperty(name = "status", value = "状态", dataType = "String", required = true)
    private Integer status;

    @ApiModelProperty(name = "insTime", value = "插入时间", dataType = "String", required = true)
    private LocalDateTime insTime;

    @ApiModelProperty(name = "version", value = "版本/乐观锁", dataType = "String", required = true)
    @Version
    private Long version;

    @ApiModelProperty(name = "price", value = "价格", dataType = "String", required = true)
    @Field(targetType = FieldType.DECIMAL128)
    private BigDecimal price;
}

注解

@TypeAlias
作用于 POJO 类,默认文档 _class 别名;
@Document
作用于 POJO 类,默认文档集合名;
@Id
作用于主键属性,对应 _id;
@Version
作用于版本属性,对应 version;
@Field 
作用于属性,targetType指定类型,对应数据库字段;

方法

1、新增

// 流式操作新增
ExecutableInsert insert(Class<T> c);
// 默认集合
T insert(T t);
// 指定集合
T insert(T t, String collectionName);

// 可覆写新增
T save(T t);
// 指定集合
T save(T t, String collectionName);

// 批量插入
Collection<T> insertAll(Collection<T> c);
Collection<T> insert(Collection<T> c, Class<T> t);
Collection<T> insert(Collection<T> c, String collectionName);
T_User user1 = new T_User()
        .setUserPhone("110")
        .setUserPwd("123");
// _id 未赋值,每次 insert 生成一个新文档,数据库自动生成 _id
// 默认使用 pojo 类首字母小写作为集合名,可使用 @Document 在 pojo 注解定义默认集合名
// T 非Null、基本类型、字符串、Array、List、Collection、Iterator
user1 = mongoTemplate.insert(user1);
// 相同 _id,insert 报异常
mongoTemplate.insert(user1);

T_User user2 = new T_User()
        .setUserPhone("234")
        .setUserPwd("123");
// _id 未赋值,每次 save 生成一个新文档,数据库自动生成 _id
user2 = mongoTemplate.save(user2);
// 相同 _id,覆盖原文档
user2.setUserPwd("234");
mongoTemplate.save(user2);
{ 
    "_id" : ObjectId("5e96afe815a25f3e385c1cd9"), 
    "userPhone" : "110", 
    "userPwd" : "123", 
    "version" : NumberLong(0), 
    "_class" : "top.zitangkou.mongo.model.T_User"
}

2、更新

  • 更新一个
// 流式操作新增
ExecutableUpdate update(Class<T> c);
// 更新第一个,不支持排序
// 指定 _class 中 query 匹配的第一个
UpdateResult updateFirst(Query q, Update u, Class<T> t);
// 指定集合和 _class 中 query 匹配的第一个
UpdateResult updateFirst(Query q, Update u, String collectionName);
// 指定集合中 query 匹配的第一个
UpdateResult updateFirst(Query q, Update u, Class<T> t, String collectionName);
  • 更新多个
UpdateResult updateMulti(Query q, Update u, Class<T> t);
UpdateResult updateMulti(Query q, Update u, String collectionName);
UpdateResult updateMulti(Query q, Update u, Class<T> t, String collectionName);
  • 更新 || 新增
// query 没有匹配则新增,不支持排序
// UpdateResult upsert(Query q, Update u, Class<T> t);
// UpdateResult upsert(Query q, Update u, String collectionName);
// UpdateResult upsert(Query q, Update u, Class<T> t, String collectionName);
mongoTemplate.upsert(Query.query(Criteria.where("name").is("HongLouMeng")),
        new Update().set("price", 2.5).set("name", "HongLouMeng").set("author", "aaa"),
        T_User.class);
// upsert 与 setOnInsert 使用,upsert 没有插入,setOnInsert 也不会执行;
mongoTemplate.upsert(Query.query(Criteria.where("age").is(20)),
        new Update().setOnInsert("age", 20),
        T_User.class);
  • 查询 && 新增
// T findAndModify(Query query, Update update, Class<T> entityClass);
// T findAndModify(Query query, Update update, Class<T> entityClass, String collectionName);
// T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass);
// T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass, String collectionName);

3、删除

// 流式操作删除
ExecutableRemove remove(Class<T> c);
// 根据 _id 删除
DeleteResult remove(T t);
DeleteResult remove(T t, String collectionName);
// query 匹配删除,一次性删除
DeleteResult remove(Query q, Class<T> c);
DeleteResult remove(Query q, Class<T> c, String collectionName);
DeleteResult remove(Query q, String collectionName);
// 一个一个删除
List<T> findAllAndRemove(Query q, Class<T> c);
List<T> findAllAndRemove(Query q, String collectionName);
List<T> findAllAndRemove(Query q, Class<T> c, String collectionName);

4、查询

// 流式操作查询
ExecutableQuery query(Class<T> c);
// 直接结果查询
List<T> find(Query q, Class<T> c);
List<T> find(Query q, Class<T> c, String collectionName);
List<T> findAll(Class<T> c);
List<T> findAll(Class<T> c, String collectionName);
T findById(Query q, Class<T> c);
T findById(Query q, Class<T> c, String collectionName);
T findOne(Query q, Class<T> c);
T findOne(Query q, Class<T> c, String collectionName);
// 查询分组
List<T> findDistinct(Query q, String field, Class<T> c, Class<T> resultC);
List<T> findDistinct(Query q, String field, String collectionName, Class<T> c, Class<T> resultC);

语法糖

1、Query

2、Criteria

where();
all();

3、修改器-Update

  • 键值修改-inc
// inc(String key, Number inc);     
// 增加/减少键值;不存在则创建;限制数值类型;
mongoTemplate.updateFirst(new Query(Criteria.where("_id").is("110")), 
        new Update().inc("height", 0.1), 
        T_User.class);
  • 键值修改-set
// set(String key, Object obj);     
// 修改键值;替换修改值和类型,不存在则创建;修改内嵌文档;
mongoTemplate.updateFirst(new Query(Criteria.where("_id").is("110")),
        new Update().set("son", mongoTemplate.findOne(Query.query(Criteria.where("_id").is("123")), T_User.class)),
        T_User.class);
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")), 
        new Update().set("son.userPhone", "234"), 
        T_User.class);
  • 键值删除-unset
// unset(String key);       
// 删除键值;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().unset("son"),
        T_User.class);
  • 数组添加-push
// push(String key, Object obj);    
// 数组末尾添加元素,不存在则创建;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().push("grade", 60),
        T_User.class);

// push(String key).each(Object..values);     
// 循环添加多个元素;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().push("grade").each(Stream.of(70, 80).collect(Collectors.toList())),
        T_User.class);

// push(String key).slice(int count).each(Object..values);      
// 限制数组长度为 |count|;
// count 为 0,则当前 key 数组为空;
// count 为正数,则直接保留当前 key 数组前 |count| 位;
// count 为负数,则截取 values 数组后 |count| 几位替换 key 数组,values 数组长度小于 |count| 保留所有元素;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().push("grade").slice(-2).each(Stream.of(60, 70, 80).collect(Collectors.toList())),
        T_User.class);

// push(String key).sort(Direction dir).each(Object..values);
// 用于默认键值排序;
// push(String key).sort(Sort sort).each(Object..values); 
// 用于根据内嵌文档中键值排序;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().push("grade").slice(-2).sort(Sort.Direction.ASC).each(Stream.of(62, 25).collect(Collectors.toList())),
        T_User.class);

// push(String key).atPosition(int p).each(Object..values);
// 指定位置开始添加元素,指定位置元素及后面元素后移;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().push("grade").atPosition(2).each(Stream.of(88, 89).collect(Collectors.toList())),
        T_User.class);
  • 数组去重添加-addToSet
// addToSet(String key, Object obj)
// 单个去重添加
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().addToSet("grade", 88),
        T_User.class);

// addToSet(String key).each(Object..values)
// 多个去重添加
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().addToSet("grade").each(Stream.of(89, 90).collect(Collectors.toList())),
        T_User.class);
  • 数组删除-pop
// pop(String key, Position p);
// 从数组前或后删除一个元素;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().pop("grade", Update.Position.LAST),
        T_User.class);
  • 数组删除-push
// pull(String key, Object obj);
// 删除一个;多个 pull 只会执行最后一个 pull;
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().pull("grade", 88),
        T_User.class);

// pullAll(String key, Object[] obj);
// 删除多个
  • 数组定位修改符-$
// grade.$.
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("110")),
        new Update().set("books", Stream.of(new T_Books().setName("XiXyouJi").setAuthor("www")).collect(Collectors.toList())),
        T_User.class);
mongoTemplate.updateFirst(Query.query(Criteria.where("books.author").is("dnn")),
        new Update().set("books.$.author", "dk"),
        T_User.class);

4、FindAndModifyOptions