Springboot MongoDB CRUD(二)

该文章为 MongoTemplate 方式,基于 JPA(Repositories) 可见文章 Springboot MongoDB CRUD(一)

概述

MongoDB 描述等可见其他文章, 本文章主要基于 springboot 项目演示

版本信息:

  • Java JDK 版本:1.8

  • SpringBoot 版本:2.4.5.RELEASE

  • MongoDB 版本:community-4.4

参考地址:

示例项目地址:

前置条件

以下例子需先创建库,故先手动创建好,可通过脚本或者客户端,自行选择。

# 切换到 test
use test

# 创建 est 授权 读&写&管理权限
db.createUser( {user: "test",pwd: "123456",roles: [ { role: "readWrite", db: "test" },{ role: "dbAdmin", db: "test" }]});

项目实战

SpringBoot 操作主要有两种方式,一种基于 JPA(Repositories)、一种基于MongoDB 官方 Java 驱动 MongoTemplate,直接用代码说话吧。(该文章为 MongoTemplate 方式)

项目构建等忽略, gradle 构建,配置文件:

plugins {
    id 'org.springframework.boot' version '2.4.5'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.xjxxxc.mongodb.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenLocal()
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
    implementation 'com.google.guava:guava:30.1.1-jre'
    implementation 'org.apache.commons:commons-lang3'
    implementation 'com.alibaba:fastjson:1.2.76'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'

    testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.projectlombok:lombok'
}

test {
    useJUnitPlatform()
}

包说明:

├── com
│   └── xjxxxc
│       └── mongodb
│           └── demo
│               ├── MongodbDemoApplication.java # 启动类
│               ├── config # 配置类,如数据源
│               ├── listener # 监听器,如 MongoEvent
│               ├── model # 模型
│               │   └── entity # 实体,JPA 使用
│               ├── repository # JPA repository
│               ├── service # *服务层,提供 MongoDB 特性。
│               └── template # MongoDB 模板类使用 DEMO

项目基本配置

application.properties

server.port=8866
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=test
spring.data.mongodb.username=test
spring.data.mongodb.password=123456

根据情况修改即可,为了演示方便直接写在 application.properties

MongoDBDataSourceConfig

继承 AbstractMongoClientConfiguration 类,重写 mongoClient() 、getDatabaseName() 、mappingMongoConverter() 方法,并且去除 _class 字段。

@Configuration
@EnableMongoRepositories(basePackages = {"com.xjxxxc.mongodb.demo.*"})
public class MongoDBDataSourceConfig extends AbstractMongoClientConfiguration {
    @Value(value = "${spring.data.mongodb.host:127.0.0.1}")
    private String host;

    @Value(value = "${spring.data.mongodb.port:27017}")
    private Integer port;

    @Value(value = "${spring.data.mongodb.database:test}")
    private String database;

    @Value(value = "${spring.data.mongodb.username:test}")
    private String username;

    @Value(value = "${spring.data.mongodb.password:123456}")
    private String password;

    @Override
    public MongoClient mongoClient() {
        MongoClient mongoClient = MongoClients.create(
                MongoClientSettings.builder()
                        // 集群设置
                        .applyToClusterSettings(builder ->
                                builder.hosts(Arrays.asList(new ServerAddress(host, port))))
                        // 凭据
                        .credential(
                                MongoCredential
                                        .createCredential(username, database, password.toCharArray()))
                        .build());
        return mongoClient;
    }


    /**
     * Return the name of the database to connect to.
     *
     * @return must not be {@literal null}.
     */
    @Override
    protected String getDatabaseName() {
        return database;
    }

    /**
     * 去除 _class
     * @param databaseFactory
     * @param customConversions
     * @param mappingContext
     * @return MappingMongoConverter
     */
    @Override
    public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory databaseFactory, MongoCustomConversions customConversions, MongoMappingContext mappingContext) {

        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext);
        converter.setCustomConversions(customConversions());
        converter.setCodecRegistryProvider(mongoDbFactory());
        // Don't save _class to mongo
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));

        return converter;
    }


}

MongoTemplate

这里使用 Spring Data MongoDB 封装的 MongoDB 官方 Java 驱动 MongoTemplate 对 MongoDB 进行操作。

MongoTemplateDemo

基于 MongoTemplate, 实现 CURD 外增加了复杂查询、排序、过滤、分页以及查询、创建索引等方法。

