MongoDB入门与实战-第四章-SpringBoot集成MongoDB

参考

SpringBoot 整合 MongoDB 实战解说

MongoDB 连接

Java 连接 MongoDB 服务器,与我们常用的连接关系型数据库方式类似!

标准 URI 连接语法:

mongodb://username:password@host1:port1,host2:port2,...,hostN:portN/database?options

参数说明:

  • mongodb://:这是固定的格式,必须要指定
  • username:password@:可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登录这个数据库
  • host1:port1:主机IP和端口号,必须指定至少一个host。如果要连接复制集,请指定多个主机地址
  • /database:如果指定了username:password@,连接时会验证并登录指定数据库。若不指定,默认打开 test 数据库
  • ?options:连接可选项,例如connectTimeoutMS=5000ms,表示连接等待时间最长 5 秒

例如,无密码连接 MongoDB

mongodb://127.0.0.1:27017

使用用户名test,密码test登录 MongoDB 的test_db数据库

mongodb://test:test@127.0.0.1:27017/test_db

无密码连接指定三台服务器 (端口 27017, 27018, 和27019)

mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019

java客户端方式

在这里插入图片描述

引入驱动依赖

参考:https://docs.mongodb.com/drivers/java/

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.12.7</version>
</dependency>

测试创建客户端

public class MongoDBTest {
    private static final String MONGO_URL = "localhost";
    private MongoClient mongoClient = null;

    @Test
    public void testDb(){
        // 连接到数据库
        MongoDatabase mongoDatabase = mongoClient.getDatabase("test_iot");
        System.out.println("Connect to database successfully");
        mongoDatabase.createCollection("tower_crane_property");
        System.out.println("集合创建成功");
    }

    @BeforeEach
    public void initClient(){
        //连接到MongoDB服务,如果不指定库名,则需要admin的账号密码 如果是远程连接可以替换“localhost”为服务器所在IP地址
        mongoClient = MongoClients.create("mongodb://admin:123456@192.168.0.44:27017");
        // 指定库
        mongoClient = MongoClients.create("mongodb://admin:123456@192.168.0.44:27017/iot");
        // 增加库在哪里认证,在哪里创建
        mongoClient = MongoClients.create("mongodb://admin:123456@192.168.0.44:27017/iot?authSrouce=admin");
        
    }
}

创建集合

可以通过ValidationOptions增加字段校验,也可以指定集合大小
在这里插入图片描述

查询文档

/**
     * 查询文档
     */
    @Test
    public void testQuery() {
        // 连接到数据库
        MongoDatabase mongoDatabase = mongoClient.getDatabase("iot");
        System.out.println("Connect to database successfully");
        //获取集合
        MongoCollection<org.bson.Document> collection = mongoDatabase.getCollection("device");

        //遍历所有文档
        FindIterable<org.bson.Document> findIterable = collection.find();
        MongoCursor<org.bson.Document> mongoCursor = findIterable.iterator();
        while(mongoCursor.hasNext()){
            System.out.println(mongoCursor.next());
        }

        //查询当前集合所有文档数量
        long count = collection.countDocuments();
        System.out.println("当前文档数量:" + count);

        //带条件遍历文档
        FindIterable<Document> documentFindIterable = collection.find(Filters.eq("code", "manager"));
        MongoCursor<Document> documentMongoCursor = documentFindIterable.iterator();
        while(documentMongoCursor.hasNext()){
            System.out.println(documentMongoCursor.next());
        }
    }

查询集合大小

//查询当前集合所有文档数量
long count = collection.countDocuments();

条件查询

在这里插入图片描述

排序

在这里插入图片描述

投影

在这里插入图片描述

聚合查询

对stars分组并计数
在这里插入图片描述

复合聚合

excludeId不显示id,只显示firstCategory字段,这个字段是显示categories索引小标0的值,也就是categories中第一个值
在这里插入图片描述
效果
在这里插入图片描述

插入文档

