Mongo结合Spring、监控性能数据、Redis持久化

本文介绍了MongoDB的创建删除数据库、集合操作、文档插入与查询,以及如何利用MongoDB存储性能监控数据。同时,讲解了Redis的RDB和AOF两种持久化机制,分析了各自的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MongoDB简介

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

MongoDB创建删除数据库

MongoDB使用 use DATABASE_NAME 命令来创建数据库。如果指定的数据库DATABASE_NAME不存在,则该命令将创建一个新的数据库,否则返回现有的数据库。

创建

use 命令

MongoDB使用 use DATABASE_NAME 命令来创建数据库。如果指定的数据库DATABASE_NAME不存在,则该命令将创建一个新的数据库,否则返回现有的数据库。

语法

use DATABASE 语句的基本语法如下 -

use DATABASE_NAME

示例

如果要创建一个名称为<newdb>的数据库,那么使用 use DATABASE 语句将如下所示:

> use newdb
switched to db newdb

要检查当前选择的数据库,请使用 db 命令 -

>db
newdb

如果要检查数据库列表,请使用命令:show dbs

>show dbs
local     0.000025GB
test      0.00002GB

创建的数据库(newdb)不在列表中。要显示数据库,需要至少插入一个文档,空的数据库是不显示出来的。

>db.items.insert({"name":"yiibai tutorials"})
>show dbs
local     0.00005GB
test      0.00002GB
newdb      0.00002GB

在 MongoDB 中默认数据库是:test。 如果您还没有创建过任何数据库,则集合/文档将存储在test数据库中。

删除

db.dropDatabase() 方法

MongoDB中的 db.dropDatabase()命令用于删除现有的数据库。

db.dropDatabase()

这将删除当前所选数据库。 如果没有选择任何数据库,那么它将删除默认的’test‘数据库。

示例

首先,使用命令show dbs检查可用数据库的列表。

>show dbs
local      0.00025GB
newdb       0.0002GB
test       0.00012GB

如果要删除新数据库<newdb>,那么dropDatabase()命令将如下所示:

>use newdb
switched to db newdb
>db.dropDatabase()
>{ "dropped" : "newdb", "ok" : 1 }

现在检查数据库列表,如下 -

>show dbs
local      0.00025GB
test       0.0002GB

创建集合

createCollection()方法

MongoDB 的 db.createCollection(name,options) 方法用于在MongoDB 中创建集合。

语法

createCollection()命令的基本语法如下 -

db.createCollection(name, options)

在命令中,name 是要创建的集合的名称。 options是一个文档,用于指定集合的配置。

参数类型描述
nameString要创建的集合的名称
optionsDocument(可选)指定有关内存大小和索引的选项

options参数是可选的,因此只需要指定集合的名称。 以下是可以使用的选项列表:

字段类型描述
cappedBoolean(可选)如果为true,则启用封闭的集合。上限集合是固定大小的集合,它在达到其最大大小时自动覆盖其最旧的条目。 如果指定true,则还需要指定size参数。
autoIndexIdBoolean(可选)如果为true,则在_id字段上自动创建索引。默认值为false
size数字(可选)指定上限集合的最大大小(以字节为单位)。 如果cappedtrue,那么还需要指定此字段的值。
max数字(可选)指定上限集合中允许的最大文档数。

在插入文档时,MongoDB首先检查上限集合capped字段的大小,然后检查max字段。

例子

没有使用选项的createCollection()方法的基本语法如下 -

>use test
switched to db test
>db.createCollection("mycollection")
{ "ok" : 1 }

可以使用命令show collections检查创建的集合。

>show collections
mycollection

以下示例显示了createCollection()方法的语法,其中几个重要选项 -

> db.createCollection("mycol", {capped : true, autoIndexId : true, size : 6142800, max : 10000 })
{ "ok" : 1 }

在 MongoDB 中,不需要创建集合。当插入一些文档时,MongoDB 会自动创建集合。