public class MongoTemplateDemo {
    public static final String INDEX_PREFIX = "idx_";

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 插入一条数据
     *
     * @param collectionName 集合名称
     * @param document       文档
     */
    public void insertOne(String collectionName, Document document) {
        mongoTemplate.getCollection(collectionName).insertOne(document);
    }

    /**
     * 批量插入数据
     *
     * @param collectionName 集合名称
     * @param documents      文档
     */
    public void insertMany(String collectionName, List<Document> documents) {
        mongoTemplate.getCollection(collectionName).insertMany(documents);
    }

    /**
     * 根据条件分页查询所有符合条件的结果,并指定返回字段
     *
     * @param collectionName 集合名称
     * @param query          过滤条件
     * @param projection     查询字段
     * @param sort           排序条件
     * @param skip           起始值
     * @param limit          限定数量
     * @return FindIterable<Document>
     */
    public FindIterable<Document> find(String collectionName, Document query, Document projection, Bson sort, int skip, int limit) {
        return mongoTemplate.getCollection(collectionName).find(query).projection(projection).sort(sort).skip(skip).limit(limit);
    }

    /**
     * 根据条件查询所有符合条件的结果,并指定返回字段
     *
     * @param collectionName 集合名称
     * @param query          过滤条件
     * @param projection     查询字段
     * @param sort           排序条件
     * @return FindIterable<Document>
     */
    public FindIterable<Document> find(String collectionName, Document query, Document projection, Document sort) {
        return mongoTemplate.getCollection(collectionName).find(query).projection(projection).sort(sort);
    }

    /**
     * 根据条件查询所有符合条件的结果,并指定返回字段
     *
     * @param collectionName 集合名称
     * @param query          过滤条件
     * @param projection     查询字段
     * @return FindIterable<Document>
     */
    public FindIterable<Document> find(String collectionName, Document query, Document projection) {
        return mongoTemplate.getCollection(collectionName).find(query).projection(projection);
    }

    /**
     * 根据条件查询所有符合条件的结果
     *
     * @param collectionName 集合名称
     * @param query          过滤条件
     * @return FindIterable<Document>
     */
    public FindIterable<Document> find(String collectionName, Document query) {
        return this.find(collectionName, query, null);
    }

    /**
     * 查询一个
     *
     * @param collectionName 集合名称
     * @param query          过滤条件
     * @return Document
     */
    public Document findOne(String collectionName, Document query) {
        FindIterable<Document> iterable = this.find(collectionName, query);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            return mongoCursor.next();
        }
        return new Document();
    }


    /**
     * 分页查询
     *
     * @param collectionName 集合名称
     * @param query          过滤条件
     * @param skip           起始值
     * @param limit          限制条数
     * @return FindIterable
     */
    public FindIterable findPage(String collectionName, Document query, int skip, int limit) {
        return mongoTemplate.getCollection(collectionName).find(query).skip(skip).limit(limit);
    }

    /**
     * 查询条数
     *
     * @param collectionName
     * @param query
     * @return long
     */
    public long count(String collectionName, Document query) {
        return mongoTemplate.getCollection(collectionName).countDocuments(query);
    }

    /**
     * 删除一条
     *
     * @param collectionName
     * @param query
     * @return DeleteResult
     */
    public DeleteResult removeOne(String collectionName, Document query) {
        return mongoTemplate.getCollection(collectionName).deleteOne(query);
    }

    /**
     * 删除多条
     *
     * @param collectionName
     * @param query
     * @return DeleteResult
     */
    public DeleteResult removeMany(String collectionName, Document query) {
        return mongoTemplate.getCollection(collectionName).deleteMany(query);
    }


    /**
     * 修改一条
     *
     * @param collectionName
     * @param query
     * @param update
     * @return UpdateResult
     */
    public UpdateResult updateOne(String collectionName, Document query, Document update) {
        return mongoTemplate.getCollection(collectionName).updateOne(query, update);
    }

    /**
     * 修改多条
     *
     * @param collectionName
     * @param query
     * @param update
     * @return UpdateResult
     */
    public UpdateResult updateMany(String collectionName, Document query, Document update) {
        return mongoTemplate.getCollection(collectionName).updateMany(query, update);
    }

    /**
     * 替换 整个文档
     *
     * @param collectionName
     * @param query
     * @param update
     * @return UpdateResult
     */
    public UpdateResult replaceOne(String collectionName, Document query, Document update) {
        return mongoTemplate.getCollection(collectionName).replaceOne(query, update);
    }

    /**
     * 获取当前集合对应的所有索引的名称
     *
     * @param collectionName
     * @return List<String>
     */
    public List<String> getAllIndexes(String collectionName) {
        ListIndexesIterable<Document> list = mongoTemplate.getCollection(collectionName).listIndexes();
        //上面的list不能直接获取size,因此初始化arrayList就不设置初始化大小了
        List<String> indexes = new ArrayList<>();
        for (Document document : list) {
            document.entrySet().forEach((key) -> {
                //提取出索引的名称
                if (key.getKey().equals("name")) {
                    indexes.add(key.getValue().toString());
                }
            });
        }
        return indexes;
    }

    /**
     * 创建索引
     *
     * @param collectionName
     * @param filedName      [默认升序索引]
     * @return String 索引名
     */
    public String createIndex(String collectionName, String filedName) {
        // TODO:检查是否已经有索引 getAllIndexes
        //该参数为索引的属性配置
        IndexOptions indexOptions = new IndexOptions();
        // 后台进行索引的创建
        indexOptions.background(true);
        indexOptions.name(INDEX_PREFIX + filedName);

        return mongoTemplate.getCollection(collectionName).createIndex(Indexes.ascending(filedName), indexOptions);
    }

    /**
     * 创建复合索引
     *
     * @param collectionName
     * @param filedNames     [默认升序索引]
     * @return String 索引名
     */
    public String createIndex(String collectionName, List<String> filedNames) {
        // TODO:检查是否已经有索引 getAllIndexes
        //该参数为索引的属性配置
        IndexOptions indexOptions = new IndexOptions();
        // 后台进行索引的创建
        indexOptions.background(true);
        indexOptions.name(INDEX_PREFIX + filedNames.stream().collect(Collectors.joining("_")));

        return mongoTemplate.getCollection(collectionName).createIndex(Indexes.ascending(filedNames), indexOptions);
    }

}