/**
     * 测试插入
     */
    @Test
    public void testInsert(){
        // 连接到数据库
        MongoDatabase mongoDatabase = mongoClient.getDatabase("iot");
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("device");

        //向集合中插入文档
        Document document = new Document("name", "管理员").
                append("code", "manager").
                append("sort", 100).
                append("lat", 22.81503471517295).
                append("lng", 108.37301005337522);
        List<Document> documents = new ArrayList<>();
        documents.add(document);
        collection.insertMany(documents);
        System.out.println("文档插入成功");
    }

批量插入

在这里插入图片描述

更新文档

在这里插入图片描述

删除文档

在这里插入图片描述

SpringDataMongoDB

添加依赖


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

配置文件

server:
  port: 8083

spring:
  data:
    mongodb:
      # 服务器地址
      host: 192.168.0.44
      # 端口
      port: 27107
      # 用户名
      username: iot_admin
      # 密码
      password: iot_admin
      # 认证数据库
      authentication-database: iot
      # 操作数据库
      database: iot

新建实体映射

在这里插入图片描述

插入文档

在这里插入图片描述

修改文档

在这里插入图片描述

/**
     * 更新对象
     * @param user
     */
    @Override
    public void updateUser(UserEntity user) {
        Query query=new Query(Criteria.where("id").is(user.getId()));
        Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord());
        //更新查询返回结果集的第一条
        mongoTemplate.updateFirst(query,update,UserEntity.class);
        //更新查询返回结果集的所有
        // mongoTemplate.updateMulti(query,update,UserEntity.class);
    }

删除

/**
     * 删除对象
     * @param id
     */
    @Override
    public void deleteUserById(Long id) {
        Query query=new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query,UserEntity.class);
    }
