源码地址

springboot2教程系列

Mongodb使用 一下场景

  • 网站数据:Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

  • 缓存:由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由 Mongo 搭建的持久化缓存可以避免下层的数据源过载。

  • 大尺寸,低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。

  • 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库

  • 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档格式化的存储及查询。

不适合的场景

  • 高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复制事物的应用程序。
  • 传统的商业智能应用:针对特定问题的 BI 数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能时更适合的选择(如Hadoop套件中的Hive)。
  • 需要SQL的问题。

springboot2集成

引入依赖

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

添加配置

#myframe和myframe123分别为用户和密码
spring.data.mongodb.uri: mongodb://myframe:myframe123@10.10.2.137:27017/receiver?maxPoolSize=256
# 多个IP集群可以采用以下配置:
#spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database
@Configuration
public class MongodbConfig {

    /**
     * 去除class字段
     * @param factory
     * @param context
     * @param beanFactory
     * @return
     */
    @Bean
    public MappingMongoConverter mappingMongoConverter(
        MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(
            dbRefResolver, context);
        try {
            mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
        } catch (NoSuchBeanDefinitionException ignore) {
        }
        // Don't save _class to mongo
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));

        return mappingConverter;
    }
    
}

业务实现

@Component
public class BusReceiverDaoImp implements BaseDao<BusReceiverEntity> {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void insert(BusReceiverEntity entity) {
        mongoTemplate.save(entity);
    }

    @Override
    public void batchInsert(List<BusReceiverEntity> list) {
        mongoTemplate.insert(list, BusReceiverEntity.class);
    }

    @Override
    public BusReceiverEntity findById(Serializable id) {
        Query query = new Query(Criteria.where("id").is(id));
        BusReceiverEntity ent = mongoTemplate.findOne(query, BusReceiverEntity.class);
        return ent;
    }

    /**
     * 普通分页,逐行扫描,数据多时查询慢
     * @param limit
     * @param pageNo
     * @return
     */
    public List<BusReceiverEntity> findPage(int limit,int pageNo){
        Query query = new Query()
                .skip((pageNo-1)*limit)
                .limit(limit);
        List<BusReceiverEntity> list = mongoTemplate.find(query,BusReceiverEntity.class);
        return list;
    }

    /**
     * 改进分页查询
     * 通过保留上一次查询分布最后一条数据的Id
     * @param limit
     * @param pageNo
     * @param preId
     * @return
     */
    public List<BusReceiverEntity> findPage2(int limit,int pageNo,Serializable preId){
        Query query = new Query(Criteria.where("id").gt(preId));
        query.with(new Sort(Sort.Direction.ASC, "_id"));//排序
        query.limit(limit);
      //  query.add
        List<BusReceiverEntity> list = mongoTemplate.find(query,BusReceiverEntity.class);
        return list;
    }


    @Override
    public void update(BusReceiverEntity entity) {
        Query query = new Query(Criteria.where("_id").is(entity.getId()));
        Update update = new Update()
                .set("name", entity.getName());
        //更新查询返回结果集的第一条
        mongoTemplate.updateFirst(query, update, BusReceiverEntity.class);
    }

    @Override
    public void delete(Serializable id) {
        Query query = new Query(Criteria.where("_id").is(id));
        mongoTemplate.remove(query, BusReceiverEntity.class);
    }
}

mongodb配置文件(/etc/mongod.conf)

systemLog:
   destination: file
   path: /var/log/mongodb/mongod.log
   logAppend: true
storage:
   dbPath: /var/lib/mongo
   directoryPerDB: true                 #默认值:false
   journal:
      enabled: true
processManagement:
   fork: true
net:
   bindIp: 127.0.0.1
   port: 27017
setParameter:
   enableLocalhostAuthBypass: false
storage.dbPath (数据存放)
  • 默认值:/data/db(linux和macOS系统) ,\data\db(window系统)
  • 作用:设置数据存储文件目录
storage.directoryPerDB(分目录)
  • 默认值:false
  • 当为true,mongodb为每个数据库建立一个单独的路径,这个路径是在dbpath下创建的;每次创建需要重启服务器