MongoTemplateDemoTest

单元测试类,用来测试 MongoTemplateDemo 的方法。
大致描述下测试的方法

insertOneTest 插入一条数据

库中可查到数据:

{
    "_id": "1234567890",
    "name": "jason",
    "age": NumberInt("25"),
    "sex": "男"
}
insertManyTest

库中可查到数据:

{
    "_id": "1234567891",
    "name": "jason",
    "age": NumberInt("25"),
    "sex": "男"
}

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女"
}

findTestTest

控制台数据输出 _id = 1234567890 的文档。
Document{{_id=1234567890, name=jason, age=25, sex=男}}

findBySexTestTest

控制台数据输出 sex = 男 的文档。
Document{{_id=1234567890, name=jason, age=25, sex=男}}
Document{{_id=1234567891, name=jason, age=25, sex=男}}

findManyWithFieldTest

控制台数据输出 sex = 男 的文档。[仅显示 age 字段]
Document{{age=25}}
Document{{age=25}}

findManyWithPageTest

控制台数据输出前 5 条数据[示例只有 3 条],可结合批量生成测试数据的方法测试。
Document{{_id=1234567890, name=jason, age=25, sex=男}}
Document{{_id=1234567891, name=jason, age=25, sex=男}}
Document{{_id=1234567892, name=花花, age=22, sex=女}}

findManyWithInTest

控制台数据输出 _id in(1234567890, 1234567891,1234567892) 的文档(案例中所有数据)。
Document{{_id=1234567890, name=jason, age=25, sex=男}}
Document{{_id=1234567891, name=jason, age=25, sex=男}}
Document{{_id=1234567892, name=花花, age=22, sex=女}}

findManyWithOrTest

控制台数据输出 sex = 男 or age = 22 的文档(案例中所有数据)。
Document{{_id=1234567890, name=jason, age=25, sex=男}}
Document{{_id=1234567891, name=jason, age=25, sex=男}}
Document{{_id=1234567892, name=花花, age=22, sex=女}}

findManyWithGtTest

控制台数据输出 age > 21 and age < 24 的文档。
Document{{_id=1234567892, name=花花, age=22, sex=女}}

findManyWithPatternTest

控制台数据输出 name like '%花%'' 的文档。
Document{{_id=1234567892, name=花花, age=22, sex=女}}

countTest

控制台数据输出 sex = 男 的合计。
输出 2

