mongodb java简单使用



1      安装引入



1.1    Jar驱动



mongo对应的java驱动的下载地址



https://github.com/mongodb/mongo-java-driver/downloads



1.2    Marven



<dependency>

<groupId>org.mongodb</groupId>
 
  
 
    <artifactId>mongo-java-driver</artifactId>
 
  
 
    <version>2.9.1</version> 
 
  
 
</dependency>



1.3    文档


API文档的地址
 
 
http://api.mongodb.org/java/
 
 
官方入门地址
 
 
http://www.mongodb.org/display/DOCS/Java+Tutorial
 
 
2      在java中使用
 
 
2.1    java驱动的并发情况
 
 
    mongo db的java驱动是线程安全的,在一个web项目中,可以创建一个Mongo的单例,然后在每次请求时都使用这个单例。该单例会维护一个内部的连接池(默认大小为10),对于每次对DB的请求(find、insert等),java线程都会从连接池中获取一个连接,进行操作,然后释放连接,所以,每次使用的连接可能不总是同一个连接。如果你想一直使用同一个连接,可以用下边这种方式:
 
 
 
 
 
 
 
DBdb...;
 
  
 
db.requestStart();
 
  
 
code....
 
  
 
db.requestDone();
 
  
 
    但是如果最后db.requestDone()没有被调用,该连接不会被交还给线程池,所以,一定要在finally块中调用db.requestDone()。
 
 
    DB和DBCollection都是线程安全的。
 
 
    在默认配置的情况下,每次对DB请求(find、insert等)后,连接会被交还给连接池,你并不知道是否操作成功,这会造成“数据无故丢失”的情况。所以,对于数据安全性比较重要的操作,我们要使用WriteConcern.SAFE模式,这样,驱动会在将连接交还前调用getLastError()方法来校验是否操作成功。示例如下:
 
 
 
 
DBCollectioncoll...;
 
  
 
coll.insert(...,WriteConcern.SAFE);
 
  
 
2.2    数据类型
 
 
1. 正则表达式
 
java驱动使用java.util.regex.Pattern做正则表达式:
 
 
 
 
Pattern john = Pattern.compile("joh?n", CASE_INSENSITIVE);
 
  
 
BasicDBObject query = new BasicDBObject("name", john);
 
  
 
// finds all people with "name" matching /joh?n/i
 
  
 
DBCursor cursor = collection.find(query);
 
  
 
1. 日期、时间
 
java驱动使用java.util.Date做日期
 
 
 
 
Date now = new Date();
 
  
 
BasicDBObject time = new BasicDBObject("ts", now);
 
  
 
collection.save(time);
 
  
 
1. 内嵌文档
 
 
 
 
{ "x" :  {"y" :  3 } }
 
 
上边这种文档结构可以用下边这种方式存储
 
 
 
 
BasicDBObject y = new BasicDBObject("y", 3);
 
  
 
BasicDBObject x = new BasicDBObject("x", y);
 
  
 
 
 
 
(4)数组
 
 
 扩展自List的结构都可以用数组形式存储
 
 
{"x" : [1, 2, {"foo" : "bar"}, 4 ]}
 
 
上边这种结构形式可以用下边这种方式存储
 
 
 
 
ArrayList x = new ArrayList();
 
  
 
x.add(1);
 
  
 
x.add(2);
 
  
 
x.add(new BasicDBObject("foo", "bar"));
 
  
 
x.add(4);
 
  
 
BasicDBObject doc = new BasicDBObject("x", x);
 
  
 
 
 
 
2.3    MongoOptions
 
 
java驱动中,可以在获取mongo实例时,指定一些参数,如下:
 
 
 
 
ServerAddress serverAddress=newServerAddress("127.0.0.1",27017);
 
  
 
 
 
  
 
MongoOptions mongoOptions=new MongoOptions();
 
  
 
Mongo mongo=new Mongo(serverAddress,mongoOptions);
 
  
 
参数列表如下:
 
 
 
 
 
 
 
//控制系统在发生连接错误时是否重试 ,默认为false --boolean
 
  
 
mongoOptions.autoConnectRetry=false;
 
  
 
//每个主机允许的连接数(每个主机的连接池大小),当连接池被用光时,会被阻塞住 ,默认为10 --int
 
  
 
mongoOptions.connectionsPerHost=10;
 
  
 
//设置等待获取连接池连接的最大数,比如,connectionsPerHost 是10,threadsAllowedToBlockForConnectionMultiplier 是5,则最多有50个线程可以等待获取连接 --int
 
  
 
mongoOptions.threadsAllowedToBlockForConnectionMultiplier=5;
 
  
 
