赞
踩
目录
4.1 mongodbmanagerfree_inst.exe
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
现在4.x以后引入了跨节点事务特性,可以粗浅的说关系型数据库能做的,它基本都能做了。
至于MongoDB是否在未来能够替代MySQL,这个还有得讨论。不过作为程序员而言,数据库只是工具,用什么工具并不重要,我们要习惯拥抱变化才能走的更长远。
下载地址:Download MongoDB Community Server | MongoDB
此文档使用的版本为:3.2.22
建议自定义安装,修改一下安装路径,其他的就下一步下一步即可。
任意路径打开cmd窗口,输入mongod,如果没有出现找不到指令则说明配置成功。
以上提示报初始化异常,说没有找到data目录。
那么我们可以手动添加mongoDB的数据库目录,到它指定的路径下。即c:\data\db\
以上数据库目录创建完成后,我们就可以再次使用mongod命令启动mongodb了。
出现以上界面则说明启动成功。
注意启动服务器界面不要关闭,再次启动一个cmd窗口,输入mongo,则会去连接mongoDB ,出现 > ,则说明已经成功进入了客户端界面了。
直接使用ctrl + c 即可退出。
修改MongoDB数据库目录
默认情况下,是在C:\data\db\下的,我们也可以为它指定目录。方法是在启动数据库时追加命令。
mongod --dbpath 指定目录地址
修改默认端口
默认启动时,端口号为27017,如果想要修改也只需要追加参数即可。
mongod --port 指定端口号
注意:参数是可以同时追加多个的,并非指定数据库目录同时不能指定端口号。
在当前数据库db同级目录下,创建一个log文件夹
在mongodb的安装home目录下新建配置文件mongod.cfg
内容如下(如果想更改位置也可以自己指定):
- systemLog:
- destination: file
- path: c:\data\log\mongod.log
- storage:
- dbPath: c:\data\db
已管理员权限运行cmd,然后执行如下命令
sc.exe create MongoDB binPath= "\"D:\it\MongoDB3.2.22\bin\mongod.exe\" --service --config=\"D:\it\MongoDB3.2.22\mongod.cfg\"" DisplayName= "MongoDB" start= "auto"
启动mongodb服务
测试
此时,你只需要输入mongo命令,无需再启动MongoDB的服务器了。
如果启动失败,证明上面的操作有误
在控制台输入 sc delete MongoDB 删除之前配置的服务,然后再从第一步重新开始。
MongoDB的结构分为:
database(数据库)、collection(集合)、document(文档)
与关系型数据库比较,其实就相当于数据库、表、记录。
- # 查看所有数据库,默认只有一个叫local的数据库
- show databases;
- # 进入某个数据库,如果数据库不存在,也不影响进入,只要为数据库创建了内容,会自动生成该数据库
- use 数据库名;
- # 查看当前在哪个数据库中
- db
- # 查看当前数据库中所有的集合
- show collections;
这里只是简单演示一下,后面使用图形化界面工具重点演示
向数据库中插入文档
db.集合名.insert(文档)
例如:
向my-test数据库中 ,stus集合中插入一个新的学生对象:{name:"王二",age:12,gender:"男"}
db.stus.insert({name:"王二",age:12,gender:"男"});
查询集合中的所有文档
db.集合名.find();
安装默认下一步即可。登录也是
其实个人认为最好用的还是navicat
当我们向集合插入文档时,如果没有给文档指定 _id 属性,则数据库会自动为文档添加 _id。该属性作为文档的唯一标识。
我们也可以自己生成,但是如果自己生成一定要保证其唯一性。建议使用默认的自动生成。
总结
insert()
insertOne()
insertMany()
后面两个方法其实本质上也属于第一个。insertOne则只能插入一个文档,而insertMany()则必须使用数组的形式插入,可以是多个,也可以是一个。
find()
不传参数表示查询查询集合中所有文档
传递文档参数则表示查询当前集合中指定文档参数的全部文档
返回的是数组
后面追加count()表示统计数量
findOne()
查询符合条件的第一个文档
返回的是文档对象
举例:
第一个对象依然是条件,第二个对象使用$unset,然后对象里面的属性就是要删除的属性,属性的值是多少不重要。
该方法只要符合条件的都会替换
db.west.update( {"_id" : ObjectId("6490023fd5582aef179c3bc9"}, {age:8})
remove()
默认删除多个
如果第二个参数设置为true,则只会删除第一个
必须传参,否则报错
如果传递{},则集合中所有的文档都删除了。如果想要删除所有的,建议使用db.集合名.drop() 效率更高。
deleteOne() 默认删除第一个
deleteMany()
一般情况下,数据库中的数据很少删除,所以一般不会调用删除命令。因为一旦删除就会永久丢失了。
一般我们也会像Mysql那样,设置逻辑删除字段。只是要求在查询的时候带上逻辑删除字段的条件。
默认情况下,mongodb是没有账号密码的,需要我们手动进行设置,否则如果是线上环境,那绝对是裸奔了。
- # 设置管理员用户名密码需要切换到admin库(系统默认要求的)
- use admin
- # 创建管理员
- db.createUser({user:"hssy",pwd:"qwe!2345",roles:["root"]})
- # 查看所有用户信息
- show users
- # 删除用户
- db.dropUser("hssy")
登录
mongo -u 用户名 -p 密码 --authenticationDatabase=admin
但是我们发现,好像直接用mongo命令也能启动哦
这是因为我们启动MongoDB服务器的时候,没有以auth启动。当我们启动时使用--auth命令后,再使用mongo命令就无法看到数据库及其内容了。
我们也可以在某一个库下,创建管理员,这样该管理员只能针对该数据库有权限,其他数据库是无法操作的。
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-mongodb</artifactId>
- </dependency>
- spring:
- data:
- mongodb:
- uri: mongodb://hssy:qwe!2345@localhost:27017/my-test?authSource=admin
- # uri 等同于下面的配置
- # database: my-test
- # host: localhost
- # port: 27017
- # username: hssy
- # password: qwe!2345
- # authentication-database: amin
如下方法都是通过MongoTemplate对象调用。
方法名 | 返回值类型 | 解释 |
---|---|---|
getCollectionNames | Set<String> | 获取当前库下全部集合名称 |
collectionExists(String collectionName) | boolean | 判断当前集合名称是否存在 |
createCollection(String collectionName) | MongoCollection<Document> | 新建集合 |
dropCollection(String collectionName) | 无 | 删除集合 |
findAll(Class<T> entityClass, String collectionName) | <T> List<T> | 查询指定集合中的全部文档,第一个参数是告诉MongoDB用哪个实体类映射 |
find(Query query, Class<T> entityClass, String collectionName) | <T> List<T> | 根据条件查询指定集合中的文档,第一个参数是查询条件 |
findById(Object id, Class<T> entityClass, String collectionName) | <T> T | 根据id查询指定集合中的文档,因为id是唯一的,所以只会有一个返回值 |
insert(T objectToSave, String collectionName) | <T> T | 向指定集合新增一条文档。需要指定集合名。 |
insert(T objectToSave) | <T> T | 向指定集合新增一条文档,没有指定集合名,默认根据实体类名生成。另外,无论是否指定集合名,即使不存在该集合,新增的时候也会自动创建该集合。 |
upsert(Query query, UpdateDefinition update, Class<?> entityClass) | UpdateResult | 按条件更新文档,如果查询条件未找到记录,则会新增一条记录。如果查询出符合条件的数据有n条,则会修改这n条数据 |
remove(Query query, Class<?> entityClass, String collectionName) | DeleteResult | 按条件删除文档 |
count(Query query, @Nullable Class<?> entityClass, String collectionName) | long | 查询指定条件下某集合的文档总条数 |
- package com.hssy.smartaide.controller.mongodb;
-
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.hssy.smartaide.common.Result;
- import com.hssy.smartaide.common.constant.enums.StatusCode;
- import com.hssy.smartaide.entity.User;
- import com.hssy.smartaide.entity.mongo.ConsumerDetail;
- import com.hssy.smartaide.form.mongo.ConsumerDetailQueryForm;
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.PageImpl;
- import org.springframework.data.domain.PageRequest;
- import org.springframework.data.domain.Pageable;
- import org.springframework.data.domain.Sort;
- import org.springframework.data.mongodb.core.MongoTemplate;
- import org.springframework.data.mongodb.core.query.Criteria;
- import org.springframework.data.mongodb.core.query.Query;
- import org.springframework.data.mongodb.core.query.Update;
- import org.springframework.web.bind.annotation.*;
-
- import java.time.LocalDate;
- import java.util.List;
- import java.util.Set;
-
- @Api(tags = "MongoDB数据库操作")
- @RestController
- @RequestMapping("mongo")
- public class MongoController {
- @Autowired
- private MongoTemplate mongoTemplate;
-
- @ApiOperation("查询所有集合名称")
- @GetMapping("findAllCollectionName")
- public Result<Set<String>> findAllCollectionName(){
- Set<String> collectionNameSet = mongoTemplate.getCollectionNames();
- return Result.success(collectionNameSet);
- }
-
- @ApiOperation("判断指定集合是否存在")
- @GetMapping("isExistCollection")
- public Result<Boolean> isExistCollection(@RequestParam(value = "collectionName") String collectionName){
- return Result.success(mongoTemplate.collectionExists(collectionName));
- }
-
- @ApiOperation("新建集合")
- @PostMapping("createCollection")
- public Result<String> createCollection(@RequestParam(value = "collectionName") String collectionName){
- boolean isExistCollection = mongoTemplate.collectionExists(collectionName);
- if (!isExistCollection){
- mongoTemplate.createCollection(collectionName);
- return Result.success(StatusCode.CREATE_SUCCESS.getCode(),StatusCode.CREATE_SUCCESS.getValue());
- }else {
- return Result.error(-1,"当前数据库已存在该集合,添加失败!");
- }
- }
-
- @ApiOperation("删除集合")
- @PostMapping("dropCollection")
- public Result<String> dropCollection(@RequestParam(value = "collectionName") String collectionName){
- mongoTemplate.dropCollection(collectionName);
- return Result.success(StatusCode.DELETE_SUCCESS.getCode(), StatusCode.DELETE_SUCCESS.getValue());
- }
-
- @ApiOperation("查询指定集合中的全部文档(Object接收)")
- @GetMapping("findAllDocumentByCollectionName")
- public Result<List<Object>> findAllDocumentByCollectionName(@RequestParam(value = "collectionName") String collectionName){
- // 如果知道文档的属性,建议用一个实体类去接收
- List<Object> list = mongoTemplate.findAll(Object.class, collectionName);
- return Result.success(list);
- }
-
- @ApiOperation("查询user集合中的全部文档(具体实体类映射)")
- @GetMapping("findAllDocument-user")
- public Result<List<User>> findAllDocumentByCollectionName2(){
- List<User> list = mongoTemplate.findAll(User.class, "user");
- return Result.success(list);
- }
-
- @ApiOperation("查询myFriend集合中的全部文档(具体实体类映射)")
- @GetMapping("findAllDocument-myFriend")
- public Result<List<ConsumerDetail>> findAllDocumentINmyFriend(){
- List<ConsumerDetail> list = mongoTemplate.findAll(ConsumerDetail.class, "myFriend");
- return Result.success(list);
- }
-
- @ApiOperation("根据名称查询myFriend集合中的文档")
- @GetMapping("findDocumentByConsumerName")
- public Result<List<ConsumerDetail>> findDocumentByConsumerName(@RequestParam(value = "consumerName") String consumerName){
- Query query = new Query(Criteria.where("consumerName").is(consumerName));
- List<ConsumerDetail> list = mongoTemplate.find(query, ConsumerDetail.class, "myFriend");
- return Result.success(list);
- }
-
- @ApiOperation("条件查询myFriend集合中的文档")
- @GetMapping("findDocumentQuery")
- public Result<List<ConsumerDetail>> findDocumentQuery(ConsumerDetailQueryForm form){
- // Query 用来封装所有条件的对象
- Query query = new Query();
-
- //Criteria criteria = new Criteria();
- //criteria.andOperator(
- // Criteria.where("consumerName").regex(".*"+form.getConsumerName()+".*"),
- // Criteria.where("gender").is(form.getGender()),
- // Criteria.where("houseNum").is(form.getHouseNum()));
- //query.addCriteria(criteria);
-
- if (form.getConsumerName() != null && ! "".equals(form.getConsumerName())){
- //Criteria 用来构建条件
- Criteria criteria = Criteria.where("consumerName").regex(".*" + form.getConsumerName() + ".*");
- query.addCriteria(criteria);
- }
- if (form.getGender()!=null && ! "".equals(form.getGender())){
- Criteria criteria = Criteria.where("gender").is(form.getGender());
- query.addCriteria(criteria);
- }
- if (form.getHouseNum()!=null && ! "".equals(form.getHouseNum())){
- Criteria criteria = Criteria.where("houseNum").is(form.getHouseNum());
- query.addCriteria(criteria);
- }
-
- List<ConsumerDetail> list = mongoTemplate.find(query, ConsumerDetail.class, "myFriend");
- return Result.success(list);
- }
-
- @ApiOperation("根据id查询myFriend集合中的文档")
- @GetMapping("findMyFriendDocumentById")
- public Result<ConsumerDetail> findMyFriendDocumentById(@RequestParam(value = "id") String id){
- //Query query = new Query(Criteria.where("_id").is(id));
- //List<ConsumerDetail> list = mongoTemplate.find(query, ConsumerDetail.class, "myFriend");
-
- ConsumerDetail consumerDetail = mongoTemplate.findById(id, ConsumerDetail.class,"myFriend");
- return Result.success(consumerDetail);
- }
-
-
- @ApiOperation("新增文档")
- @GetMapping("insertDocument")
- public Result<String> insertDocument(){
- User user = new User();
- user.setUsername("萧敬腾");
- user.setBirthday(LocalDate.of(1988,8,3));
- user.setGender("男");
- user.setPhoneNo("561523");
- user.setAddress("台北市重庆路188号");
- mongoTemplate.insert(user,"east");
- return Result.success(StatusCode.CREATE_SUCCESS.getCode(), StatusCode.CREATE_SUCCESS.getValue());
- }
-
- @ApiOperation("新增文档-user集合")
- @PostMapping("insertDocument-user")
- public Result<String> insertDocumentUser(@RequestBody User user){
- // 沒有指定集合,则默认使用实体类的名称作为集合名称,且默认转换成小驼峰
- // 实体类中如果没有_id字段,则MongoDB会自动生成唯一的_id值。
- mongoTemplate.insert(user);
- return Result.success(StatusCode.CREATE_SUCCESS.getCode(), StatusCode.CREATE_SUCCESS.getValue());
- }
-
- @ApiOperation("新增文档-myFriend集合")
- @PostMapping("insertDocument-myFriend")
- public Result<String> insertDocumentMyFriend(@RequestBody ConsumerDetail consumerDetail){
- // 如果实体类使用了@Document(collection = "MyFriend")注解,则会使用注解参数中设置的名称作为集合名称。不会擅改大小写。
- // 如果实体类中有id字段,则最好设置成string类型,就会自动映射。
- // 但是如果字段名不是id,比如cid,那么就不会自动映射了。需要我们使用注解@Id或者@MongoId,建议是@Id,其他注解可能有些问题,或者使用上有要求
- // 表明该字段为主键,这样就会识别为mongodb的_id
- // 当然前提是使用String字符串类型去映射,因为MongoDB默认生成的_id就是字符串类型
- // 这样我们在新增的时候可以设置id值也可以让mongoDB自动生成。
-
- // ps(这里实体类名叫ConsumerDetail,映射的集合叫myFriend,这里只是演示。实际建议他们名称一致)
- mongoTemplate.insert(consumerDetail);
- return Result.success(StatusCode.CREATE_SUCCESS.getCode(), StatusCode.CREATE_SUCCESS.getValue());
- }
-
- @ApiOperation("新增文档-foodDetail集合(自定义主键规则)")
- @PostMapping("insertDocument-foodDetail")
- public Result<StringBuilder> insertDocumentFoodDetail(){
- StringBuilder result = new StringBuilder();
- result.append("倘若我们不希望使用MongoDB默认规则生成的主键 \n" +
- " 比如希望主键自增,怎么办呢? \n" +
- "由于MongoDB本身并不维护自增ID,因此只能利用MongoDB的原子性通过findAndModify自增1来实现 \n " +
- "所以需要我们自定义规则来生成id。\n " +
- "比如自定义一个自增注解,表明此ID需要自增 \n " +
- "然后监听MongoDB-data的保存操作,在保存前进行ID的替换\n" +
- "比较麻烦,这里就不掩饰了,感兴趣的可以自行尝试");
- return Result.success(result);
- }
-
-
- @ApiOperation("修改文档-myFriend集合")
- @PostMapping("updateDocument-myFriend")
- public Result<StringBuilder> updateDocumentMyFriend(ConsumerDetail consumerDetail){
- // 参数校验
- if (consumerDetail.getCid() == null){
- Result.error(-1,"请传递id参数");
- }
- // 构建查询条件
- Query query = new Query();
- query.addCriteria(Criteria.where("_id").is(consumerDetail.getCid()));
- // 设置更新字段
- Update update = new Update();
- update.set("consumerName",consumerDetail.getConsumerName());
- update.set("gender",consumerDetail.getGender());
- update.set("birthday",consumerDetail.getBirthday());
- update.set("phoneNo",consumerDetail.getPhoneNo());
- update.set("houseNum",consumerDetail.getHouseNum());
- update.set("remark",consumerDetail.getRemark());
-
- // 调用upsert方法进行修改
- // 以下三个重载方法都可以。加上集合名称是为了防止你修改了映射集合名称。
- // 所以,保险起见,最好的方式是使用第三个方法。
- // mongoTemplate.upsert(query,update,ConsumerDetail.class);
- // mongoTemplate.upsert(query,update,"myFriend");
- mongoTemplate.upsert(query,update,ConsumerDetail.class,"myFriend");
- return Result.success();
- }
-
- @ApiOperation("删除文档-myFriend集合")
- @PostMapping("removeDocument-myFriend")
- public Result<StringBuilder> removeDocumentMyFriend(@RequestParam("id") String id){
- //mongoTemplate.remove(new Query(Criteria.where("_id").is(id)),ConsumerDetail.class);
- //mongoTemplate.remove(new Query(Criteria.where("_id").is(id)),"myFriend");
- mongoTemplate.remove(new Query(Criteria.where("_id").is(id)),ConsumerDetail.class,"myFriend");
- return Result.success(StatusCode.DELETE_SUCCESS.getCode(), StatusCode.DELETE_SUCCESS.getValue());
- }
-
-
- @ApiOperation("查询myFriend集合中的文档总数")
- @GetMapping("findMyFriendDocumentCount")
- public Result<Long> findMyFriendDocumentCount(){
- // 其实该方法可以根据条件查询,查询符合条件的文档记录总数,只不过这里query未设置条件而已
- // 当然了,和修改删除一样,它也有几个重载方法,保险期间用如下这个
- Query query = new Query();
- long count = mongoTemplate.count(query, ConsumerDetail.class, "myFriend");
- return Result.success(count);
- }
-
-
- @ApiOperation("分页查询myFriend集合中的全部文档")
- @GetMapping("findMyFriendAllDocumentPage")
- public Result<PageImpl<ConsumerDetail>> findMyFriendAllDocumentPage(Integer pageNum,Integer pageSize){
- // 查询方法还是它find()方法,只是查询条件中封装分页对象
- Query query = new Query();
- query.with(Sort.by(Sort.Order.desc("birthday"))); // 按照生日降序排列
- Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
- query.with(pageable); // 分页查询
-
- List<ConsumerDetail> list = mongoTemplate.find(query, ConsumerDetail.class, "myFriend");
- return Result.success(new PageImpl<>(list));
- }
-
- }
就展示到这儿,需要的可以将代码直接复制到自己的项目中进行演示。
当然也可以自己写。不过一定要熟悉一下,毕竟今后是用代码打交道的~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。