updateOneTest

修改 _id = 1234567891 的 age = 1
修改前数据:

{
    "_id": "1234567891",
    "name": "jason",
    "age": NumberInt("25"),
    "sex": "男"
}

修改后数据:

{
    "_id": "1234567891",
    "name": "jason",
    "age": NumberInt("1"),
    "sex": "男"
}
updateManyTest

修改 name = jason 的 age = 26
修改前数据:

{
    "_id": "1234567890",
    "name": "jason",
    "age": NumberInt("25"),
    "sex": "男"
}

{
    "_id": "1234567891",
    "name": "jason",
    "age": NumberInt("1"),
    "sex": "男"
}

修改后数据:

{
    "_id": "1234567890",
    "name": "jason",
    "age": NumberInt("26"),
    "sex": "男"
}

{
    "_id": "1234567891",
    "name": "jason",
    "age": NumberInt("26"),
    "sex": "男"
}
updateOneInObjectTest

修改 _id = 1234567892 的数据,$set university 的键值。
修改前数据:

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女"
}

修改后数据:

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女",
    "university": {
        "name": "SZU",
        "address": "SZ"
    }
}
updateOnePushListTest

修改 name = BAT 的数据,插入 workExperience 的文档 。
修改前数据:

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女",
    "university": {
        "name": "SZU",
        "address": "SZ"
    }
}

修改后数据:

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女",
    "university": {
        "name": "SZU",
        "address": "SZ"
    },
    "workExperience": [
        {
            "startDate": "2013-09",
            "endDate": "2017-09",
            "address": "SZ",
            "name": "BAT"
        }
    ]
}
updateOneInListTest

修改 workExperience.name = BAT 的 workExperience.$.address = SZ.NS 。[案例只有一条]
修改前数据:

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女",
    "university": {
        "name": "SZU",
        "address": "SZ"
    },
    "workExperience": [
        {
            "startDate": "2013-09",
            "endDate": "2017-09",
            "address": "SZ",
            "name": "BAT"
        }
    ]
}

修改后数据:

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女",
    "university": {
        "name": "SZU",
        "address": "SZ"
    },
    "workExperience": [
        {
            "startDate": "2013-09",
            "endDate": "2017-09",
            "address": "SZ.NS",
            "name": "BAT"
        }
    ]
}
replaceOne

替换 _id = 1234567891 的文档数据。
修改前数据:

{
    "_id": "1234567891",
    "name": "jason",
    "age": NumberInt("26"),
    "sex": "男"
}

修改后数据:

{
    "_id": "1234567891",
    "name": "replace name",
    "age": NumberInt("22"),
    "sex": "女"
}
removeOne

删除 _id = 1234567890 的文档数据。
修改前数据:

{
    "_id": "1234567890",
    "name": "jason",
    "age": NumberInt("26"),
    "sex": "男"
}

修改后数据:

// 空文档
{
}
removeMany

删除 _id in (1234567891,1234567892) 的文档数据。
修改前数据:

{
    "_id": "1234567891",
    "name": "replace name",
    "age": NumberInt("22"),
    "sex": "女"
}

{
    "_id": "1234567892",
    "name": "花花",
    "age": NumberInt("22"),
    "sex": "女",
    "university": {
        "name": "SZU",
        "address": "SZ"
    },
    "workExperience": [
        {
            "startDate": "2013-09",
            "endDate": "2017-09",
            "address": "SZ.NS",
            "name": "BAT"
        }
    ]
}

修改后数据:

// 空文档
{
}
代码
class MongoTemplateDemoTest {

    @Autowired
    private MongoTemplateDemo mongoTemplateDemo;

    // test_template
    private String collectionName = "test_template";

    /**
     * 插入一条数据
     */
    @Test
    void insertOneTest() {
        Document document = new Document();
        document.put("_id", "1234567890");
        document.put("name", "jason");
        document.put("age", 25);
        document.put("sex", "男");
        mongoTemplateDemo.insertOne(collectionName, document);
    }

    /**
     * 插入多条数据
     */
    @Test
    void insertManyTest() {
        Document document = new Document();
        document.put("_id", "1234567891");
        document.put("name", "jason");
        document.put("age", 25);
        document.put("sex", "男");
        Document document2 = new Document();
        document2.put("_id", "1234567892");
        document2.put("name", "花花");
        document2.put("age", 22);
        document2.put("sex", "女");
        List<Document> list = new ArrayList<>();
        list.add(document);
        list.add(document2);
        mongoTemplateDemo.insertMany(collectionName, list);

    }

