mongodb简介
MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。
MongoDB中的一条记录就是一个文档,是一个数据结构,由字段和值对组成。MongoDB文档与JSON对象类似。字段的值有可能包括其它文档、数组以及文档数组。MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,PHP,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。
MongoDB的适合对大量或者无固定格式的数据进行存储,比如:日志、缓存等。对事物支持较弱,不适用复杂的多文档(多表)的级联查询。文中演示mongodb版本为3.4。
mongodb的增删改查
Spring Boot对各种流行的数据源都进行了封装,当然也包括了mongodb,下面给大家介绍如何在spring boot中使用mongodb:
1、pom包配置
pom包里面添加spring-boot-starter-data-mongodb包引用
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
2、mongodb标准 URI 连接语法:
-
mongodb:// 这是固定的格式,必须要指定。
-
username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库
-
host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。
-
portX 可选的指定端口,如果不填,默认为27017
-
/database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。
-
?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开
标准的连接格式包含了多个选项(options),如下所示:
选项 | 描述 |
---|---|
replicaSet=name | 验证replica set的名称。 Impliesconnect=replicaSet. |
slaveOk=true|false |
|
safe=true|false |
|
w=n | 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。 |
wtimeoutMS=ms | 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true. |
fsync=true|false |
|
journal=true|false | 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true |
connectTimeoutMS=ms | 可以打开连接的时间。 |
socketTimeoutMS=ms | 发送和接受sockets的时间。 |
3、在application.properties中添加URI配置
spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test
多个IP集群可以采用以下配置:
spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database
4、使用MongoTemplate创建集合
1)根据数据实体生成集合及其结构
其效果是自动根据实体内容生成集合结构
@Document(collection="person")//此注解可以省略 如果省略则集合名称为类名的首字母小写对应的名称 即:personEntity
public class PersonEntity implements Serializable {
private static final long serialVersionUID = -3258839839160856613L;
private Long id;
private String zhName;
private String passWord;
//getter、setter省略
}
2)根据java代码命令先生成一个空结构的集合
CollectionOptions collectionOptions=new CollectionOptions(6142800,10000,true);//第一个参数size
(可选)指定上限集合的 //最大大小(以字节为单位),目前限制为6142800字节。 如果capped
为true
,那么还需要指定此字段的值。第二个参数max(可选) //指定上限集合中允许的最大文档数。目前为10000 第三个参数capped
(可选)如果为true
,则启用封闭的集合。上限集合是固定大 //小的集合,它在达到其最大大小时自动覆盖其最旧的条目。 如果指定true
,则还需要指定size
参数。
DBCollection dBCollection=mongoTemplate.createCollection("mycol",collectionOptions); 注:mongoTemplate.getCollection("mycol").drop() 删除一个指定集合
5、集合的使用:例如增删改查
1)使用实体对集合进行增删改查
@Component
public class PersonDaoImpl implements PersonDao {
@Autowired
private MongoTemplate mongoTemplate;
/**
* 创建对象
* @param person
*/
@Override
public void savePerson(PersonEntity person) {
mongoTemplate.save(person);//如果集合不存在,则按照实体的属性创建集合结构
}
/**
* 根据用户名查询对象
* @param zhName
* @return
*/
@Override
public PersonEntity findPersonByZhName(String zhName) {
Query query=new Query(Criteria.where("zhName").is(zhName));
query.with(new Sort(new Order(Direction.ASC,"zhName")));
PersonEntity person= mongoTemplate.findOne(query , PersonEntity.class);
return person;
}
/**
* 更新对象
* @param person
*/
@Override
public int updatePerson(PersonEntity person) {
Query query=new Query(Criteria.where("id").is(person.getId()));
Update update= new Update().set("zhName", person.getZhName()).set("passWord", person.getPassWord());
//更新查询返回结果集的第一条
WriteResult result =mongoTemplate.updateFirst(query,update,PersonEntity.class);
//更新查询返回结果集的所有
// mongoTemplate.updateMulti(query,update,PersonEntity.class);
if(result!=null)
return result.getN();
else
return 0;
}
/**
* 删除对象
* @param id
*/
@Override
public void deleteUserById(Long id) {
Query query=new Query(Criteria.where("id").is(id));
mongoTemplate.remove(query,PersonEntity.class);
}
}
2)根据java命令对已存在的集合生成指定结构
@Override
public void addData() {
DBCollection dBCollection=mongoTemplate.getCollection("mycol");
if(dBCollection==null) {
CollectionOptions collectionOptions=new CollectionOptions(6142800,10000,true);
dBCollection=mongoTemplate.createCollection("mycol",collectionOptions);
}
//添加操作
//下面分别是创建文档的几种方式:1. .append()
DBObject english = new BasicDBObject().append("name","english").append("score", 5).append("id",1);
dBCollection.insert(english);
//2.put()
DBObject math = new BasicDBObject();
math.put("id", 2);
math.put("name", "math");
math.put("score", 10);
dBCollection.insert(math);
//3. 通过map
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","physics" );
map.put("score", 10);
map.put("id", 3);
DBObject physics= new BasicDBObject(map);
dBCollection.insert(physics);
// 4. 将json转换成DBObject对象
String json ="{'name':'chemistry','score':10,'id':4}";
DBObject chemistry =(DBObject)JSON.parse(json);
dBCollection.insert(chemistry);
//4.1.1将json转换成DBObject对象添加内嵌文档
String json2 =" {'name':'english','score':10,'teacher':[{'name':'柳松','id':'1'},{'name':'柳松松','id':2}]}";
DBObject english2= (DBObject)JSON.parse(json2);
dBCollection.insert(english2);
}
//常用操作
@Override
public void mongoDbOperate() {
try {
DBCollection dBCollection=mongoTemplate.getCollection("score");
if(dBCollection==null) {
CollectionOptions collectionOptions=new CollectionOptions(6142800,10000,true);
dBCollection=mongoTemplate.createCollection("score",collectionOptions);
}
/* //批量添加
List<DBObject> documents=new ArrayList<DBObject>();
for(int i=0;i<10;i++) {
DBObject query=new BasicDBObject();
query.put("name", i);
query.put("subject", "语文"+i%3);
query.put("score",Math.random()*100);
query.put("status",i%2);
documents.add(query);
}
dBCollection.insert(documents); */
/* //mogonDb mapReduce使用 String map = "function() { "+
"emit(this.subject,this.score);}";
String reduce = "function(key, values) { " +
"var sum = 0; " +
"var count = 0; " +
"values.forEach(function(score) { " +
"sum += score; "+
"count += 1"+
"}); " +
"var avg = sum/count; " +
"return {totalScore: sum,avg:avg,count:count};} ";
DBObject quesry=new BasicDBObject();
quesry.put("status", 0);//取出状态为0的数据进行mapReduce运算
MapReduceCommand cmd = new MapReduceCommand(dBCollection, map, reduce, null, MapReduceCommand.OutputType.INLINE, quesry);
MapReduceOutput out = dBCollection.mapReduce(cmd);
for (DBObject o : out.results()) {
System.out.println(o.toString());
} */
/*//根据多条件查询数据以及将结果排序
DBObject query=new BasicDBObject();
query.put("status", 0);//取出status为0的数据
query.put("name", new BasicDBObject("$type","int"));//取出name属性中数据类型为int的数据 具体对应关系可参照MongoDB $type 操作符int等价于16
//query.put("name", new BasicDBObject("$type",16));//取出name属性中数据类型为int的数据 具体对应关系可参照MongoDB $type 操作符 int等价于16
// query.put("score", new BasicDBObject("$gt",30).append("$lt", 90));//取出score大于30 小于90分的数据
DBCursor dbCursor= dBCollection.find(query).sort(new BasicDBObject("name",1));//new BasicDBObject("name",1) 按照name属性的升序方式排序
dBCollection.setWriteConcern(WriteConcern.SAFE);
try {
while (dbCursor.hasNext()) {
System.out.println(dbCursor.next());
}
} finally {
dbCursor.close();
}*/
//MongoDB中聚合的方法使用aggregate()
DBObject totalscore = new BasicDBObject("$sum","$score"); //依据subject进行分组后对score求总分
DBObject avg = new BasicDBObject("$avg","$score"); /依据subject进行分组后对score求平均分
DBObject groupFileds = new BasicDBObject("_id", "$subject"); //依据subject进行分组
groupFileds.put("totalscore", totalscore);
groupFileds.put("avg", avg);
groupFileds.put("max", new BasicDBObject("$max","$score")); //依据subject进行分组后对score求最大值
groupFileds.put("min", new BasicDBObject("$min","$score")); //依据subject进行分组后对score求最小值
groupFileds.put("count", new BasicDBObject("$sum",1)); //依据subject进行分组后,统计各个分组项的个数
DBObject group = new BasicDBObject("$group", groupFileds);
DBObject match = new BasicDBObject("$match", new BasicDBObject("status",0)); //取出status为0的数据 然后依据subject进行分组
DBObject sort = new BasicDBObject("$sort",new BasicDBObject("_id",1));//依据_id属性升序排列
AggregationOutput output = dBCollection.aggregate(Arrays.asList(match,group,sort));
//注意:管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
//MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
//表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
//由此可知MongoDB的聚合管道的先后顺序是很重要的,因为上一管道操作命令的结果会作为下一个管道操作的参数
List<DBObject> dbObjects = (List<DBObject>) output.results();
for(DBObject dBObject:dbObjects) {
System.out.println(dBObject.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
更多的mongoDB的使用方式参见:http://www.runoob.com/mongodb/mongodb-tutorial.html