storage.indexBuildRetry (重建索引)
  • 默认值:true
  • 作用:开启或关闭是否在mongod下次启动重建不完整的索引。
  • 注:在in-memory存储引擎下不可用
storage.engine (存储引擎)
  • 默认值:wiredTiger

  • 可设置:MMAPV1,wiredTiger,inMemory

  • WiredTiger和MMAPv1都用于持久化存储数据,相对而言,WiredTiger比MMAPv1更新,功能更强大。 1, 文档级别的并发控制(Document-Level Concurrency Control) 2,检查点(Checkpoint) 3,预先记录日志(Write-ahead Transaction Log)

详细说明

Mongodb基本命令

进入命令模式:

mongo

数据库操作
查看所有的库
show dbs;
# 用户创建的库,如果没有数据将不显示
创建库
use nias;
删除库
use nias;  --switched to db nias
db.dropDatabase();
删除集合
db.collection.drop();

例子:
use nias;  --switched to db nias
show tables; --receiver 
db.receiver.drop()   --true
用户操作
创建用户
#要进入相应的库里建用户 
use receiver;
db.createUser({
    user: 'rojao',
    pwd: 'Rojao@123',
    roles: [ { role: "readWrite", db: "receiver" } ]
});

mongoDB 没有无敌用户root,只有能管理用户的用户 userAdminAnyDatabase

查看用户是否创建成功
show users;
修改用户密码
db.changeUserPassword('rojao','Rojao123');
验证用户
db.auth('rojao','Rojao123');
集合操作
新增集合
db.createCollection(name, options);

eg.
use nias;                                 --switched to db nias 
db.createCollection("sysuser");           --{ "ok" : 1 }
show collections; 

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

  • capped: (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
  • autoIndexId:(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
  • size: (可选)为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也需要指定该字段。
  • max: (可选)指定固定集合中包含文档的最大数量。
索引

索引的创建 db.collection.createIndex(keys, options)

db.busReceiverEntity.createIndex({"name":1})

#全文索引
db.busReceiverEntity.createIndex({'name':'text'}) #MongoDB的全文索引自带分词功能

查看集合索引

db.col.getIndexes()

eg.
db.busReceiverEntity.getIndexes()
[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_", #索引名字
		"ns" : "receiver.busReceiverEntity"
	}
]

查看集合索引大小

db.col.totalIndexSize()

删除集合所有索引

db.col.dropIndexes()

删除集合指定索引

db.col.dropIndex("索引名称")

强制命中索引

db.busReceiverEntity.find({"name":/鸿禧/}).hint('name_1').count(); #'name_1'为索引名称
插入文档
db.COLLECTION_NAME.insert(document);

db.sysuser.insert({"name":"admin","pwd":"666666"});
查看文档
db.col.find();          #查询了集合 col 中的数据

db.users.find().count();   #查询集合数据条数

db.busReceiverEntity.find().limit(10).skip(100);  #表示从第100条开始取10条
#skip是逐行扫描的,数据多会影响性能
db.busReceiverEntity.find({"_id":{$gt:94900001}}).limit(10);

#查询busReceiverEntity集合中"_id"为79000001,"regionCode"为"226193"的数据
db.busReceiverEntity.find({"_id":79000001,"regionCode":"226193"}).limit(10);

#模糊查询,i为忽略大小写
db.busReceiverEntity.find({"name":{$regex:'景明',$options:'i'}}).count();
{name:/xxx/} #查询包含XXX
{name:/^xxx/}#查询以XXX开头
{name:/xxx^/}#查询以XXX结尾
{name:/xxx/i}#查询忽略大小写

#排序
db.COLLECTION_NAME.find().sort({KEY:1})
修改文档
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

eg.
db.sysuser.update({'name':'admin'},{$set:{'pwd':'123456'}},{multi:true})

save() 方法通过传入的文档来替换已有文档。语法格式如下:

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

更多实例

只更新第一条记录:

db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
全部更新:

db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
只添加第一条:

db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
全部添加进去:

db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
全部更新:

db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
只更新第一条记录:

db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );
Logo

Agent 垂直技术社区,欢迎活跃、内容共建,欢迎商务合作。wx: diudiu5555

更多推荐