    /**
     * 查询符合条件的一条数据
     */
    @Test
    void findTest() {
        Document document = new Document();
        document.put("_id", "1234567890");
        //document.put("name","花花");
        FindIterable<Document> iterable = mongoTemplateDemo.find(collectionName, document);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
            //System.out.println(result.toJson());
        }
    }

    /**
     * 查询符合条件的多条数据
     */
    @Test
    void findBySexTest() {

        Document document = new Document();
        document.put("sex", "男");
        FindIterable<Document> iterable = mongoTemplateDemo.find(collectionName, document);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }

    /**
     * 查询符合条件的数据,指定返回字段
     */
    @Test
    public void findManyWithFieldTest() {
        Document document = new Document();
        document.put("sex", "男");
        Document fieldDocument = new Document();
        fieldDocument.put("_id", false);
        fieldDocument.put("age", true);
        FindIterable<Document> iterable = mongoTemplateDemo.find(collectionName, document, fieldDocument);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }

    /**
     * 查询多条数据,分页
     */
    @Test
    public void findManyWithPageTest() {
        Document document = new Document();
        FindIterable<Document> iterable = mongoTemplateDemo.findPage(collectionName, document, 0, 5);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }

    /**
     * $in 查询
     * 反向 $nin
     */
    @Test
    public void findManyWithInIdTest() {
        Document document = new Document();
        document.put("_id", new Document().append("$in", Arrays.asList("1234567890", "1234567891", "1234567892")));
        FindIterable<Document> iterable = mongoTemplateDemo.find(collectionName, document);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }

    /**
     * or 查询
     */
    @Test
    public void findManyWithOrTest() {
        Document document1 = new Document();//条件1
        document1.put("sex", "男");
        Document document2 = new Document();//条件2
        document2.put("age", 22);
        Document dbObject = new Document();
        dbObject.put("$or", Arrays.asList(document1, document2));//组合
        FindIterable iterable = mongoTemplateDemo.find(collectionName, dbObject);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }

    /**
     * $gt:大于
     * $lt:小于
     * $gte:大于等于
     * $lte:小于等于
     * $ne:不等于
     */
    @Test
    public void findManyWithGtTest() {
        Document document = new Document();
        //document.put("age" , new Document().append("$gt",21));
        document.put("age", new Document().append("$gt", 21).append("$lt", 24));
        FindIterable iterable = mongoTemplateDemo.find(collectionName, document);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }


    /**
     * 模糊查询
     * mongodb用的是正则表达式来进行模糊查询的
     * <p>
     * Spring中不区分大小写的模糊查询:
     * //完全匹配
     * Pattern pattern = Pattern.compile("^花$", Pattern.CASE_INSENSITIVE);
     * //右匹配
     * Pattern pattern = Pattern.compile("^.*花$", Pattern.CASE_INSENSITIVE);
     * //左匹配
     * Pattern pattern = Pattern.compile("^花.*$", Pattern.CASE_INSENSITIVE);
     * //模糊匹配
     * Pattern pattern = Pattern.compile("^.*花.*$", Pattern.CASE_INSENSITIVE);
     */
    @Test
    public void findManyWithPatternTest() {
        String name = "花";
        Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
        Document document = new Document();
        document.put("name", pattern);
        FindIterable iterable = mongoTemplateDemo.find(collectionName, document);
        MongoCursor<Document> mongoCursor = iterable.iterator();
        while (mongoCursor.hasNext()) {
            Document result = mongoCursor.next();
            System.out.println(result);
        }
    }

    /**
     * 统计条数
     */
    @Test
    void countTest() {
        Document document = new Document();
        document.put("sex", "男");
        long count = mongoTemplateDemo.count(collectionName, document);
        System.out.println(count);
    }

    /**
     * 更新一条数据
     */
    @Test
    void updateOneTest() {
        Document document = new Document();
        document.put("_id", "1234567891");
        Document updateDocument = new Document();
        updateDocument.put("age", 1);
        Document setDocument = new Document();
        setDocument.put("$set", updateDocument);
        mongoTemplateDemo.updateOne(collectionName, document, setDocument);
    }

    /**
     * 更新多条数据
     */
    @Test
    void updateManyTest() {
        Document document = new Document();
        document.put("name", "jason");
        Document updateDocument = new Document();
        updateDocument.put("age", 26);
        Document setDocument = new Document();
        setDocument.put("$set", updateDocument);
        mongoTemplateDemo.updateMany(collectionName, document, setDocument);
    }

    /**
     * 修改一条数据 修改文档中的对象
     */
    @Test
    public void updateOneInObjectTest() {
        Document document = new Document();
        document.put("_id", "1234567892");
        Document updateDocument = new Document();
        updateDocument.put("name", "SZU");
        updateDocument.put("address", "SZ");
        Document setDocument = new Document();
        setDocument.put("$set", new Document().append("university", updateDocument));
        mongoTemplateDemo.updateOne(collectionName, document, setDocument);
    }

    /**
     * 向数组中添加一个对象
     * 也是更新文档的内容 所以算update
     */
    @Test
    public void updateOnePushListTest() {
        Document document = new Document();
        document.put("_id", "1234567892");//查询条件

        Document pushDocument = new Document();//要插入的内容
        pushDocument.put("startDate", "2013-09");
        pushDocument.put("endDate", "2017-09");
        pushDocument.put("address", "SZ");
        pushDocument.put("name", "BAT");

        Document updateDocument = new Document();//要插入哪个list
        updateDocument.put("workExperience", pushDocument);

        Document setDocument = new Document();
        setDocument.put("$push", updateDocument);//操作

        mongoTemplateDemo.updateOne(collectionName, document, setDocument);
    }

    /**
     * 修改一条数据 修改文档数组中的对象
     */
    @Test
    public void updateOneInListTest() {
        Document document = new Document();
        //document.put("_id", "1234567892");

        Document elemMatchDocument = new Document();
        elemMatchDocument.put("name", "BAT");
        document.put("workExperience", new Document().append("$elemMatch", elemMatchDocument));
        //Document result=documentQueryDao.findOne(document); 查询符合条件的数组
        //以上为查询条件
        Document updateDocument = new Document();
        updateDocument.put("workExperience.$.address", "SZ.NS");
        Document setDocument = new Document();
        setDocument.put("$set", updateDocument);
        mongoTemplateDemo.updateOne(collectionName, document, setDocument);
    }


    /**
     * replace 替换:
     * 把符合条件的document换成replaceDocument
     * 不管以前document以前的内容是什么,
     * 替换之后
     * replaceDocument是什么 数据库里面就是什么。
     * 这样理解:就是把符合条件的document删除,插入replaceDocument。
     */
    @Test
    void replaceOne() {
        Document document = new Document();
        document.put("_id", "1234567891");
        Document replaceDocument = new Document();
        replaceDocument.put("name", "replace name");
        replaceDocument.put("age", 22);
        replaceDocument.put("sex", "女");
        mongoTemplateDemo.replaceOne(collectionName, document, replaceDocument);
    }


    /**
     * 删除一条数据
     */
    @Test
    void removeOne() {
        Document document = new Document();
        document.put("_id", "1234567890");
        mongoTemplateDemo.removeOne(collectionName, document);
    }

    /**
     * 删除多条数据
     */
    @Test
    void removeMany() {
        Document document = new Document();
        document.put("_id", new Document().append("$in", Arrays.asList("1234567891", "1234567892")));
        mongoTemplateDemo.removeMany(collectionName, document);
    }
}

下偏文章将继续封装演示一些高级的功能

备注:个人博客同步至简书。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • 摘要:开始前,建议大家去了解以下文章,当然不看也没问题: MongoDB从入门到“精通”之简介和如何安装 Mong...
    暖夏未眠丶阅读 730评论 0 2
  • MongoDB讲义 为0 何要学习MongoDB 灵活的数据模型 MongoDB的文档数据模型使开发人员和数...
    小虎_9f76阅读 425评论 1 3
  • 本文包括以下几个方面: –安全措施 – 部署架构 – 系统优化 – 索引设计 – 备份监控 – 模式设计 – 程序...
    张伟科阅读 3,959评论 0 9
  • 前言 1、为什么要使用mongodb?image.png 2、什么场景下使用mongdb?应用不需要事务及复杂 j...
    jackcooper阅读 1,019评论 0 4
  • java.lang.Object类是所有类的父类(又叫根类,超类,基类),它里面写了所有子类应该具有的共同功能,为...
    zexiongweng阅读 491评论 0 1