//被阻塞线程从连接池获取连接的最长等待时间(ms) --int
 
  
 
mongoOptions.maxWaitTime = 1;
 
  
 
//在建立(打开)套接字连接时的超时时间(ms),默认为0(无限) --int
 
  
 
mongoOptions.connectTimeout=0;
 
  
 
//套接字超时时间;该值会被传递给Socket.setSoTimeout(int)。默认为0(无限) --int
 
  
 
mongoOptions.socketTimeout=0;
 
  
 
//This controls whether or not to have socket keep alive turned on(SO_KEEPALIVE). defaults to false --boolean
 
  
 
mongoOptions.socketKeepAlive=false;
 
  
 
//指明是否允许驱动从次要节点或者奴隶节点读取数据,默认为false --boolean
 
  
 
mongoOptions.slaveOk=false;
 
  
 
//如果为true,驱动每次update后会发出一个getLastError命令来保证成功,默认为false --boolean
 
  
 
mongoOptions.safe=false;
 
  
 
//If set, the w value of WriteConcern for the connection is set to this.Defaults to 0; implies safe = true --int
 
  
 
mongoOptions.w=0;
 
  
 
//If set, the wtimeout value of WriteConcern for the connection isset to this. Defaults to 0; implies safe = true --int
 
  
 
mongoOptions.wtimeout=0;
 
  
 
//Sets the fsync value of WriteConcern for the connection. Defaultsto false; implies safe = true --boolean
 
  
 
mongoOptions.fsync=false;
 
  
 
2.4    ObjectId
 
 
由4部分编码而成:当前时间、机器标识、进程号和自增的整数。
 
 
2.5    排序加翻页
 
 
 
 
collection.find(queryObject).sort(new BasicDBObject().append("pt","-1").append("ct", "1")).skip(10).limit(10);
 
  
 
2.6      操作
 
 
从名为tag的数组中删除值为123的元素
 
 
 
 
BasicDBObject updateObject = newBasicDBObject().append("$pull", newBasicDBObject().append("tag","123"));
 
  
 
//queryObject是查询条件
 
  
 
dbCollection.updateMulti(queryObject, updateObject);
 
  
 
批量从数组中删除元素
 
 
 
 
//从name等于xiaoming的文档中批量删除tag数组中的r521元素  
 
  
 
collection.updateMulti(new BasicDBObject().append("name", "xiaoming"),  new BasicDBObject().append("$pull", new BasicDBObject().append("tag","r521")));  
 
  
 
查询数量,以下三种方式未发现明显性能差别,相对于在mongoVUE里查询,都表现较慢
 
 
 
 
//  方式一  
 
  
 
long count=collection.find(queryObject).count();  
 
  
 
//方式二,可以查询某个字段的数量   
 
  
 
long count=collection.getCount(queryObject,new BasicDBObject().append("_id", 1));  
 
  
 
//方式三  
 
  
 
 long count=collection.count(queryObject);  collection.updateMulti(newBasicDBObject().append("name", "xiaoming"),



2.7    图片文件



存图片文件
 
 
 
 
String newFileName = "mkyong-java-image";
 
  
 
File imageFile = newFile("c:\\JavaWebHosting.png");
 
  
 
GridFS gfsPhoto = new GridFS(db, "photo");
 
  
 
GridFSInputFile gfsFile = gfsPhoto.createFile(imageFile);
 
  
 
gfsFile.setFilename(newFileName);
 
  
 
gfsFile.save();
 
  
 
取图片文件
 
 
 
 
String newFileName = "mkyong-java-image";
 
  
 
GridFS gfsPhoto = new GridFS(db, "photo");
 
  
 
GridFSDBFile imageForOutput =gfsPhoto.findOne(newFileName);
 
  
 
System.out.println(imageForOutput);




打印所有图片

GridFS gfsPhoto = new GridFS(db, "photo");
 
  
 
DBCursor cursor = gfsPhoto.getFileList();
 
  
 
while (cursor.hasNext()) {
 
  
 
    System.out.println(cursor.next());
 
  
 
}



存到另外一个文件中

String newFileName = "mkyong-java-image";
 
  
 
GridFS gfsPhoto = new GridFS(db, "photo");
 
  
 
GridFSDBFile imageForOutput = gfsPhoto.findOne(newFileName);
 
  
 
imageForOutput.writeTo("c:\\JavaWebHostingNew.png");//output to new file



 



删除图片

String newFileName = "mkyong-java-image";
 
  
 
GridFS gfsPhoto = new GridFS(db, "photo");
 
  
 
gfsPhoto.remove(gfsPhoto.findOne(newFileName));