• 数据库MongoDB


    MongoDB记录是一个文档,由一个字段和值对组成的数据结构,文档类似于JSON对象。
    一个文档认为就是一个对象,字段的数据类型是字符型,值除了使用基本类型外,还可以包括其他文档,普通数组和文档数组。
    在这里插入图片描述
    在这里插入图片描述

    一、下载安装、解压、创建存放数据文件的目录data/db

    ①、window安装
    在这里插入图片描述
    在这里插入图片描述

    启动方式:

    • 命令行参数方式启动,bin目录下打开命令提示符:mongod --dbpath=…\data\db 默认端口27017,可以通过–port来指定端口
    • 配置文件方式启动,在解压目录中创建config文件夹,该文件夹中新建配置文件mongod.conf
      在这里插入图片描述

    ②、Linux中通过docker安装

    docker pull mongo:latest
    
    # 创建和启动容器
    docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo
    
    # 查看
    docker ps
    
    # 进入容器
    docker exec -it mymongo /bin/bash
    
    # 使用客户端进行操作
    mongo
    
    # 查询当前mogodb中有哪些数据库
    show dbs
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    =========================================================================

    命令行进行连接:
    在这里插入图片描述

    图形化界面进行连接:
    在这里插入图片描述

    Linux系统中进行安装、启动、连接

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    ==============================================================

    基本常用命令

    在这里插入图片描述

    创建一个集合(table)

    db.createCollection("collName")
    
    # 得到指定名称的集合
    db.getCollection("user")
    
    • 1
    • 2
    • 3
    • 4

    向comment集合中插入一条数据并查询

    db.User.save({name:'jordan',age:23,sex:true})
    
    db.User.find() #查询所有
    
    db.User.find({name:"jordan"}) #查询指定名字的数据
    
    db.User.find({age:23},{'name':1,'age':1}) #查询age=23的,只显示name/age字段
    
    db.User.createIndex({"name":1}) # 添加索引
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果comment不存在,则会隐式创建
    数字默认是double类型,如果存整型,需要函数NumberInt()
    插入的数据没有指定_id,会自动生成主键值
    如果某字段没有值,可以赋值为null,或不写该字段

    db.comment.insert(
    	{
    		"articleid":"100000",
    		"content":"今天天气好晴朗,处处好风光",
    		"userid":"1001",
    		"nickname":"Rose",
    		"createdatetime":new Date(),
    		"likenum":NumberInt(10),
    		"state":null
    	}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    批量插入
    如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
    可以使用try{…}catch(e){print(e);}

    db.comment insertMany(
    	[
    		{"_id":"1","articleid":"100001","content":"天气晴朗","userid":"10002","nickname":"jordan","createdatetime":new Date("2008-08-01"),"likenum":NumberInt(1000),"state":"1"},
    		{},
    		{}
    	]
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    投影查询(只查询部分字段)

    db.comment.find(
    	{userid:"1003"},
    	{userid:1,nickname:1}
    )
    
    • 1
    • 2
    • 3
    • 4

    排序

    #1为升序排列,-1为降序排列
    db.User.find().sort({age:1}) 
    
    • 1
    • 2

    文档更新

    # 覆盖修改,修改_id为1,点赞量为1001
    db.comment.update({_id:"1"},{likenum:NumberInt(1001)}) 
    
    # 局部修改,修改_id为2,浏览量为889 
    db.comment.update({_id:2},{$set:{likenum:NumberInt(889)}})
    
    # 批量修改,更新所有用户为1003的用户的昵称
    db.comment.update({userid:"1003"},{$set:{nickname:"jordan"}}) # 默认只修改一条数据
    db.comment.update({userid:"1003"},{$set:{nickname:"jordan"}},{multi:true}) # 修改所有符合条件的数据
    
    # 列值增长的修改,对原有值的基础上进行增加或减少,可以使用$inc运算符
    # 对3号数据的点赞数,每次递增1
    db.comment.update({_id:"3"},{$inc:{linknum:NumberInt(1)}})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    分页查询

    db.comment.find().limit(3) # 查询3条记录,默认值20
    db.comment.find().skip(3) # 跳过3条记录,默认值0
    
    # 每页2个
    db.comment.find().skip(0).limit(2) # 第一页
    db.comment.find().skip(2).limit(2) # 第二页
    db.comment.find().skip(4).limit(2) # 第三页
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    正则表达式实现的模糊查询

    # 内容评论包含开水打的所有文档
    db.comment.find({content:/开水/})
    
    # 以专家开头的评论内容
    db.comment.find({content:/^专家/})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    比较查询

    # 评论点赞数大于700
    db.comment.find({linenum:{$gt:NumberInt(700)}})
    
    • 1
    • 2

    包含查询

    # 查询评论集合中userid字段包含1003或1004的文档
    db.comment.find({userid:{$in:["1003","1004"]}})
    
    # 不好含使用$nin操作符 查询集合中suerid字段不包含1003和1004的文档
    db.comment.find({userid:{$nin:["1003","1004"]}})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    条件连接查询

    # 查询评论集合中likenum大于等于700并且小于2000的文档 $and:[{},{}]
    db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]})
    
    # 或  $or:[{},{}]  查询评论集合中userid为1003,或者点赞数小于1000的文档记录
    db.comment.find({$or:[{userid:"1003"},{likenum:{$lt:1000}}]})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    删除操作

    db.User.remove(id) # 按照指定id移除
    
    db.User.remove() #移除所有
    
    • 1
    • 2
    • 3

    总结:
    在这里插入图片描述

    ====================================================================
    在这里插入图片描述

    创建索引

    # 单字段索引,对userid字段建立索引
    db.comment.createIndex({userid:1})
    
    # 复合字段索引,对userid和nickname同时建立复合索引
    db.comment.createIndex({userid:1,nickname:-1})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    移除索引

    # 删除userid字段上的升序索引
    db.comment.dropIndex({userid:1})
    
    # 删除所有索引(_id的字段是无法删除的,只能删除非_id字段的索引)
    db.comment.dropIndexes()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    执行计划

    # 根据userid查询数据的情况,建立的索引是否有效,效果如何
    db.comment.find({userid:"1003"}).explain()
    
    • 1
    • 2

    =================================================

    MongoDB集群和安全

    副本集的创建

    一、创建主节点

    二、创建副本节点

    三、创建仲裁节点

    四、初始化配置副本集和主节点

    五、查看副本集的配置内容和副本集的状态

    六、添加副本节点

    七、添加冲裁节点

    八、数据的读写

    故障测试

    =========================================================

    SpringBoot集成mongodb

    spring-data-mongodb提供了两种方式访问mongodb
    ①、MongoTemplate
    ②、MongoRepository 不够灵活,所以MongoTemplate弥补了不足

    一、添加依赖

    <dependency>
    	<groupId>org.springframework.bootgroupId>
    	<artifactId>spring-boot-starter-data-mongodbartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    二、application.properties配置文件添加连接信息

    spring.data.mongodb.uri=mongodb://47.93.118.241:27017/test
    
    • 1

    三、创建对应的实体类

    @Data
    @Document("User") //指定对应的mongodb对应的
    public class User{
    	@Id
    	private String id;
    	private String name;
    	private Integer age;
    	private String email;
    	private String createData;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、测试

    一、通过MongoTemplate实现对MongoDB的CRUD

    @SpringBootTest
    public class DemomogoApplicationTests{
    	
    	@Autowired
    	private MongoTemplate mongoTemplate;
    
    	//添加操作
    	@Test
    	public void create(){
    		User user = new User();
    		user.setAge(20);
    		user.setName("jordan");
    		user.setEmail("jordan@qq.com");
    
    		User user = mongoTemplate.insert(user);//返回添加后的数据
    		
    	}
    
    	//查询所有记录
    	@Test
    	public void findAll(){
    		List<User> all = mongoTemplate.findAll(User.class);
    		System.out.println(all);
    	}
    
    	//根据id查询
    	@Test
    	public void findById(){
    		User user = mongoTemplate.findById("id",User.class);
    	}
    	
    	//条件查询
    	@Test
    	public void findUserList(){
    		Query query = new Query(Criteria.where("name").is("jordan").and("age").is(23));
    		mongoTemplate.find(query,User.class);
    	}
    
    	//模糊查询
    	@Test
    	public void findLikeUserList(){
    		
    		String name = "jor";
    		String regex = String.format("%s%s%s","^.*",name,".*$");
    		Pattern pattern = Pattern.compile(regex.Pattern.CASE_INSENSTIVE);
    		
    		Query query = new Query(Criteria.where("name").regex(pattern));
    		mongoTemplate.find(query,User.class);
    	}
    
    	//分页查询
    	@Test
    	public void findPageUserList(){
    		int pageNo = 1; //当前页
    		int pageSize = 3; //每页显示数
    
    		String name = "jor";
    		String regex = String.format("%s%s%s","^.*",name,".*$");
    		Pattern pattern = Pattern.compile(regex.Pattern.CASE_INSENSTIVE);
    		
    		Query query = new Query(Criteria.where("name").regex(pattern));
    
    		//分页构建
    		//查询记录数(当前页=(pageNo - 1)*pageSize)
    		long count = mongoTemplate.count(query,User.class);
    		List<User> users = mongoTemplate.find(query,skip((pageNo - 1)*pageSize).limit(pageSize),User.class);
    	}
    
    	//修改操作
    	@Test
    	public void updateUser(){
    		//1.根据id查询
    		User user = mongoTemplate.findById("id",User.class);
    		//2.设置修改值
    		user.setName("kobe");
    		user.setAge(24);
    		user.setEmail("kobe@qq.com");
    		//3.调用方式实现修改
    		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());
    		UpdateResult upsert = mongoTemplate.upsert(query,update,User.class);
    		long modifiedCount = upsert.getModifiedCount();//影响的行数
    	}
    
    	//删除操作
    	@Test
    	public void deleteUser(){
    		Query query = new Query(Criteria.where("_id").is("id获取"));
    		DeleteResult remove = mongoTemplate.remove(query,User.class);
    		long deletedCount = remove.getDeleteCount();
    		System.out.println(deletedCount);
    	}
    }
    
    • 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

    实战案例

    public Map<String,Object> getRuleSchedule(long page,long limit,String hoscode,String depcode){
    	
    	//1. 根据医院编号和科室编号查询
    	Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode);
    
    	//2. 根据工作日期workData进行分组
    	Aggregation agg = Aggregation.newAggregation(
    		Aggregation.match(criteria),//匹配条件
    		Aggregation.group("workDate")//分组字段
    			.first("workDate").as("workData")//添加别名
    			.count().as("docCount")//统计号源数量
    			.sum("reservedNumber").as("reservedNumber")
    			.sum("availableNumber").as("availabeNumber"),
    		Aggregation.sort(Sort.Direction.DESC,"workData"),//排序字段
    		Aggregation.skip((page-1)*limit),//实现分页(当前页)
    		Aggregation.limit(limit)
    	);
    	
    	//调用方法,传递三个参数(条件,实体类,返回类)
    	AggregationResults<BookingScheduleRuleVo> aggResults = mongoTemplate.aggregate(agg,Schedule.class,BookingSchedleRuleVo.class);
    
    	List<BooingScheduleRuleVo> mappedResults = aggResults.getMappedResults();
    
    	//分组查询总记录数
    	Aggregation totalAgg = Aggregation.newAggregation(
    		Aggregation.match(criteria),
    		Aggregation.group("workDate")
    	);
    	AggregationResults<BookingScheduleRuleVo> totalAggresults = mongoTemplate.aggregate(agg,Schedule.class,BookingSchedleRuleVo.class);
    	int total = totalAggResults.getMappedResults().size();
    
    	//
    }
    
    • 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

    二、通过MongoRepository实现对MongoDB的CRUD

    SpringData提供了对mongodb的数据访问支持,只需要继承MongoRepository

    ①、创建一个接口继承MongoRepository

    public interface UserRepository extends MongoRepository<User,String>{
    
    }
    
    • 1
    • 2
    • 3

    ②、将上面的接口注入到业务类中

    @Autowired
    private UserRepository userRepository;
    
    //添加操作
    @Test
    public void create(){
    	User user = new User();
    	user.setAge(16);
    	user.setName("james");
    	user.setEmail("james.qq.com");
    
    	User u = userRepository.save(user);
    }
    
    //查询所有
    @Test
    public void findId(){
    	List<Uer> all = userRepository.findAll();
    }
    
    //根据id查询
    @Test
    public void findId(){
    	User user = userRepository.findById("id值").get();
    }
    
    //条件查询
    @Test
    public void findUserList(){
    	User user = new User();
    	user.setAge(23);
    	user.setName("jordan");
    	Example<User> userExample = Example.of(user);
    	List<User> all = userRepository.findAll(userExample);
    }
    
    //模糊查询
    @Test
    public void findLikeUserList(){
    
    	//设置模糊查询的匹配规则(设置模糊查询,忽略大小写)
    	ExampleMatcher matcher = ExampleMatcher.matching()
    		.withStringMatcher(ExampleMather.StringMatcher.CONTAINING)
    		.withIgnoreCase(true);
    	
    	User user = new User();
    	user.setAge(23);
    	user.setName("jor");
    	Example<User> userExample = Example.of(user,matcher);
    	List<User> all = userRepository.findAll(userExample);
    }
    
    //分页查询
    @Test
    public void findPageUserList(){
    	//设置分页参数
    	//0代表第一页
    	Pageable pageable = PageRequest.of(0,3);
    	
    	User user = new User();
    	user.setName("jordan");
    	Example<User> userExample = Example.of(user);
    	Page<User> page = userRepository.findAll(userExample,pageable);  
    	page.getTotalPages();//总页数
    }
    
    //修改
    @Test
    public void updateUser(){
    	User user = userRepository.findById("id值").get();
    	user.setAge(100);
    	user.setName("jordan");
    	user.setEmail("jordan@qq.com");
    	User save = userRepository.save();//如果有id表示修改,没有id表示保存
    }
    
    //删除
    @Test
    public void deleteUser(){
    	userRepository.deleteById("id值");
    }
    
    • 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

    MongoDB读写方式

    方式一:MongoRepository接口

    ①、定义UserRepository接口类文件

    若查询一些数据,只需要按照格式写一个接口名和对应的参数即可

    @Repository
    public interface UserRepository extends MongoRepository<BootUser,String>{
    	
    	public BootUser save(BootUser user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ②、定义UserService接口类文件

    public interface UserService{
    	
    	public void save(BootUser user);
    }
    
    • 1
    • 2
    • 3
    • 4
    @Service
    public class UserServiceImpl implements UserService{
    	
    	@Autowired
    	private UserRepository userRepository;
    
    	public void save(BootUser user){
    		userRepository.save(user);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ③、Controller

    @RestController
    public class HelloWorldController {
    
        @Autowired
        private UserService userService;
           
        @RequestMapping("save")
        public boolean save(){
            // 插入数据
            BootUser user = new BootUser();
            user.setId("003");
            user.setName("素文宅博客");
            user.setDetail("003关注“Java精选”微信公众号,一起进步!");
            userService.save(user);
            return true;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    启动项目,访问地址 http://localhost:8080/save
    返回true,数据已存储到MongoDB数据库,如图所示:
    在这里插入图片描述

    方式二:使用MongoTemplate

    ①、Spring Boot会自动注入mongotemplate

    直接修改Controller

    @RestController
    public class HelloWorldController {
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private MongoTemplate mongotemplate;
           
        @RequestMapping("save")
        public boolean save(){
            // 插入数据
            BootUser user = new BootUser();
            user.setId("003");
            user.setName("素文宅博客");
            user.setDetail("003关注“Java精选”微信公众号,一起进步!");
            mongotemplate.save(user);
            return true;
        }
    
        @RequestMapping("select")
        public String select(String id){
            //查询数据
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(id));
            String detail = mongotemplate.findOne(query, BootUser.class).getDetail();
            return detail;
        }
    
    }
    
    • 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
  • 相关阅读:
    ADB底层原理
    prostate数据集下载
    侯捷 - C++ Startup 揭密:C++ 程序的生前和死后 (四)
    vue项目中定制化音频展示,wavesurfer.js基本使用
    对于工作中复杂的业务,使用mabatis-plus加分页插件的话,有时候得不到自己想要的
    linux指令总结
    Unity 代码控制Text文本换行
    拼多多商品详情页API接口、拼多多商品销量API接口、拼多多商品列表API接口、拼多多APP详情API接口、拼多多详情API接口
    高等教育学:课程
    2022-08-20 C++并发编程(十三)
  • 原文地址:https://blog.csdn.net/usa_washington/article/details/131138054