Bootstrap

MongoDB使用

MongoDB介绍

什么是MongoDB

  • 基于分布式文件存储数据库(就是一个数据库
  • C++语言编写
  • 支持的数据结构非常松散,是类似json的bson格式(后期插入修改数据写JSON

基本命令

  1. 数据库相关
1.查看所有数据库
show databases
2.选择数据库(如果数据库不存在,不会报错;会隐式创建:当后期该数据库有数据时自动创建)
use 数据库名
3.删除数据库(先选中数据库)
db.dropDatabase()

2.集合相关

1.查看所有集合
show collections
2.创建集合(插入数据会隐式创建)
db.createCollection('集合名')
3.删除集合
db.集合名.drop()

增删改查

1.增

语法:db.集合名.inset(JSON数据)

集合存在则插入,不存在则隐式创建

use test2
db.c1.insert({uname:"webopenfather",age:18})
注意:对象的键都不加引号,查看时集合数据时系统会自动加,且会给每条数据增加唯一ID键
1.自定义id
只需要给插入的JSON数据增加_id键即可覆盖(强烈不推荐)
db.c1.insert({_id:1,uname:"webopenfather",age:18})
2.一次插入多条记录
直接传输JSON格式数据
db.c1.insert([
		{uname:"z3",age:3},
		{uname:"z4",age:4},
		])
3.快速插入多条数据
MongoDB底层使用JS引擎,支持部分JS语法
需求:在test2数据库c2集合中插入10条数据,分别是a1....a10
for(var i=1;i<10;i++){
	db.c2.insert({uname:"a"+i,age:i})
}

2.查

语法:db.集合名.find(条件[,查询的列])
条件:
	查询所有数据				{}或者不写
	查询age=6				{age:6}
	查询age=6且性别=男		{age:6,sex:'男'}
查询字段
	不写				查询全部字段
	{age:1}				只显示age字段
	{age:0}			除了age字段都显示
	注意:_id无论如何查询都显示
条件查询
	db.集合名.find({键:值})   值不直接写  {运算符:值}
	db.集合名.find({
				键:{运算符:值}
				})
运算符作用
$gt大于
$gte大于等于
$lt小于
$lte小于等于
$ne不等于
$inin
$ninnot in

3.改

语法:db.集合名.update(条件,新数据[,是否新增,是否修改多条])
是否新增:条件匹配不到数据则插入(true插入,false不插入)
是否修改多条:匹配成功数据修改(true是,false否  默认)
注意:若不使用修改器默认是将数据替换
修改器作用
$inc递增
$set修改字段值
$rename重命名列
$unset删除字段
db.集合名.update(条件,新数据)
						{修改器:{键:值}}

在这里插入图片描述
4.删

语法:db.集合名.remove(条件[,是否删除一条])
是否删除一条:true是,false否全部删除  默认

排序、分页、聚合查询

排序sort、分页limit

db.集合名.find()
	.sort({字段:1/-1})	排序(1升-1降)
	.skip(数字)			跳过指定条数
	.limit(数字)		限制查询条数
	.count()			统计总数

聚合查询

db.集合名.aggregate([
	{管道:{表达式}}
	...
	])

常用管道

管道作用
$group将集合中文档分组,用于统计结果
$match过滤数据,只输出符合条件的文档
$sort聚合数据进一步排序
$skip跳过指定文档数
$limit限制集合数据返回文档数

常用表达式

表达式作用
$sum总和;$sum:1同count表示统计
$avg平均
$min最小值
$max最大值
求学生总数和平均年龄
db.c1.aggregate([
	{
		$group:{
			_id:null,  //_id必须有   null表示对全部数据分组
			total_num:{$sum:1},
			total_avg:{$avg:"$age"}
			}
		}
	])
查询男生、女生人数,按人数升序
db.c1.aggregate([
	{$group:{_id:"$sex",rs:{$sum:1}}},
	{$sort:{rs:-1}}
	])

索引

创建索引
_id是系统自建的索引,删除全部索引,也会保留_id

db.集合名.createIndex(待创建索引的字段[,额外选项/唯一索引等])
待创建索引的字段:{键:1,...,键:-1}  1升/-1降
额外选项:设置索引的名称或者唯一索引等

给name添加普通索引
db.c1.createIndex({name:1})

查询索引

db.集合名.getIndexes()

删除索引

全部删除:db.集合名.dropIndexes()
删除指定:db.集合名.dropIndex(索引名)

复合索引

db.集合名.createIndex({键1:方式,键2:方式})

给索引起名

db.集合名.createIndex({{键1:方式},{键1:"别名"}})

设置唯一索引

db.集合名.createIndex({{键1:方式},{unique:"键1"}})

分析索引

语法:db.集合名.find().explain('executionSrats')

stage状态:

  • COLLSCAN 全表扫描
  • IXSCAN 索引扫描
  • FETCH 根据索引去检索指定document
    在这里插入图片描述

权限机制

备份还原

SpringBoot集成MongoDB

1.构建SpringBoot项目
2.引入MongoDB依赖
3.在application.properties文件添加MongoDB配置(test库)

spring.data.mongodb.uri=mongodb://127.0.0.1:27017/test

MongoTemplate常用方法

方法作用
mongoTemplate.findAll(User.class)查询User文档的全部数据
mongoTemplate.findById(, User.class)查询User文档id为id的数据
mongoTemplate.find(query, User.class)根据query内的查询条件查询
mongoTemplate.upsert(query, update, User.class)修改
mongoTemplate.remove(query, User.class)删除
mongoTemplate.insert(User)新增

Query对象
1、创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件)
2、 精准条件:criteria.and(“key”).is(“条件”)
模糊条件:criteria.and(“key”).regex(“条件”)
3、封装条件:query.addCriteria(criteria)
4、大于(创建新的criteria):Criteria gt = Criteria.where(“key”).gt(“条件”)
小于(创建新的criteria):Criteria lt = Criteria.where(“key”).lt(“条件”)
5、Query.addCriteria(new Criteria().andOperator(gt,lt));
6、一个query中只能有一个andOperator()。其参数也可以是Criteria数组。
7、排序 :query.with(new Sort(Sort.Direction.ASC, “age”). and(new Sort(Sort.Direction.DESC, “date”)))

案例

  • 创建实体类
    MongoDB常用注解
注解作用
@Document标注在实体类上,标明由mongodb来维护该表。
@Id主键,不可重复,自带索引,需要自己生成并维护不重复的约束。
@Indexed索引,加索引后以该字段为条件检索将大大提高速度。
@Field定义存储字段名。可以不加,不加的话默认以参数名为列名。
@Transient被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性。
@DBRef设置对象的关联。类似于关系型数据库的外键
@Data
@Document("User")
public class User {
    @Id
    private String id;
    private String name;
    private Integer age;
    private String email;
    private String createDate;
}

*新增数据(mongoTemplate.insert(对象))

@Autowired
    private MongoTemplate mongoTemplate;
    //添加操作
    @Test
    void contextLoads() {
        User user = new User();
        user.setAge(20);
        user.setName("test");
        user.setEmail("[email protected]");
        User user1 = mongoTemplate.insert(user);
        System.out.println(user1);
    }
  • 查询全部数据(mongoTemplate.findAll(类.class))
//查询所有记录
@Test
 public void findAll(){
     List<User> all = mongoTemplate.findAll(User.class);
     System.out.println(all);
 }

  • 根据id查询(mongoTemplate.findById(“id”, User.class))
 //根据id查询
 @Test
 public void findId(){
     User user = mongoTemplate.findById("60b4b3ca861699233d33f3e2", User.class);
     System.out.println(user);
 }
  • 条件查询(mongoTemplate.find(query, User.class))
//条件查询
@Test
 public void findUserList(){
     Query query = new Query(Criteria.where("name").is("test").and("age").is(20));
     List<User> users = mongoTemplate.find(query, User.class);
     System.out.println(users);
 }
  • 模糊查询
 //模糊条件查询
    @Test
    public void findLikeUserList(){
//        name like test
        String name = "est";
        String regex = String.format("%s%s%s", "^.*", name, ".*$");
        /*1、在使用Pattern.compile函数时,可以加入控制正则表达式的匹配行为的参数:
        Pattern Pattern.compile(String regex, int flag)
        2、regex设置匹配规则
        3、Pattern.CASE_INSENSITIVE,这个标志能让表达式忽略大小写进行匹配。*/
        Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
        //创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件)
        Query query = new Query(//构建查询条件
                Criteria.where("name").regex(pattern));
        List<User> users = mongoTemplate.find(query, User.class);
        System.out.println(users);
    }

在这里插入图片描述

  • 分页查询
//分页查询(带条件)
@Test
 public void pageLikeUserList(){
     int pageNo = 1;//设置当前页
     int pageSize = 3;//设置每页显示的记录数
     //条件构建
     String name = "est";
     String regex = String.format("%s%s%s", "^.*", name, ".*$");
     /*1、在使用Pattern.compile函数时,可以加入控制正则表达式的匹配行为的参数:
     Pattern Pattern.compile(String regex, int flag)
     2、regex设置匹配规则
     3、Pattern.CASE_INSENSITIVE,这个标志能让表达式忽略大小写进行匹配。*/
     Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
     //创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件)
     Query query = new Query(//构建查询条件
             Criteria.where("name").regex(pattern));

     //分页构建
     //查询数来集合(表)中的总记录数
     long count = mongoTemplate.count(query, User.class);
     List<User> users = mongoTemplate.find(
             query.skip((pageNo - 1) * pageSize).limit(pageSize), User.class);
     System.out.println(count);
     System.out.println(users);
 }
  • 修改数据
 //修改操作
@Test
public void  updateUser(){
    //根据id查询
    User user = mongoTemplate.findById("60b4f89db925b61fbf529591", User.class);
    //修改值
    user.setName("test_02");
    user.setAge(2);
    user.setEmail("[email protected]");

    //调用方法实现修改
    Query query = new Query(Criteria.where("_id").is(user.getId()));
    Update update = new Update();
    update.set("name",user.getName());
    update.set("age",user.getAge());
    update.set("email",user.getEmail());
    //调用mongoTemplate的修改方法实现修改
    UpdateResult upsert = mongoTemplate.upsert(query, update, User.class);
    long modifiedCount = upsert.getModifiedCount();//获取到修改受影响的行数
    System.out.println("受影响的条数:"+modifiedCount);
}
  • 删除数据
//删除条件
@Test
 public void deleteUser(){
     Query query = new Query(Criteria.where("_id").is("60b4b3ca861699233d33f3e2"));
     DeleteResult remove = mongoTemplate.remove(query, User.class);
     long deletedCount = remove.getDeletedCount();
     System.out.println("删除的条数:"+deletedCount);
 }//删除条件
 @Test
 public void deleteUser(){
     Query query = new Query(Criteria.where("_id").is("60b4b3ca861699233d33f3e2"));
     DeleteResult remove = mongoTemplate.remove(query, User.class);
     long deletedCount = remove.getDeletedCount();
     System.out.println("删除的条数:"+deletedCount);
 }
  • 索引
  • 创建索引
@Test
public void createAscendingIndex() {
 // 设置字段名称
   String field = "name";
   // 创建索引   升序
    mongoTemplate.getCollection("user").createIndex(Indexes.ascending(field));
 }
  • 移除索引
 @Test
  public void removeIndex() {
      // 设置字段名称
     String field = "name";
     // 删除索引
      mongoTemplate.getCollection("user").dropIndex(field);
  }
  • 查询所有索引
 @Test
public void getIndexAll() {
   // 获取集合中所有列表>
    ListIndexesIterable<Document> indexList = mongoTemplate.getCollection("user").listIndexes();
    // 获取集合中全部索引信息
    for (Document document : indexList) {
        System.out.println("索引列表:" + document);
    }
}

MongoDB事务
单节点 mongodb 不支持事务,需要搭建 MongoDB 复制集

;