在springBoot项目中使用mongodb数据库时,我们通常使用 spring-boot-starter-data-mongodb来进行数据库相关操作。相关操作流程如下
1、在项目中引入相关依赖
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-mongodb')
compileOnly('org.projectlombok:lombok')
}
引入spring-data-mongodb和lombok插件
2、创建测试的实体类
@Data
@Document(collection = "class")
@FieldNameConstants
public class ClassDO {
public static final String FIELD_WITH_OUT_STUDENT_ID ="studentId";
public static final String FIELD_STUDENT_ID ="students.studentId";
public static final String FIELD_STUDENT_NAME ="students.$.name";
public static final String FIELD_STUDENT_SEX ="students.$.sex";
public static final String FIELD_STUDENT_AGE ="students.$.age";
@Id
private String id;
private String name;
/**
* 老师Id列表
*/
private List<String> teacherIds;
/**
* 学生列表
*/
private List<Student> students;
@Data
public static class Student {
private String studentId;
private String name;
private String sex;
private Integer age;
}
}
可以看到老师的id是String类型的list,Student是个内部类,相当于mongodb的子文档的概念。本文主要介绍对于两种类型list的修改操作。
3、对List< String> 的相关操作
主要介绍批量插入和删除操作,mongodb使用push来进行插入操作,使用pull来进行删除操作。
3.1、批量插入数据
public long pushTeacherItem(String classId, List<String> item) {
Criteria criteria = Criteria.where(ClassDO.FIELD_ID).is(new ObjectId(classId));
Update update = new Update();
update.pushAll(ClassDO.FIELD_TEACHER_IDS, item.toArray());
UpdateResult writeResult = template.updateMulti(Query.query(criteria), update, clazz);
long n = writeResult.getModifiedCount();
if (n == 0) {
log.warn("No matched class {} found when push class teacher item", classId);
}
return n;
}
执行pushall操作时需要传入数组对象。
3.2、批量删除数据
public long pullTeacherItem(String classId, List<String> item) {
Criteria criteria = Criteria.where(ClassDO.FIELD_ID).is(new ObjectId(classId));
Update update = new Update();
update.pullAll(ClassDO.FIELD_TEACHER_IDS, item.toArray());
UpdateResult writeResult = template.updateMulti(Query.query(criteria), update, clazz);
long n = writeResult.getModifiedCount();
if (n == 0) {
log.warn("No matched class {} found when pull class teacher item", classId);
}
return n;
}
4、对List< 实体类>的相关操作
不同于对List< String>的操作,对于List< 实体类>不能直接使用push和pull操作进行修改。
4.1、批量插入数据
public long pushStudentItem(String classId, List<ClassController.StudentDTO> item) {
Criteria criteria = Criteria.where(ClassDO.FIELD_ID).is(new ObjectId(classId));
Update update = new Update();
Update.AddToSetBuilder add = update.new AddToSetBuilder(ClassDO.FIELD_STUDENTS);
update = add.each(item);
UpdateResult writeResult = template.updateMulti(Query.query(criteria), update, clazz);
long n = writeResult.getModifiedCount();
if (n == 0) {
log.warn("No matched class {} found when push class student item", classId);
}
return n;
}
使用AddToSetBuilder 和each进行批量数据插入操作
4.2、批量删除操作
public long pullStudentItem(String classId, List<String> ids) {
Criteria criteria = Criteria.where(ClassDO.FIELD_ID).is(new ObjectId(classId));
Criteria subCriteria = Criteria.where(ClassDO.FIELD_WITH_OUT_STUDENT_ID).in(ids);
Update update = new Update();
update.pull(ClassDO.FIELD_STUDENTS, Query.query(subCriteria));
UpdateResult writeResult = template.updateMulti(Query.query(criteria), update, clazz);
long n = writeResult.getModifiedCount();
if (n == 0) {
log.warn("No matched class {} found when pull class student item", classId);
}
return n;
}
上述操作与下面语句相对应:
db.getCollection("class").update({"_id" : ObjectId("5be040b04564c8658f36a600")},
{$pull:{"students":{studentId:{$in:["101","102"]}}}})
5、更改指定子文档属性
public long updateStudentItem(String classId, String studentId, ClassController.StudentDTO item) {
Criteria criteria = Criteria.where(ClassDO.FIELD_ID).is(classId)
.and(ClassDO.FIELD_STUDENT_ID).is(studentId);
Update update = Update.update(ClassDO.FIELD_STUDENT_AGE, item.getAge())
.set(ClassDO.FIELD_STUDENT_NAME, item.getName())
.set(ClassDO.FIELD_STUDENT_SEX, item.getSex());
UpdateResult updateResult = template.updateFirst(Query.query(criteria), update, clazz);
long n = updateResult.getModifiedCount();
if (n == 0) {
log.warn("No matched class {} found when update class student item", classId);
}
return n;
}