>db.newcollection.insert({"name" : "yiibaitutorials"})
>show collections
mycol
newcollection
mycollection

删除集合

drop()方法

MongoDB 的 db.collection.drop() 用于从数据库中删除集合。

语法

drop()命令的基本语法如下 -

db.COLLECTION_NAME.drop()

示例

首先,检查数据库 test 中可用的集合。

>use test
switched to db test
> show collections
mycol
mycollection
newcollection

现在删除名称为 mycollection 的集合。

>db.mycollection.drop()
true

再次检查当前数据库的集合列表,如下 -

> show collections
mycol
newcollection

如果选定的集合成功删除,drop()方法将返回true,否则返回false

插入文档

insert()方法

要将数据插入到 MongoDB 集合中,需要使用 MongoDB 的 insert()save()方法。

语法

insert()命令的基本语法如下:

>db.COLLECTION_NAME.insert(document)

示例

>db.mycol.insert({
   _id: 100,
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by: 'yiibai tutorials',
   url: 'http://www.yiibai.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100,
})

这里mycol是集合的名称,在前一章中所创建的。如果数据库中不存在集合,则MongoDB将创建此集合,然后将文档插入到该集合中。

在插入的文档中,如果不指定_id参数,那么 MongoDB 会为此文档分配一个唯一的ObjectId。

_id为集合中的每个文档唯一的12个字节的十六进制数。 12字节划分如下 -

_id: ObjectId(4 bytes timestamp, 3 bytes machine id, 2 bytes process id, 3 bytes incrementer)

要在单个查询中插入多个文档,可以在insert()命令中传递文档数组。如下所示 -

> db.mycol.insert([
   {
      _id: 101,
      title: 'MongoDB Guide', 
      description: 'MongoDB is no sql database',
      by: 'yiibai tutorials',
      url: 'http://www.yiibai.com',
      tags: ['mongodb', 'database', 'NoSQL'],
      likes: 100
   },

   {
      _id: 102,
      title: 'NoSQL Database', 
      description: "NoSQL database doesn't have tables",
      by: 'yiibai tutorials',
      url: 'http://www.yiibai.com',
      tags: ['mongodb', 'database', 'NoSQL'],
      likes: 210, 
      comments: [
         {
            user:'user1',
            message: 'My first comment',
            dateCreated: new Date(2017,11,10,2,35),
            like: 0 
         }
      ]
   },
   {
      _id: 104,
      title: 'Python Quick Guide', 
      description: "Python Quick start ",
      by: 'yiibai tutorials',
      url: 'http://www.yiibai.com',
      tags: ['Python', 'database', 'NoSQL'],
      likes: 30, 
      comments: [
         {
            user:'user1',
            message: 'My first comment',
            dateCreated: new Date(2018,11,10,2,35),
            like: 590 
         }
      ]
   }
])

要插入文档,也可以使用db.post.save(document)。 如果不在文档中指定_id,那么save()方法将与insert()方法一样自动分配ID的值。如果指定_id,则将以save()方法的形式替换包含_id的文档的全部数据。

其它插入文档的方法

db.collection.insertOne()方法

db.collection.insertOne()方法将单个文档插入到集合中。以下示例将新文档插入到库存集合中。 如果文档没有指定_id字段,MongoDB会自动将_id字段与ObjectId值添加到新文档。

db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

db.collection.insertOne()方法返回包含新插入的文档的`_id```字段值的文档。

执行结果如下 -

