回到正题记录下熟悉MongoDB为Java语言提供的操作接口mongo-java-driver.jar
1.基本的根基不变,连接数据库
2.基本的数据库操作不变,CRUD
3.变化的是提供的接口,实现类名,操作对象大不相同
4.变化的是没有标准的Java操作MongoDB的标准API
MongoDB提供的Java操作API可以说是对Mongo数据库命令的Java翻译,熟悉Mongo命令,熟悉Java操作数据库的基本思路,很容易掌握基本操作。
-
数据库连接
1234567891011package
com.im;
public
final
class
SystemConstant {
public
static
final
class
Configure {
public
static
final
String HOST =
"127.0.0.1"
;
public
static
final
int
PORT =
27017
;
public
static
final
String USERNAME =
""
;
public
static
final
String PASSWORD =
""
;
public
static
final
String DATABASE =
"im"
;
}
}
123456789101112131415161718192021222324252627package
com.im;
import
java.net.UnknownHostException;
import
com.mongodb.Mongo;
import
com.mongodb.MongoException;
public
class
MongoFactory {
private
static
MongoFactory mongoFactory;
private
MongoFactory() {
}
public
static
MongoFactory getInstance() {
if
(mongoFactory ==
null
) {
mongoFactory =
new
MongoFactory();
}
return
mongoFactory;
}
public
Mongo getMongo() {
Mongo mongo =
null
;
try
{
mongo =
new
Mongo(SystemConstant.Configure.HOST,
SystemConstant.Configure.PORT);
}
catch
(UnknownHostException e) {
e.printStackTrace();
}
catch
(MongoException e) {
e.printStackTrace();
}
return
mongo;
}
}
数据库链接少不了的主机名,端口号,数据库名称。上面代码中的Mongo对象就相当与Connection对象。
-
数据库的操作
下面的每个方法代表一个方面的测试
测试类初始化方法:
12345private
static
BaseDao dao;
@BeforeClass
public
static
void
start() {
dao =
new
BaseDao(
"users"
,
"uf"
);
}
关于BaseDao是对Mongo操作数据库的基本常用的方法做了封装的一个DAO对象,代码会在本文末尾附上。
1
2
3
4
5
6
7
8
9
10
11
|
// 添加一条记录
public
void
test1() {
BasicDBObject jo =
new
BasicDBObject();
jo.put(
"_id"
,
"00001"
);
jo.put(
"name"
,
"Tomcat"
);
jo.put(
"age"
,
22
);
jo.put(
"interest"
,
new
String[] {
"swimming"
,
"Taiji"
,
"football"
});
int
actual = dao.insert(jo);
System.out.println(actual);
Assert.assertEquals(
1
, actual);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 添加多条记录
public
void
test2() {
int
actual =
0
;
int
size =
0
;
for
(
int
i =
2
; i <
11
; i++) {
BasicDBObject jo =
new
BasicDBObject();
jo.put(
"_id"
,
"0000"
+ i);
jo.put(
"name"
,
"Tomcat_"
+ i);
jo.put(
"age"
, i *
2
);
jo.put(
"interest"
,
new
String[] {
"swimming"
,
"Taiji"
});
actual += dao.insert(jo);
size++;
}
Assert.assertEquals(size, actual);
}
|
BasicDBObject对象是Mongo的BSONObject的基本实现类,而BSONObject对象正是Key-Value的形式的Map保存到数据库中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// 查询指定编号的记录
public
void
test3() {
BasicDBObject query =
new
BasicDBObject();
query.put(
"_id"
,
"00001"
);
List<DBObject> dboList = dao.query(query);
System.out.println(dboList.get(
0
).toString());
Assert.assertEquals(
1
, dboList.size());
}
// 模糊查询,统计记录结果数量
public
void
test4() {
BasicDBObject query =
new
BasicDBObject();
query.put(
"interest"
,
new
String[] {
"swimming"
,
"Taiji"
});
long
count = dao.getCount(query);
Assert.assertEquals(
9
, count);
}
// 模块查询,查询结果集合
public
void
test5() {
BasicDBObject query =
new
BasicDBObject();
query.put(
"interest"
,
new
String[] {
"swimming"
,
"Taiji"
});
List<DBObject> dboList = dao.query(query);
for
(DBObject jo : dboList) {
System.out.println(jo.toString());
}
Assert.assertEquals(
9
, dboList.size());
}
|
下面是插入数据后的数据库的数据情况,图中数据是各种测试后的数据,不完全对于每个方法的操作后数据库情况。
Mongo更新操作要准备两个BasicDBObject对象,一个是要更新的对象,另一个是更新后的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 更新指定记录的信息
public
void
test6() {
BasicDBObject query =
new
BasicDBObject();
query.put(
"_id"
,
"00001"
);
BasicDBObject jo =
new
BasicDBObject();
jo.put(
"_id"
,
"00001"
);
jo.put(
"name"
,
"Jackson"
);
jo.put(
"interest"
,
new
String[] {
"Song"
,
"Taiji"
,
"Running"
});
jo.put(
"firends"
,
new
BasicDBObject[] {
(BasicDBObject) dao.query(
new
BasicDBObject(
"_id"
,
"00002"
)).get(
0
),
(BasicDBObject) dao.query(
new
BasicDBObject(
"_id"
,
"00002"
)).get(
0
) });
int
actual = dao.update(query, jo);
Assert.assertEquals(
1
, actual);
}
|
1
2
3
4
5
6
7
8
|
// 删除指定记录
public
void
test7() {
BasicDBObject query =
new
BasicDBObject();
query.put(
"_id"
,
"000010"
);
dao.delete(query);
List<DBObject> dboList = dao.query(query);
Assert.assertEquals(
0
, dboList.size());
}
|
Mongo删除比较容易,指定一个BasicDBObject作为匹配条件,将删除匹配的所有记录(文档对象)。
在数据库的CRUD操作中查询操作更加多样化和频繁,Mongo的Java驱动程序中对Mongo数据自身的各种条件查询做了封装,提供一个QueryBuilder的类,将Mongo中的查询操作对象化,用此类来创建出要查询的条件,然后在进行基本查询。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
// 指定多条件的查询
public
void
test8() {
BasicDBObject query =
new
BasicDBObject();
BasicDBObject condition =
new
BasicDBObject();
condition.put(QueryOperators.GTE,
10
);
query.put(
"age"
, condition);
List<DBObject> dboList = dao.query(query);
for
(DBObject jo : dboList) {
System.out.println(jo.toString());
}
Assert.assertEquals(
5
, dboList.size());
}
public
void
test9() {
BasicDBObject query =
new
BasicDBObject();
BasicDBObject condition =
new
BasicDBObject();
condition.put(QueryOperators.GTE,
10
);
condition.put(QueryOperators.LTE,
16
);
query.put(
"age"
, condition);
List<DBObject> dboList = dao.query(query);
for
(DBObject jo : dboList) {
System.out.println(jo.toString());
}
Assert.assertEquals(
4
, dboList.size());
}
public
void
test10() {
QueryBuilder qb =
new
QueryBuilder();
BasicDBObject query = (BasicDBObject) qb.and(
"age"
)
.greaterThanEquals(
10
).lessThanEquals(
14
).and(
"interest"
)
.in(
new
String[] {
"swimming"
,
"Taiji"
,
"football"
}).get();
List<DBObject> dboList = dao.query(query);
for
(DBObject jo : dboList) {
System.out.println(jo.toString());
}
}
|
在test8方法中的查询条件是通过创建BasicDBObject来实现,如果条件更多这样操作会写很多代码而且不易将各个条件关联起来,后面的test9和test10方法则使用QueryBuilder来实现。
上述对Mongo数据的操作侧重于准备查询条件,插入对象,删除条件,更新条件等,主要原因是Mongo数据库操作再不是我们以前SQL那样具有高度标准化的操作,相反更多的注意力集中到如何在程序语言中翻译Mongo命令操作,原因很简单没有统一的标准实现。
至于数据库的基本操作Mongo的Java驱动自然要提供最基本的操作功能。
附上BaseDao代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
package
com.im.dao;
import
java.io.File;
import
java.io.IOException;
import
java.io.InputStream;
import
java.util.ArrayList;
import
java.util.List;
import
com.im.MongoFactory;
import
com.im.SystemConstant;
import
com.mongodb.BasicDBObject;
import
com.mongodb.DB;
import
com.mongodb.DBCollection;
import
com.mongodb.DBCursor;
import
com.mongodb.DBObject;
import
com.mongodb.WriteResult;
import
com.mongodb.gridfs.GridFS;
import
com.mongodb.gridfs.GridFSDBFile;
import
com.mongodb.gridfs.GridFSInputFile;
public
class
BaseDao {
/**
* 数据库对象
*/
private
DB db;
/**
* 数据库文档对象(相当于RDBMS中的表)
*/
private
DBCollection dbCollection;
/**
* 数据库文件存在集合
*/
private
GridFS fs;
public
BaseDao(String docBucket, String fileBucket) {
db = MongoFactory.getInstance().getMongo()
.getDB(SystemConstant.Configure.DATABASE);
this
.dbCollection = db.getCollection(docBucket);
if
(fileBucket.endsWith(
""
) || fileBucket ==
null
) {
fileBucket =
"fs"
;
}
this
.setFs(
new
GridFS(db, fileBucket));
}
/**
* 插入文档
*
* @param jo
* @return
*/
public
int
insert(DBObject jo) {
WriteResult wr = dbCollection.save(jo);
return
wr.getN();
}
/**
* 删除文档
*
* @param jo
* 删除的匹配文档
*/
public
void
delete(DBObject jo) {
dbCollection.remove(jo);
}
/**
* 更新文档
*
* @param query
* 指定更新的文档
* @param jo
* 更新后的文档
* @return
*/
public
int
update(DBObject query, DBObject jo) {
WriteResult wr = dbCollection.update(query, jo);
return
wr.getN();
}
/**
* 查询文档
*
* @param query
* 查询的匹配文档
* @return
*/
public
List<DBObject> query(DBObject query) {
DBCursor dbc = dbCollection.find(query);
List<DBObject> joList =
new
ArrayList<DBObject>();
while
(dbc.hasNext()) {
DBObject jo = dbc.next();
joList.add(jo);
}
return
joList;
}
/**
* 存储文件
*
* @param file
*/
public
void
saveFile(File file) {
try
{
GridFSInputFile gif = fs.createFile(file);
gif.save();
}
catch
(IOException e) {
e.printStackTrace();
}
}
/**
* 存储输入流,并指定的一些描述信息
*
* @param in
* @param id
* @param filename
* 文件名
* @param contentType
* 文件内容类型
*/
public
void
saveFile(InputStream in, Object id, String filename,
Object contentType) {
DBObject query = (DBObject)
new
BasicDBObject(
"_id"
, id);
GridFSDBFile gff = fs.findOne(query);
if
(gff ==
null
) {
GridFSInputFile gif = fs.createFile(in);
gif.setFilename(filename);
gif.put(
"_id"
, id);
gif.put(
"contentType"
, contentType);
gif.save();
}
}
/**
* 查询指定ID的文件
*
* @param id
* @return
*/
public
GridFSDBFile queryFile(Object id) {
DBObject query = (DBObject)
new
BasicDBObject(
"_id"
, id);
return
fs.findOne(query);
}
/**
* 查询指定文件名的文件
*
* @param filename
* @return
*/
public
GridFSDBFile queryFile(String filename) {
DBObject query = (DBObject)
new
BasicDBObject(
"filename"
, filename);
return
fs.findOne(query);
}
/**
* 查询文件
*
* @param query
* 查询的匹配文件
* @return
*/
public
List<GridFSDBFile> queryFile(DBObject query) {
return
fs.find(query);
}
/**
* 统计查询结果数
*
* @param query
* 查询匹配的文档
* @return
*/
public
long
getCount(DBObject query) {
return
dbCollection.getCount(query);
}
public
GridFS getFs() {
return
fs;
}
public
void
setFs(GridFS fs) {
this
.fs = fs;
}
public
DBCollection getDbCollection() {
return
dbCollection;
}
public
void
setDbCollection(DBCollection dbCollection) {
this
.dbCollection = dbCollection;
}
}
|