MongoDB是一款很典型的NoSql(not only sql)数据库,相比关系型数据库,储存的是json文档,有着大数据量下查询快,易扩容的优点(除了这些,因为不支持事务,感觉还是不能完全替代关系型数据库,可以互补),讲真,我感觉跟ElasticSearch有点像,不过MonoDB跟ElasticSearch比起来就更像关系型数据库。
官网:https://www.mongodb.com/
安装
官网下载地址:https://www.mongodb.com/try/download/community
如上图选择适合自己的版本,并复制地址,这里以ubuntu20.04为例。
下载安装包并解压到安装路径(截止发文前最新版本是4.4.4)
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.4.tgz
tar -zxvf mongodb-linux-x86_64-ubuntu2004-4.4.4.tgz
解压之后把bin目录配置下环境变量(替换成自己的安装路径)
export PATH=/home/zhaohy/myspace/profiles/mongodb-linux-x86_64-ubuntu2004-4.4.4/bin:$PATH
默认下mongodb会用到两个目录,分别是:
数据存储目录:/var/lib/mongodb
日志文件目录:/var/log/mongodb
创建这两个目录并赋予当前用户读写权限(其中的zhaohy是当前用户名,可根据情况替换)
sudo mkdir -p /var/lib/mongo
sudo mkdir -p /var/log/mongodb
sudo chown zhaohy /var/lib/mongo # 设置权限
sudo chown zhaohy /var/log/mongodb # 设置权限
启动mongodb:
mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork
打印出下面日志说明启动成功,默认端口27017:
about to fork child process, waiting until server is ready for connections.
forked process: 15232
child process started successfully, parent exiting
运行日志存储在/var/log/mongodb/mongod.log
连接mongodb
mongodb自带了MongoDB Shell,可以以命令行的形式和数据库交互(它是一个JavaScript shell)
只要在安装路径bin目录下运行
./mongo
下面写几个常用的交互命令
db #显示当前数据库名称,第一次进去默认在test库
show dbs #显示所有的数据库名称,默认有admin,config,local,test四个库
use 库名称 #创建或切换数据库 如use zhaohy 如果没有zhaohy库会创建否则是切换
db.createCollection(集合名) #创建集合,这里的集合类似于关系型数据库里的表
show collections #显示所有集合(表)
db.集合名.insert(json) #给某一个集合插入一个json数据,如果集合不存在会自动创建集合插入,插入之后自动生成一个_id主键,String类型
db.集合名.drop() #删除集合
db.dropDatabase() #删除当前所在数据库
db.collection.update(
<query>,
<update>
) #根据query条件update数据,其中的<query><update>都是json格式,update里要加$set关键字,相当于关系型数据库里的where条件和set字段语句
db.集合名.find().pretty() #查询某个集合下的所有数据并美化好json格式
db.集合名.find(json).pretty() #查询满足json条件的所有数据并美化好json格式,其中的json条件是过滤条件
db.集合名.remove(query条件json) #删除满足条件的记录
关闭数据库服务命令:
mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown
也可以在 mongo 的命令出口中实现:
> use admin
switched to db admin
> db.shutdownServer()
可去菜鸟教程https://www.runoob.com/mongodb/mongodb-operators-type.html看更多用法,聚合,分页,排序,索引,条件都支持,还是很强大的。
数据库查询工具:NoSqlBooster for MongoDB
看了好几个工具,感觉这个NoSqlBooster比较好用,推荐一下,这样就可以在其他机子上直接用ip访问mongodb数据库了,支持win,linux,mac等多个平台
NoSqlBooster下载地址:https://nosqlbooster.com/downloads
下面是运行截图
java调用MongoDB
maven下载(截止发文前最新版本是3.12.8)
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.8</version>
</dependency>
mongodb提供的driver包中包含连接池配置,所以我们可以直接调用,不必再自己写一个连接池了。
新建MongoDbClient.java
package com.zhaohy.app.utils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.mongodb.WriteResult;
public class MongoDbClient {
private MongoClient mongoClient = null;
private static final MongoDbClient mongoDbClient = new MongoDbClient();// 饿汉式单例模式
private MongoDbClient()
{
if (mongoClient == null)
{
MongoClientOptions.Builder buide = new MongoClientOptions.Builder();
buide.connectionsPerHost(100);// 与目标数据库可以建立的最大链接数
buide.connectTimeout(1000 * 60 * 20);// 与数据库建立链接的超时时间
buide.maxWaitTime(100 * 60 * 5);// 一个线程成功获取到一个可用数据库之前的最大等待时间
buide.threadsAllowedToBlockForConnectionMultiplier(100);
buide.maxConnectionIdleTime(0);
buide.maxConnectionLifeTime(0);
buide.socketTimeout(0);
buide.socketKeepAlive(true);
MongoClientOptions myOptions = buide.build();
// try {
// //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
// //ServerAddress()两个参数分别为 服务器地址 和 端口
// ServerAddress serverAddress = new ServerAddress("127.0.0.1",27017, myOptions);
// List<ServerAddress> addrs = new ArrayList<ServerAddress>();
// addrs.add(serverAddress);
//
// //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
// MongoCredential credential = MongoCredential.createScramSha1Credential(null, "zhaohy", null);
// List<MongoCredential> credentials = new ArrayList<MongoCredential>();
// credentials.add(credential);
//
// //通过连接认证获取MongoDB连接
// MongoClient mongoClient = new MongoClient(addrs,credentials);
//
// //连接到数据库
// MongoDatabase mongoDatabase = mongoClient.getDatabase("zhaohy");
// System.out.println("Connect to database successfully");
// } catch (Exception e) {
// System.err.println( e.getClass().getName() + ": " + e.getMessage() );
// }
try
{
mongoClient = new MongoClient(new ServerAddress("127.0.0.1", 27017), myOptions);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
public static MongoDbClient getMongoDbClient()
{
return mongoDbClient;
}
public DB getDb(String dbName)
{
return mongoClient.getDB(dbName);
}
public DBCollection getCollection(String dbName, String collectionName)
{
DB db = mongoClient.getDB(dbName);
return db.getCollection(collectionName);
}
public boolean insert(String dbName, String collectionName, Map<String, Object> testMap)
{
DB db = mongoClient.getDB(dbName);
DBCollection dbCollection = db.getCollection(collectionName);
long num = dbCollection.count();
BasicDBObject doc = new BasicDBObject();
for(String key : testMap.keySet()) {
doc.put(key, testMap.get(key));
}
dbCollection.insert(doc);
if (dbCollection.count() - num > 0)
{
System.out.println("添加数据成功!!!");
return true;
}
return false;
}
public boolean delete(String dbName, String collectionName, String keys, Object values)
{
WriteResult writeResult = null;
DB db = mongoClient.getDB(dbName);
DBCollection dbCollection = db.getCollection(collectionName);
BasicDBObject doc = new BasicDBObject();
doc.put(keys, values);
writeResult = dbCollection.remove(doc);
if (writeResult.getN() > 0)
{
System.out.println("删除数据成功!!!!");
return true;
}
return false;
}
public ArrayList<DBObject> find(String dbName, String collectionName, int num)
{
int count=num;
ArrayList<DBObject> list = new ArrayList<DBObject>();
DB db = mongoClient.getDB(dbName);
DBCollection dbCollection = db.getCollection(collectionName);
DBCursor dbCursor = dbCollection.find();
if (num == -1)
{
while (dbCursor.hasNext())
{
list.add(dbCursor.next());
}
} else
{
while(dbCursor.hasNext())
{
if(count==0) break;
list.add(dbCursor.next());
count--;
}
}
return list;
}
public boolean update(String dbName, String collectionName, DBObject queryValue, DBObject value)
{
WriteResult writeResult = null;
DB db = mongoClient.getDB(dbName);
DBCollection dbCollection = db.getCollection(collectionName);
writeResult = dbCollection.update(queryValue, value);
if (writeResult.getN() > 0)
{
System.out.println("数据更新成功");
return true;
}
return false;
}
public boolean isExit(String dbName, String collectionName, String key, Object value)
{
DB db = mongoClient.getDB(dbName);
DBCollection dbCollection = db.getCollection(collectionName);
BasicDBObject doc = new BasicDBObject();
doc.put(key, value);
if (dbCollection.count(doc) > 0)
{
return true;
}
return false;
}
public static void main(String args[])
{
MongoDbClient client = MongoDbClient.getMongoDbClient();
ArrayList<DBObject> list=new ArrayList<DBObject>();
list = client.find("zhaohy", "t_user",-1);
for(int i = 0; i < list.size(); i++) {
DBObject obj = list.get(i);
System.out.println("_id:" + obj.get("_id") + " name:" + obj.get("name") + " sex:" + obj.get("sex"));
}
System.out.println(JSON.toJSONString(list));
Map<String, Object> testMap = new LinkedHashMap<String, Object>();
testMap.put("name", "test1");
testMap.put("sex", "1");
testMap.put("description", "这是备注");
client.insert("zhaohy", "t_user", testMap);
list = client.find("zhaohy", "t_user",-1);
System.out.println(JSON.toJSONString(list));
DBObject queryObj = new BasicDBObject();
queryObj.put("name", "test1");
DBObject updateObj = new BasicDBObject();
DBObject updateObj1 = new BasicDBObject();
updateObj1.put("description", "test");
updateObj.put("$set", updateObj1);
client.update("zhaohy", "t_user", queryObj, updateObj);
list = client.find("zhaohy", "t_user",-1);
System.out.println(JSON.toJSONString(list));
}
}
如上代码所示,简单封装了增删改查的方法,直接运行main方法打印日志如下:
_id:606038553e560d3c4c6d40ab name:zhaohy sex:1
[{"_id":{"counter":7159979,"date":1616918613000,"machineIdentifier":4085261,"processIdentifier":15436,"time":1616918613000,"timeSecond":1616918613,"timestamp":1616918613},"name":"zhaohy","sex":"1"}]
添加数据成功!!!
[{"_id":{"counter":7159979,"date":1616918613000,"machineIdentifier":4085261,"processIdentifier":15436,"time":1616918613000,"timeSecond":1616918613,"timestamp":1616918613},"name":"zhaohy","sex":"1"},{"_id":{"counter":3929590,"date":1616928344000,"machineIdentifier":11177507,"processIdentifier":7193,"time":1616928344000,"timeSecond":1616928344,"timestamp":1616928344},"name":"test1","sex":"1","description":"这是备注"}]
数据更新成功
[{"_id":{"counter":7159979,"date":1616918613000,"machineIdentifier":4085261,"processIdentifier":15436,"time":1616918613000,"timeSecond":1616918613,"timestamp":1616918613},"name":"zhaohy","sex":"1"},{"_id":{"counter":3929590,"date":1616928344000,"machineIdentifier":11177507,"processIdentifier":7193,"time":1616928344000,"timeSecond":1616928344,"timestamp":1616928344},"name":"test1","sex":"1","description":"test"}]
更复杂的用法可以去看driver的源码,看看那些聚合排序什么的是要怎么用的,不过大方向和命令行的命令差不多,所以掌握了那些命令行的请求方式,java调用大差不差,就是拼json,这里要明确一点,千万不要尝试根据_id去更新某一条数据,因为查询只能根据自己存储进去的json字段,这个自动生成的主键是不能作为条件查询的,反正我没试成功,以后用的时候,还是要生成一个唯一id放进去比较靠谱,ok,先到这里啦,伸懒腰~
参考:https://www.runoob.com/mongodb/mongodb-tutorial.html
http://itpcb.com/a/564146