> db.inventory.insertOne(
...    { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
... )
{
        "acknowledged" : true,
        "insertedId" : ObjectId("5955220846be576f199feb55")
}

db.collection.insertMany()方法

db.collection.insertMany()方法将多个文档插入到集合中,可将一系列文档传递给db.collection.insertMany()方法。以下示例将三个新文档插入到库存集合中。如果文档没有指定_id字段,MongoDB会向每个文档添加一个ObjectId值的_id字段。

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

insertMany()返回包含新插入的文档_id字段值的文档。执行结果如下 -

> db.inventory.insertMany([
...    { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
...    { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
...    { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
... ])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("59552c1c46be576f199feb56"),
                ObjectId("59552c1c46be576f199feb57"),
                ObjectId("59552c1c46be576f199feb58")
        ]
}

查询文档

find()方法

要从MongoDB集合查询数据,需要使用MongoDB的find()方法。

语法

find()命令的基本语法如下:

>db.COLLECTION_NAME.find(document)

find()方法将以非结构化的方式显示所有文档。

pretty()方法

要以格式化的方式显示结果,可以使用pretty()方法。

语法

> db.mycol.find().pretty()

示例

>db.mycol.find().pretty()
{
   "_id": 100,
   "title": "MongoDB Overview", 
   "description": "MongoDB is no sql database",
   "by": "yiibai tutorials",
   "url": "http://www.yiibai.com",
   "tags": ["mongodb", "database", "NoSQL"],
   "likes": "100"
}

除了find()方法外,还有一个findOne()方法,它只返回一个文档。

MongoDB 与 RDBMS的等效 Where 子句

要在一些条件的基础上查询文档,可以使用以下操作。

操作语法示例RDBMS等效语句
相等{<key>:<value>}db.mycol.find({"by":"yiibai"}).pretty()where by = 'yiibai'
小于{<key>:{$lt:<value>}}db.mycol.find({"likes":{$lt:50}}).pretty()where likes < 50
小于等于{<key>:{$lte:<value>}}db.mycol.find({"likes":{$lte:50}}).pretty()where likes <= 50
大于{<key>:{$gt:<value>}}db.mycol.find({"likes":{$gt:50}}).pretty()where likes > 50
大于等于{<key>:{$gte:<value>}}db.mycol.find({"likes":{$gte:50}}).pretty()where likes >= 50
不等于{<key>:{$ne:<value>}}db.mycol.find({"likes":{$ne:50}}).pretty()where likes != 50

下面我们将对上表中的所有操作演示 -

MongoDB中的AND操作符

语法

find()方法中,如果通过使用’‘将它们分开传递多个键,则 MongoDB 将其视为AND条件。 以下是AND的基本语法 -

>db.mycol.find(
   {
      $and: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

示例

以下示例将显示由“yiibai tutorials”编写并且标题为“MongoDB Overview”的所有教程。

> db.mycol.find({$and:[{"by":"yiibai tutorials"},{"title": "MongoDB Overview"}]}).pretty()
{
        "_id" : 100,
        "title" : "MongoDB Overview",
        "description" : "MongoDB is no sql database",
        "by" : "yiibai tutorials",
        "url" : "http://www.yiibai.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}

对于上面给出的例子,等效的SQL where子句是 -

SELECT * FROM mycol where by ='yiibai tutorials' AND title ='MongoDB Overview'

可以在find子句中传递任意数量的键值。

MongoDB中的OR操作符

语法

在要根据OR条件查询文档,需要使用$or关键字。 以下是OR条件的基本语法 -

>db.mycol.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

示例

以下示例将显示由“yiibai tutorials”编写或标题为“MongoDB Overview”的所有教程。

>db.mycol.find({$or:[{"by":"yiibai tutorials"},{"title": "MongoDB Overview"}]}).pretty()
{
   "_id": 100,
   "title": "MongoDB Overview", 
   "description": "MongoDB is no sql database",
   "by": "yiibai tutorials",
   "url": "http://www.yiibai.com",
   "tags": ["mongodb", "database", "NoSQL"],
   "likes": "100"
}

使用 AND 和 OR 条件一起

示例

以下示例将显示likes大于10以及标题是“MongoDB Overview”或者“yiibai tutorials”的所有文档。 等价SQL where子句为 -

SELECT * FROM mycol where likes> 10 AND(by ='yiibai tutorials' OR title ='MongoDB Overview')


SQL
>db.mycol.find({"likes": {$gt:10}, $or: [{"by": "yiibai tutorials"},
   {"title": "MongoDB Overview"}]}).pretty()
{
   "_id": 100,
   "title": "MongoDB Overview", 
   "description": "MongoDB is no sql database",
   "by": "yiibai tutorials",
   "url": "http://www.yiibai.com",
   "tags": ["mongodb", "database", "NoSQL"],
   "likes": "100"
}

查询嵌入/嵌套文档

这里演示如何使用:db.collection.find()方法对嵌入/嵌套文档的查询操作的示例。 此页面上的示例使用inventory集合。要填充库存(inventory)集合以准备一些数据,请运行以下命令:

db.inventory.insertMany( [
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);

匹配嵌入/嵌套文档

要在作为嵌入/嵌套文档的字段上指定相等条件,请使用查询过滤器文档{<field>:<value>},其中<value>是要匹配的文档。

例如,以下查询选择字段size等于{ h: 14, w: 21, uom: "cm" }的所有文档:

db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )

整个嵌入式文档中的相等匹配需要精确匹配指定的<value>文档,包括字段顺序。
例如,以下查询与库存(inventory)集合中的任何文档不匹配:

db.inventory.find(  { size: { w: 21, h: 14, uom: "cm" } }  )

查询嵌套字段

要在嵌入/嵌套文档中的字段上指定查询条件,请使用点符号(“field.nestedField”)。

在嵌套字段上指定等于匹配

以下示例选择在size字段中嵌套的字段uom等于“in”的所有文档:

db.inventory.find( { "size.uom": "in" } )

使用查询运算符指定匹配

查询过滤器文档可以使用查询运算符来指定,如以下形式的条件:

{ <field1>: { <operator1>: <value1> }, ... }

以下查询使用size字段中嵌入的字段h中的小于运算符($lt):

db.inventory.find( { "size.h": { $lt: 15 } } )

指定AND条件

以下查询选择嵌套字段h小于15的所有文档,嵌套字段uom等于“in”,status字段等于“D”:

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

更新文档

MongoDB的update()save()方法用于将集合中的文档更新。update()方法更新现有文档中的值,而save()方法使用save()方法中传递的文档数据替换现有文档。

MongoDB Update()方法

update()方法更新现有文档中的值。

语法

update()方法的基本语法如下 -

> db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)

示例

考虑mycol集合具有以下数据 -

> db.mycol.find({}, {'_id':1, 'title':1})
{ "_id" : 100, "title" : "MongoDB Overview" }
{ "_id" : 101, "title" : "MongoDB Guide" }
{ "_id" : 102, "title" : "NoSQL Database" }
{ "_id" : 104, "title" : "Python Quick Guide" }

以下示例将为标题为“MongoDB Overview”的文档设置为“New Update MongoDB Overview”。

> db.mycol.find({'title':'MongoDB Overview'},{'_id':1, 'title':1})
{ "_id" : 100, "title" : "MongoDB Overview" }
> # 更新操作
> db.mycol.update({'title':'MongoDB Overview'},{$set:{'title':'New Update MongoDB Overview'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> # 查询更新后的结果 -
> db.mycol.find({'_id':100},{'_id':1, 'title':1})
{ "_id" : 100, "title" : "New Update MongoDB Overview" }

默认情况下,MongoDB只会更新一个文档。要更新多个文档,需要将参数’multi‘设置为true

>db.mycol.update({'title':'MongoDB Overview'},
   {$set:{'title':'New Update MongoDB Overview'}},{multi:true})

MongoDB Save()方法

save()方法使用save()方法中传递的文档数据替换现有文档。

语法

MongoDB save()方法的基本语法如下所示:

>db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA})

以下示例将_id100 的文档使用新的文档替换。

db.mycol.save(
   {
      "_id" : 100, "title":"Update By Save()Method.", "by":"biuaxia.com"
   }
)

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

db.mycol.find({'_id':100}, {'_id':1, 'title':1})
{ "_id" : 100, "title" : "Update By Save()Method." }

删除文档

remove()方法

MongoDB中的 remove()方法用于从集合中删除文档。 remove()方法接受两个参数。 一个是删除条件,第二个是标志:justOne

  • criteria - (可选)符合删除条件的集合将被删除。
  • justOne - (可选)如果设置为true1,则只删除一个文档。

语法

remove()方法的基本语法如下 -

>db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)

假设mycol集合具有以下数据。

> db.mycol.find({}, {'_id':1, 'title':1})
{ "_id" : 101, "title" : "MongoDB Guide" }
{ "_id" : 102, "title" : "NoSQL Database" }
{ "_id" : 104, "title" : "Python Quick Guide" }
{ "_id" : 100, "title" : "Update By Save()Method." }

以下示例将删除_id为“100”的文档。

> db.mycol.find({}, {'_id':1, 'title':1})
{ "_id" : 101, "title" : "MongoDB Guide" }
{ "_id" : 102, "title" : "NoSQL Database" }
{ "_id" : 104, "title" : "Python Quick Guide" }
{ "_id" : 100, "title" : "Update By Save()Method." }
>
> db.mycol.remove({'_id':100})
WriteResult({ "nRemoved" : 1 })
> db.mycol.find({}, {'_id':1, 'title':1})
{ "_id" : 101, "title" : "MongoDB Guide" }
{ "_id" : 102, "title" : "NoSQL Database" }
{ "_id" : 104, "title" : "Python Quick Guide" }

只删除一条文档记录

如果有多条记录,并且只想删除第一条记录,则在remove()方法中设置justOne参数。

>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)

删除所有文档记录

删除所有文档记录,可在remove()方法中设置justOne参数。

如果不指定删除条件,MongoDB 将删除集合中的所有文档。 这相当于SQL的truncate命令。

>db.mycol.remove()
>db.mycol.find()

Java访问mongodb

原生方式对MongoDB操作

package mvc.model.test;

import com.mongodb.*;
import org.junit.Test;

import java.net.UnknownHostException;
import java.util.List;

/**
 * Class Describe:
 * 使用原生MongoDB的一些操作
 * <p>
 * MongoClient相当于建立连接
 * DB相当于库对象
 * DBCollection相当于集合
 * DBObject相当于一行json
 *
 * @author biuaxia
 * @date 2018/11/28
 * @time 14:15
 */
public class MongoDbGetTest {

    @Test
    /**
     * 获取库名
     */
    public void test1() throws UnknownHostException {
        /**
         * 已过时
         * Mongo mongo = new Mongo();
         */
        MongoClient mongo = new MongoClient("localhost");
        List<String> dbs = mongo.getDatabaseNames();
        for (String db : dbs) {
            System.out.println("库:" + db);
        }
        mongo.close();
    }

    @Test
    /**
     * 拿出MongoDB的内容
     */
    public void test2() throws UnknownHostException {
        MongoClient mongo = new MongoClient("localhost");
        DB db = mongo.getDB("test");
        /**
         * 查看集合名
         * db.getCollectionNames()
         */
        //获取dept集合对象
        DBCollection dept = db.getCollection("dept");
        DBCursor cursor = dept.find();
        while (cursor.hasNext()) {
            //DBObject就类似于json对象
            DBObject obj = cursor.next();
            Object no = obj.get("no");
            Object dname = obj.get("dname");
            System.out.println(no + "\t" + dname);
        }
        mongo.close();
    }

    @Test
    /**
     * 写记录/插入数据
     */
    public void test3() throws UnknownHostException {
        MongoClient mongo = new MongoClient("localhost");
        DB db = mongo.getDB("test");
        //获取dept集合对象
        DBCollection dept = db.getCollection("dept");
        //插入数据
        DBObject dbj = new BasicDBObject();
        dbj.put("no", 2);
        dbj.put("dname", "huidong");
        dept.insert(dbj);

        mongo.close();
    }

    @Test
    /**
     * 更新/修改数据
     */
    public void test4() throws UnknownHostException {
        MongoClient mongo = new MongoClient("localhost");
        DB db = mongo.getDB("test");
        //获取dept集合对象
        DBCollection dept = db.getCollection("dept");
        //更新数据
        DBObject q = new BasicDBObject();
        q.put("no", 4);
        DBObject o = new BasicDBObject();
        DBObject n = new BasicDBObject();
        n.put("dname", "巴中");
        o.put("$set", n);
        dept.update(q, o);

        mongo.close();
    }
}

使用mongoTemplate操作MongoDB

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">

    <!--配置工厂-->
    <mongo:db-factory id="mongoDbFactory" dbname="java11" host="localhost" port="27017"></mongo:db-factory>

    <!--配置模板-->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
        <constructor-arg name="mongoConverter" ref="mongoConverter"/>
    </bean>

    <!--转换类型-->
    <!-- 默认Mongodb类型映射 -->
    <bean id="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
        <constructor-arg name="typeKey">
            <null/><!-- 这里设置为空,可以把 spring data mongodb 多余保存的_class字段去掉 -->
        </constructor-arg>
    </bean>

    <!-- 转换器:1、去掉write的_class字段 2、TimestampConverter -->
    <mongo:mapping-converter id="mongoConverter" base-package="mvc.model.util"
                             type-mapper-ref="defaultMongoTypeMapper">
        <mongo:custom-converters>
            <mongo:converter>
                <bean class="mvc.model.util.TimestampConverter"/>
            </mongo:converter>

        </mongo:custom-converters>
    </mongo:mapping-converter>
</beans>
package mvc.model.test;

import mvc.model.bean.Commit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.List;

/**
 * Class Describe:
 * 使用Java    Spring-data-mongo操作MongoDB
 *
 * @author biuaxia
 * @date 2018/11/28
 * @time 14:58
 */
@Component
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:Spring*.xml"})
public class MongoDbTemplateTest {

    @Resource
    private MongoTemplate mongoTemplate;

    @Test
    /**
     * 存放对象到MongoDB
     */
    public void test1() {
        Commit commit = new Commit();
        commit.setCommit_Id(1);
        commit.setUser_Commit("水平锤子");
        commit.setUser_Commits_CreateTime(new Timestamp(System.currentTimeMillis()));
        mongoTemplate.save(commit);
        //如果想存到其它集合而不是commit集合,那么可以使用
        mongoTemplate.save(commit, "User_commit");
    }

    @Test
    /**
     * 读取集合Commit中存放的所有对象
     */
    public void test2() {
        //默认查user库
        List<Commit> commits = mongoTemplate.findAll(Commit.class, "User_commit");
        for (Commit commit : commits) {
            System.out.println(commit);
        }
    }

    @Test
    /**
     * 读取集合Commit中单个满足条件的Commit对象
     */
    public void test3() {
        Query query = new Query(Criteria.where("commit_Id").gt(0));
        List<Commit> commits = mongoTemplate.find(query, Commit.class, "User_commit");
        for (Commit commit : commits) {
            System.out.println(commit);
        }
    }

}

利用MongoDB存储性能监控数据

利用之前的AOP知识,在WatchBean中写入数据

package mvc.model.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;


@Component
@Aspect
public class WatchBean {

    @Resource
    private MongoTemplate mongoTemplate;

    @Around("bean(*Controller)")
    public Object watch(ProceedingJoinPoint pjp) throws Throwable {
        //开始计时
        StopWatch watch = new StopWatch();
        watch.start();
        //调用Controller方法
        Object obj = pjp.proceed();
        //结束计时
        watch.stop();
        //获取目标组件类名
        String className = pjp.getTarget().getClass().getName();
        //获取方法名
        String methodName = pjp.getSignature().getName();
        System.out.println(className + "组件的" + methodName + "方法执行时间:" + watch.getTotalTimeMillis());

        //将性能监控信息写入MongoDB
        Map data = new HashMap();
        data.put("class_name", className);
        data.put("method_name", methodName);
        data.put("execute_time", watch.getTotalTimeMillis());
        mongoTemplate.save(data, "watch_log");
        return obj;
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">

    <!--配置工厂-->
    <mongo:db-factory id="mongoDbFactory" dbname="java11" host="localhost" port="27017"></mongo:db-factory>

    <!--配置模板-->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
        <constructor-arg name="mongoConverter" ref="mongoConverter"/>
    </bean>

    <!--转换类型-->
    <!-- 默认Mongodb类型映射 -->
    <bean id="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
        <constructor-arg name="typeKey">
            <null/><!-- 这里设置为空,可以把 spring data mongodb 多余保存的_class字段去掉 -->
        </constructor-arg>
    </bean>

    <!-- 转换器:1、去掉write的_class字段 2、TimestampConverter -->
    <mongo:mapping-converter id="mongoConverter" base-package="mvc.model.util"
                             type-mapper-ref="defaultMongoTypeMapper">
        <mongo:custom-converters>
            <mongo:converter>
                <bean class="mvc.model.util.TimestampConverter"/>
            </mongo:converter>

        </mongo:custom-converters>
    </mongo:mapping-converter>
</beans>

Redis持久化机制、消息传递

Redis支持RDBAOF两种持久化机制

  • RDB即快照模式,每隔固定的时间后会自动备份,文件后缀为.rdb,规则是900秒1次、300秒10次、60秒10000次则立即备份
  • AOF即日志模式,是指所有的命令行记录以Redis命令请求协议的格式保存为aof文件。

MongoDB默认采用RDB模式,如需开启日志模式则需要修改配置文件redis.conf中的appendonly修改为yes

两种持久化机制总结

RDB持久化

RDB持久化是指用数据集快照的方式记录redis数据库的所有键值对。

两个命令:SAVE命令会阻塞主进程来完成写文件,BGSAVE命令会创建子进程来完成写文件,主进程会继续处理命令。

优点:
  1. 只有一个文件dump.rdb,方便持久化。
  2. 容灾性好,一个文件可以保存到安全的磁盘。
  3. 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。
  4. 相对于数据集大时,比AOF的启动效率更高。
缺点:
  1. 数据安全性低,通过配置save参数来达到定时的写快照,比如 每900 秒有1个键被修改就进行一次快照,每600秒至少有10个键被修改进行快照,每30秒有至少10000个键被修改进行记录。所以如果当服务器还在等待写快照时出现了宕机,那么将会丢失数据。
  2. fork子进程时可能导致服务器停机1秒,数据集太大。

AOF持久化

AOF持久化是指所有的命令行记录以redis命令请求协议的格式保存为aof文件。

优点:
  1. 数据安全,aof持久化可以配置appendfsync属性,有always,每进行一次命令操作就记录到aof文件中一次;everySec,就是每秒内进行一次文件的写操作;no就是不进行aof文件的写操作。
  2. 通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。
  3. AOF机制的rewrite模式,用来将过大的aof文件缩小,实现原理是将所有的set 通过一句set 命令总结,所有的SADD命令用总结为一句,这样每种命令都概括为一句来执行,就可以减少aof文件的大小了。(注意,在重写的过程中,是创建子进程来完成重写操作,主进程每个命令都会在AOF缓冲区和AOF重写缓冲区进行保存,这样旧版aof文件可以实现数据最新,当更新完后将重写缓冲区中的数据写入新的aof文件中然后就可以将新的文件替换掉旧版的文件。
缺点:
  1. 文件会比RDB形式的文件大。
  2. 数据集大的时候,比rdb启动效率低。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值