/***********方法二************/
/**
     * 删除
     *
     * @param id id
     * @return ApiResponse
     */
    public ApiResponse delete(String id) {
        try {
            Query query = new Query(Criteria.where("_id").is(id));
            DeleteResult result = mongoTemplate.remove(query, Student.class);
            long count = result.getDeletedCount();
            if (count > 0) {
                return Api.ok(count, "删除成功");
            }
            throw new ServiceException(-1, String.format("【%s】%s", id, "不存在"));
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            throw new SystemException(-1, "删除出错");
        }

高级查询

查询某一天的数据

public PageDTO<ElevatorAlarmDTO> findTodayList(DevicePageQueryDTO param) {
        /*
        相差8个时区
        24 = 16 + 8
        db.getCollection("elevator_alarm").find({deviceCode:"1589581864182480897",timestamp:{"$gte":ISODate("2022-11-07T16:00:00.000Z")}}).sort({timestamp:-1})

         */
//        todayStr = todayStr + "T16:00:00.000Z";
        PageDTO<ElevatorAlarmDTO> result = new PageDTO<>();
        int pageIndex = param.getPageIndex();
        int pageSize = param.getPageSize();
        result.setPageSize(pageSize);
        //mongodb查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where(IotConstant.FIELD_DEVICE_CODE).is(param.getDeviceCode()));

        String todayStr = DateUtil.date().toDateStr();
        Date today = DateUtil.parseDateTime(todayStr+" 00:00:00");
        query.addCriteria(Criteria.where(IotConstant.FIELD_TIME).gte(today));
        // 如下两种写法不可以
//        query.addCriteria(Criteria.where(IotConstant.FIELD_TIMESTAMP).gte("ISODate(\""+todayStr+"\")"));
//        query.addCriteria(Criteria.where(IotConstant.FIELD_TIMESTAMP).gte("ISODate(2022-11-07T16:00:00.000Z)"));
        long count = mongoTemplate.count(query,getClazz());
        result.setTotalCount(count);
        if (count > 0){
            long pageCount = (count+pageSize-1)/pageSize;
            result.setPageCount(pageCount);
            query.skip((long) (pageIndex - 1) * pageSize).limit(pageSize);
            Sort sort = Sort.by(new Sort.Order(Sort.Direction.DESC, IotConstant.FIELD_TIME));
            query.with(sort);
            List<ElevatorAlarmDoc> data = mongoTemplate.find(query,getClazz());
            if(data.size() > 0){
                List<ElevatorAlarmDTO> rows = data.stream().map(ElevatorAlarmDoc::toDTO).collect(Collectors.toList());
                result.setRows(rows);
            }
        }
        return result;
    }

统计最近七天趋势

public List<AlarmResultDTO> getAlarmWeekTrend(DeviceCodeQueryDTO param) {
        /*
         * db.getCollection("elevator_alarm").aggregate([ { "$match" : { "deviceCode" : "1589581864182480897"}}, { "$match" : { "timestamp" : { "$gte" : new Date("2022-11-02 00:00:00" ) } } }, { "$match" : { "timestamp" : { "$lte" : new Date("2022-11-08 23:59:59" )} } }, { "$project" : { "timestamp" : 1, "date" : { "$dateToString" : { "format" : "%Y-%m-%d", "date" : "$timestamp"}}}}, { "$group" : { "_id" : "$date", "count" : { "$sum" : 1}}}, { "$project" : { "count" : 1, "date" : "$_id"}}, { "$sort" : { "date" : 1}} ])
         */
        String deviceCode = param.getDeviceCode();
        DateTime today = DateUtil.date();
        DateTime startDate = DateUtil.parseDateTime(DateUtil.offsetDay(today,-7).toDateStr()+" 00:00:00");
        DateTime endDate = DateUtil.parseDateTime(today.toDateStr()+" 23:59:59");
        // 如下两种方式都可以
        //ProjectionOperation return1 = Aggregation.project(IotConstant.FIELD_TIME).andExpression("{$dateToString:{ format:'%Y-%m-%d',date: '$timestamp', timezone: 'Asia/Shanghai'}}").as("date");
        ProjectionOperation return1 = Aggregation.project(IotConstant.FIELD_TIME).and(DateOperators.DateToString.dateOf(IotConstant.FIELD_TIME).toString("%Y-%m-%d")).as("date");
        // 返回参数2,//如果不加这条,输出的结果如: [{"count": 3, "_id": "2019-12-13"}]
        ProjectionOperation return2 = Aggregation.project("count").and("_id").as("date");
        GroupOperation group = Aggregation.group("date").count().as("count");
        Aggregation aggregation = Aggregation.newAggregation(

                //where条件
                Aggregation.match(Criteria.where(IotConstant.FIELD_DEVICE_CODE).is(deviceCode)),
                //时间范围
                Aggregation.match(Criteria.where(IotConstant.FIELD_TIME).gte(startDate)),
                Aggregation.match(Criteria.where(IotConstant.FIELD_TIME).lte(endDate)),
                //将时间戳格式化并重命名
                //Aggregation.project("date").andExpression("{$dateToString: {date: { $add: {'$createTime', [0]} }, format: '%Y-%m-%d'}}", new Date(28800000)).as("date"),
                return1,
                // 返回参数
                //分组统计
                group,
                return2,

                //加上为:                   [{"count": 3, "date": "2019-12-13"}]
//                Aggregation.project("date", "count").and("date").previousOperation(),
                //排序
                Aggregation.sort(Sort.Direction.ASC, "date"));


        // 分组聚合查询
        AggregationResults<AlarmResultDTO> aggregate = mongoTemplate.aggregate(aggregation,
                ElevatorAlarmDoc.class, AlarmResultDTO.class);
        // 获取结果
        List<AlarmResultDTO> list = aggregate.getMappedResults();
        List<AlarmResultDTO> result = new ArrayList<>();
        Map<String,Long> resultMap = new HashMap<>();
        if(list.size() > 0){
            list.forEach(i->{resultMap.put(i.getDate(),i.getCount());});
        }
        for(int i = 0;i<7;i++){
            DateTime d = startDate.offsetNew(DateField.DAY_OF_YEAR,i+1);
            AlarmResultDTO item = new AlarmResultDTO();
            item.setDate(d.toDateStr());
            Long count = resultMap.get(d.toDateStr());
            item.setCount(count == null?0:count);
            result.add(item);
        }
        log.info("趋势:{}",result);
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值