在SpringBoot项目中集成MongoDB

文章目录

  • 1. 准备工作
  • 2. 在SpringBoot项目中集成MongoDB
    • 2.1 引入依赖
    • 2.2 编写配置文件
    • 2.3 实体类
  • 3. 测试
  • 4. 文档操作
    • 4.1 插入操作
      • 4.1.1 单次插入
      • 4.1.2 批量插入
    • 4.2 查询操作
      • 4.2.1 根据id查询
      • 4.2.2 根据特定条件查询
      • 4.2.3 正则查询
      • 4.2.4 查询所有文档
      • 4.2.5 排序后返回
    • 4.3 删除操作
      • 4.3.1 根据id删除
      • 4.3.2 根据特定条件删除
    • 4.4 修改操作
      • 4.4.1 修改符合条件的第一条文档(updateFirst)
      • 4.4.2 修改符合条件的所有文档(updateMulti)
  • 5. 完整的测试代码

阅读本文前可以先阅读以下文章:

  • MongoDB快速入门(MongoDB简介、MongoDB的应用场景、MongoDB中的基本概念、MongoDB的数据类型、MongoDB的安装与部署、MongoDB的常用命令)
  • MongoDB的常用命令(数据库操作、集合操作、文档操作)

1. 准备工作

假设我们在做一个与自媒体相关的项目,项目引入了 MongoDB 存储与文章的评论数据

数据库名称为 article,集合名称为 comment,以下是可能用到的字段

字段名称字段含义字段类型备注
_idIDObjectId或StringMongoDB文档的唯一标识符,作为主键使用
article_id文章IDString文章的唯一标识符,用于关联评论和文章
content评论内容String用户发表的评论文本内容
user_id评论人IDString发表评论的用户唯一标识符
nickname评论人昵称String发表评论的用户昵称,用于显示在评论列表中
create_time评论的日期时间Date评论创建的时间,格式通常为ISO日期时间格式
like_number点赞数Int32评论获得的点赞数量,反映评论的受欢迎程度
reply_number回复数Int32评论下方的回复数量,反映评论的互动程度
state状态String评论的可见状态,'0’表示评论不可见,'1’表示评论可见
parent_id上级IDString评论的上级评论ID,如果为’0’或空,则表示该评论是顶级评论,没有上级评论

先创建一个名为 article 的数据库

use comment

接着运行以下 SQL,插入测试数据

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MongoDB
 Source Server Version : 80003 (8.0.3)
 Source Host           : localhost:27017
 Source Schema         : test

 Target Server Type    : MongoDB
 Target Server Version : 80003 (8.0.3)
 File Encoding         : 65001

*/


// ----------------------------
// Collection structure for comment
// ----------------------------
db.getCollection("comment").drop();
db.createCollection("comment");
db.getCollection("comment").createIndex({
    user_id: NumberInt("1")
}, {
    name: "user_id_1"
});

// ----------------------------
// Documents of comment
// ----------------------------
db.getCollection("comment").insertOne({
    _id: ObjectId("6728a523d9496fae23c4c2a9"),
    article_id: NumberInt("100000"),
    content: "今天天气真好,阳光明媚",
    user_id: "1001",
    nickname: "Rose",
    create_time: ISODate("2024-11-04T10:42:43.056Z"),
    like_number: NumberInt("10"),
    state: null
});

db.getCollection("comment").insertOne({
    _id: "2",
    article_id: "100001",
    content: "我夏天空腹喝凉开水,冬天喝温开水",
    user_id: "1005",
    nickname: "伊人憔悴",
    create_time: ISODate("2019-08-05T23:58:51.485Z"),
    like_number: NumberInt("2422"),
    state: "1"
});

db.getCollection("comment").insertOne({
    _id: "3",
    article_id: "100001",
    content: "我一直喝凉开水,冬天夏天都喝。",
    user_id: "1004",
    nickname: "杰克船长",
    create_time: ISODate("2019-08-06T01:05:06.321Z"),
    like_number: NumberInt("667"),
    state: "1"
});

db.getCollection("comment").insertOne({
    _id: "4",
    article_id: "100001",
    content: "专家说不能空腹吃饭,影响健康。",
    user_id: "1003",
    nickname: "凯撒大帝",
    create_time: ISODate("2019-08-06T08:18:35.288Z"),
    like_number: NumberInt("2000"),
    state: "1"
});

db.getCollection("comment").insertOne({
    _id: "5",
    article_id: "100001",
    content: "研究表明,刚烧开的水千万不能喝,因为烫嘴。",
    user_id: "1003",
    nickname: "凯撒大帝",
    create_time: ISODate("2019-08-06T11:01:02.521Z"),
    like_number: NumberInt("3000"),
    state: "1"
});

2. 在SpringBoot项目中集成MongoDB

本次演示使用的环境为:JDK 17.0.7 + SpringBoot 3.0.2

2.1 引入依赖

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

2.2 编写配置文件

application.yml

server:
  port: 11006

spring:
  data:
    mongodb:
      database: article
      host: 127.0.0.1
      port: 27017
#      username:
#      password:

2.3 实体类

  • 在Spring Data MongoDB中,@Field注解用于指定文档中字段的名称,这在字段名称与MongoDB集合中存储的字段名称不一致时非常有用
  • 如果实体类的字段名称与MongoDB文档中的字段名称相同,那么不需要使用@Field注解
  • 通过 @Document 注解指定集合名称
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.util.Date;

/**
 * Comment 实体类,用于映射MongoDB中的 comment 集合。
 */
@Document(collection = "comment")
public class Comment {

    /**
     * MongoDB文档的唯一标识符,作为主键使用。
     */
    @Id
    private String id;

    /**
     * 文章的唯一标识符,用于关联评论和文章。
     */
    @Field("article_id")
    private String articleId;

    /**
     * 用户发表的评论文本内容。
     */
    private String content;

    /**
     * 发表评论的用户唯一标识符。
     */
    @Field("user_id")
    private String userId;

    /**
     * 发表评论的用户昵称,用于显示在评论列表中。
     */
    private String nickname;

    /**
     * 评论创建的时间,格式通常为ISO日期时间格式。
     */
    @Field("create_time")
    private Date createTime;

    /**
     * 评论获得的点赞数量,反映评论的受欢迎程度。
     */
    @Field("like_number")
    private Integer likeNumber;

    /**
     * 评论下方的回复数量,反映评论的互动程度。
     */
    @Field("reply_number")
    private Integer replyNumber;

    /**
     * 评论的可见状态,'0’表示评论不可见,'1’表示评论可见。
     */
    private String state;

    /**
     * 评论的上级评论ID,如果为’0’或空,则表示该评论是顶级评论,没有上级评论。
     */
    @Field("parent_id")
    private String parentId;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getArticleId() {
        return articleId;
    }

    public void setArticleId(String articleId) {
        this.articleId = articleId;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Integer getLikeNumber() {
        return likeNumber;
    }

    public void setLikeNumber(Integer likeNumber) {
        this.likeNumber = likeNumber;
    }

    public Integer getReplyNumber() {
        return replyNumber;
    }

    public void setReplyNumber(Integer replyNumber) {
        this.replyNumber = replyNumber;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id='" + id + '\'' +
                ", articleId='" + articleId + '\'' +
                ", content='" + content + '\'' +
                ", userId='" + userId + '\'' +
                ", nickname='" + nickname + '\'' +
                ", createTime=" + createTime +
                ", likeNumber=" + likeNumber +
                ", replyNumber=" + replyNumber +
                ", state='" + state + '\'' +
                ", parentId='" + parentId + '\'' +
                '}';
    }
    
}

3. 测试

  • 在 SpringBoot 中操作 MongoDB,可以使用 MongoRepository 对象,也可以使用 MongoTemplate 对象
  • MongoRepository是基于 Spring Data 的 Repository 抽象,它提供了一套标准的数据访问方法,使得 CRUD 操作变得非常简单
  • 如果需要进行复杂的查询或需要细粒度的控制,MongoTemplate 可能是更好的选择

我们编写一个测试类,在测试类中注入 MongoTemplate 对象(与使用 RedisTemplate 类似)

import com.mongodb.client.MongoDatabase;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

@SpringBootTest
class MongodbApplicationTests {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void showCurrentDatabase() {
        MongoDatabase db = mongoTemplate.getDb();
        System.out.println("db.getName() = " + db.getName());
    }

    @Test
    public void showAllCollections() {
        mongoTemplate.getCollectionNames().forEach(System.out::println);
    }

}

4. 文档操作

4.1 插入操作

4.1.1 单次插入

@Test
public void testInsert() {
    Comment comment = new Comment();

    comment.setArticleId("article123");
    comment.setContent("这是一个很好的文章!");
    comment.setUserId("1003");
    comment.setNickname("评论者A");
    comment.setCreateTime(new Date());
    comment.setLikeNumber(10);
    comment.setReplyNumber(2);
    comment.setState("1");
    comment.setParentId("0");

    mongoTemplate.insert(comment);
    // 拿到插入后的评论ID
    System.out.println("tempComment.getId() = " + comment.getId());
}

4.1.2 批量插入

@Test
public void testInsertAll() {
    List<Comment> commentList = new ArrayList<>();

    for (int i = 0; i < 5; i++) {
        Comment comment = new Comment();
        comment.setArticleId("article" + (i + 1));
        comment.setContent("这是第 " + (i + 1) + " 条评论内容");
        comment.setUserId(String.valueOf(1003));
        comment.setNickname("评论者" + (i + 1));
        comment.setCreateTime(new Date());
        comment.setLikeNumber(5 + i); // 假设点赞数从5开始递增
        comment.setReplyNumber(0); // 假设初始回复数为0
        comment.setState("1"); // 假设所有评论都是可见的
        comment.setParentId("0"); // 假设所有评论都是顶级评论

        commentList.add(comment);
    }

    // 批量插入评论
    mongoTemplate.insertAll(commentList);
}

4.2 查询操作

分页参数和跳过多少条文档需要通过 Query 对象指定

4.2.1 根据id查询

@Test
public void testFindById() {
    Comment comment = mongoTemplate.findById("2", Comment.class);
    System.out.println("comment = " + comment);
}

4.2.2 根据特定条件查询

@Test
public void testFindByUserIdAndCreateTime() {
    String userId = "1003";
    Query query = new Query();
    Criteria criteria = Criteria.where("user_id").is(userId).and("create_time").lte(new Date());
    query.addCriteria(criteria)
            .skip(0)
            .limit(5);
    List<Comment> commentList = mongoTemplate.find(query, Comment.class);
    commentList.forEach(System.out::println);
}

4.2.3 正则查询

@Test
public void testFindByRegex() {
    String keyword = "开水";

    Query query = new Query();
    Criteria criteria = Criteria.where("content").regex(keyword);
    query.addCriteria(criteria);

    List<Comment> commentList = mongoTemplate.find(query, Comment.class);
    commentList.forEach(System.out::println);
}

4.2.4 查询所有文档

@Test
public void testFindALl() {
    List<Comment> commentList = mongoTemplate.findAll(Comment.class);
    commentList.forEach(System.out::println);
}

4.2.5 排序后返回

在这里插入图片描述

@Test
public void testFindByArticleIdWithCreatedTimeAsc() {
    String articleId = "100001";

    Criteria criteria = Criteria.where("article_id").is(articleId)
            .and("create_time").lte(new Date());

    Query query = new Query();
    query.addCriteria(criteria)
            .with(Sort.by(Sort.Order.asc("create_time")));

    List<Comment> commentList = mongoTemplate.find(query, Comment.class);
    commentList.forEach(System.out::println);
}

4.3 删除操作

4.3.1 根据id删除

@Test
public void testDeleteById() {
    Criteria criteria = Criteria.where("_id").is("2");
    DeleteResult deleteResult = mongoTemplate.remove(new Query(criteria), Comment.class);
    System.out.println("deleteResult.getDeletedCount() = " + deleteResult.getDeletedCount());
}

4.3.2 根据特定条件删除

@Test
public void testDeleteByUserIdAndCreateTime() {
    String userId = "1003";
    Date date = new Date();
    // 删除两分钟以内发布的评论
    date.setTime(date.getTime() - 2 * 60 * 1000);

    Query query = new Query();
    Criteria criteria = Criteria.where("user_id").is(userId)
            .and("create_time").gte(date).lte(new Date())
            .and("state").is("1");
    query.addCriteria(criteria);

    DeleteResult deleteResult = mongoTemplate.remove(query, Comment.class);
    System.out.println("deleteResult.getDeletedCount() = " + deleteResult.getDeletedCount());
}

4.4 修改操作

4.4.1 修改符合条件的第一条文档(updateFirst)

@Test
public void testUpdateFirst() {
    Comment comment = new Comment();
    comment.setId("6728a523d9496fae23c4c2a9");
    comment.setLikeNumber(102);

    Query query = new Query();
    query.addCriteria(Criteria.where("_id").is(comment.getId()));

    Update update = new Update();
    update.set("like_number", comment.getLikeNumber());

    UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Comment.class);
    System.out.println("updateResult.getMatchedCount() = " + updateResult.getMatchedCount());
    System.out.println("updateResult.getModifiedCount() = " + updateResult.getModifiedCount());
}

4.4.2 修改符合条件的所有文档(updateMulti)

@Test
public void testUpdateMulti() {
    Query query = new Query();
    Criteria criteria = Criteria.where("article_id").is("100001").and("state").is("1");
    query.addCriteria(criteria);

    Update update = new Update();
    update.set("nickname", "聂可以");

    UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Comment.class);
    System.out.println("updateResult.getMatchedCount() = " + updateResult.getMatchedCount());
    System.out.println("updateResult.getModifiedCount() = " + updateResult.getModifiedCount());
}

5. 完整的测试代码

import cn.edu.scau.pojo.Comment;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
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 java.util.ArrayList;
import java.util.Date;
import java.util.List;

@SpringBootTest
class MongodbApplicationTests {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void showCurrentDatabase() {
        MongoDatabase db = mongoTemplate.getDb();
        System.out.println("db.getName() = " + db.getName());
    }

    @Test
    public void showAllCollections() {
        mongoTemplate.getCollectionNames().forEach(System.out::println);
    }

    @Test
    public void testInsert() {
        Comment comment = new Comment();

        comment.setArticleId("article123");
        comment.setContent("这是一个很好的文章!");
        comment.setUserId("1003");
        comment.setNickname("评论者A");
        comment.setCreateTime(new Date());
        comment.setLikeNumber(10);
        comment.setReplyNumber(2);
        comment.setState("1");
        comment.setParentId("0");

        mongoTemplate.insert(comment);
        // 拿到插入后的评论ID
        System.out.println("tempComment.getId() = " + comment.getId());
    }

    @Test
    public void testInsertAll() {
        List<Comment> commentList = new ArrayList<>();

        for (int i = 0; i < 5; i++) {
            Comment comment = new Comment();
            comment.setArticleId("article" + (i + 1));
            comment.setContent("这是第 " + (i + 1) + " 条评论内容");
            comment.setUserId(String.valueOf(1003));
            comment.setNickname("评论者" + (i + 1));
            comment.setCreateTime(new Date());
            comment.setLikeNumber(5 + i); // 假设点赞数从5开始递增
            comment.setReplyNumber(0); // 假设初始回复数为0
            comment.setState("1"); // 假设所有评论都是可见的
            comment.setParentId("0"); // 假设所有评论都是顶级评论

            commentList.add(comment);
        }

        // 批量插入评论
        mongoTemplate.insertAll(commentList);
    }


    @Test
    public void testFindById() {
        Comment comment = mongoTemplate.findById("2", Comment.class);
        System.out.println("comment = " + comment);
    }

    @Test
    public void testFindALl() {
        List<Comment> commentList = mongoTemplate.findAll(Comment.class);
        commentList.forEach(System.out::println);
    }

    @Test
    public void testFindByRegex() {
        String keyword = "开水";

        Query query = new Query();
        Criteria criteria = Criteria.where("content").regex(keyword);
        query.addCriteria(criteria);

        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        commentList.forEach(System.out::println);
    }

    @Test
    public void testFindByUserIdAndCreateTime() {
        String userId = "1003";
        Query query = new Query();
        Criteria criteria = Criteria.where("user_id").is(userId).and("create_time").lte(new Date());
        query.addCriteria(criteria)
                .skip(0)
                .limit(5);
        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        commentList.forEach(System.out::println);
    }

    @Test
    public void testFindByArticleIdWithCreatedTimeAsc() {
        String articleId = "100001";

        Criteria criteria = Criteria.where("article_id").is(articleId)
                .and("create_time").lte(new Date());

        Query query = new Query();
        query.addCriteria(criteria)
                .with(Sort.by(Sort.Order.asc("create_time")));

        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        commentList.forEach(System.out::println);
    }

    @Test
    public void testDeleteById() {
        Criteria criteria = Criteria.where("_id").is("672a88601f90870e2451905a");
        DeleteResult deleteResult = mongoTemplate.remove(new Query(criteria), Comment.class);
        System.out.println("deleteResult.getDeletedCount() = " + deleteResult.getDeletedCount());
    }

    @Test
    public void testDeleteByUserIdAndCreateTime() {
        String userId = "1003";
        Date date = new Date();
        // 删除两分钟以内发布的评论
        date.setTime(date.getTime() - 2 * 60 * 1000);

        Query query = new Query();
        Criteria criteria = Criteria.where("user_id").is(userId)
                .and("create_time").gte(date).lte(new Date())
                .and("state").is("1");
        query.addCriteria(criteria);

        DeleteResult deleteResult = mongoTemplate.remove(query, Comment.class);
        System.out.println("deleteResult.getDeletedCount() = " + deleteResult.getDeletedCount());
    }

    @Test
    public void testUpdateFirst() {
        Comment comment = new Comment();
        comment.setId("6728a523d9496fae23c4c2a9");
        comment.setLikeNumber(102);

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(comment.getId()));

        Update update = new Update();
        update.set("like_number", comment.getLikeNumber());

        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Comment.class);
        System.out.println("updateResult.getMatchedCount() = " + updateResult.getMatchedCount());
        System.out.println("updateResult.getModifiedCount() = " + updateResult.getModifiedCount());
    }

    @Test
    public void testUpdateMulti() {
        Query query = new Query();
        Criteria criteria = Criteria.where("article_id").is("100001").and("state").is("1");
        query.addCriteria(criteria);

        Update update = new Update();
        update.set("nickname", "聂可以");

        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Comment.class);
        System.out.println("updateResult.getMatchedCount() = " + updateResult.getMatchedCount());
        System.out.println("updateResult.getModifiedCount() = " + updateResult.getModifiedCount());
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921495.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux相关概念和易错知识点(21)(软硬链接、动静态库)

目录 1.软硬链接 &#xff08;1&#xff09;软链接 &#xff08;2&#xff09;硬链接 ①实现方式及其功能 ②硬链接在目录中的运用 ③计算子目录数量 2.动静态库 &#xff08;1&#xff09;动态库 ①动态链接和静态链接 ②动态库的实现 ③系统查找动态库问题 ④解决…

Leetcode 组合

使用回溯来解决此问题。 提供的代码使用了回溯法&#xff08;Backtracking&#xff09;&#xff0c;这是一种通过递归探索所有可能解的算法思想。以下是对算法思想的详细解释&#xff1a; 核心思想&#xff1a; 回溯法通过以下步骤解决问题&#xff1a; 路径选择&#xff1a…

工具学习_Docker

0. Docker 简介 Docker 是一个开源平台&#xff0c;旨在帮助开发者构建、运行和交付应用程序。它通过容器化技术将应用程序及其所有依赖项打包在一个标准化的单元&#xff08;即容器&#xff09;中&#xff0c;使得应用程序在任何环境中都能保持一致的运行效果。Docker 提供了…

【从零开始的LeetCode-算法】3233. 统计不是特殊数字的数字数量

给你两个 正整数 l 和 r。对于任何数字 x&#xff0c;x 的所有正因数&#xff08;除了 x 本身&#xff09;被称为 x 的 真因数。 如果一个数字恰好仅有两个 真因数&#xff0c;则称该数字为 特殊数字。例如&#xff1a; 数字 4 是 特殊数字&#xff0c;因为它的真因数为 1 和…

day06(单片机高级)PCB设计

目录 PCB设计 PCB设计流程 元器件符号设计 原理图设计 元器件封装设计 元器件库使用 PCB设计 目的&#xff1a;学习从画原理图到PCB设计的整个流程 PCB设计流程 元器件符号设计 元器件符号&#xff1a;这是电子元器件的图形表示&#xff0c;用于在原理图中表示特定的元器件。例…

Oracle JDK(通常简称为 JDK)和 OpenJDK区别

Java 的开发和运行时环境主要由两种实现主导&#xff1a;Oracle JDK&#xff08;通常简称为 JDK&#xff09;和 OpenJDK。尽管它们都基于同一个代码库&#xff0c;但在一些关键点上有所区别。以下是详细的对比&#xff1a; 1. 基础代码 Oracle JDK&#xff1a; 基于 OpenJD…

LeetCode 101题集(随时更新)

题集来源&#xff1a;GitHub - changgyhub/leetcode_101: LeetCode 101&#xff1a;力扣刷题指南 使用C完成相关题目&#xff0c;以训练笔试 贪心 采用贪心的策略&#xff0c;保证每次操作都是局部最优的&#xff0c;从而使最后得到的结果是全局最优的。 分配问题 455. 分发饼…

渗透测试笔记——shodan(4)

声明&#xff1a; 学习视频来自B站up主 【泷羽sec】有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&am…

06 —— Webpack优化—压缩过程

css代码提取后想要压缩 —— 使用css-minimizer-webpack-plugin插件 下载 css-minimizer-webpack-plugin 本地软件包 npm install css-minimizer-webpack-plugin --save-dev 配置 webpack.config.js 让webpack拥有该功能 const CssMinimizerPlugin require(css-minimizer-…

【Android】android compat理解

1&#xff0c;前提 即便是在同一手机上安装的不同apk&#xff0c;其编译的apk不同&#xff0c;也会导致行为上的差异。如SDK34有限制后台启动&#xff0c;但如果安装的apk所依赖的sdk是33&#xff0c;则不会表现出此差异。这是如何实现的呢&#xff1f;其实&#xff0c;本质是…

蓝桥杯每日真题 - 第21天

题目&#xff1a;(空间) 题目描述&#xff08;12届 C&C B组A题&#xff09; 解题思路&#xff1a; 转换单位&#xff1a; 内存总大小为 256MB&#xff0c;换算为字节&#xff1a; 25610241024268,435,456字节 计算每个整数占用空间&#xff1a; 每个 32 位整数占用…

MongoDB进阶篇-索引(索引概述、索引的类型、索引相关操作、索引的使用)

文章目录 1. 索引概述2. 索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引2.3.1 地理空间索引&#xff08;Geospatial Index&#xff09;2.3.2 文本索引&#xff08;Text Indexes&#xff09;2.3.3 哈希索引&#xff08;Hashed Indexes&#xff09; 3. 索引相关操作3.1 查看索…

做一个FabricJS.cc的中文文档网站——面向markdown编程

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;用爱发电&#…

自动驾驶之激光雷达

这里写目录标题 1 什么是激光雷达2 激光雷达的关键参数3 激光雷达种类4 自动驾驶感知传感器5 激光雷达感知框架5.1 pointcloud_preprocess5.2 pointcloud_map_based_roi5.3 pointcloud_ground_detection5.4 lidar_detection5.5 lidar_detection_filter5.6 lidar_tracking 1 什么…

Label-studio-ml-backend 和YOLOV8 YOLO11自动化标注,目标检测,实例分割,图像分类,关键点估计,视频跟踪

这里写目录标题 1.目标检测 Detection2.实例分割 segment3.图像分类 classify4.关键点估计 Keypoint detection5.视频帧检测 video detect6.视频帧分类 video classify7.旋转目标检测 obb detect8.替换yolo11模型 给我点个赞吧&#xff0c;谢谢了附录coco80类名称 笔记本 华为m…

Laravel对接SLS日志服务

Laravel对接SLS日志服务&#xff08;写入和读取&#xff09; 1、下载阿里云的sdk #通过composer下载 composer require alibabacloud/aliyun-log-php-sdk#对应的git仓库 https://github.com/aliyun/aliyun-log-php-sdk2、创建sdk请求的service <?phpnamespace App\Ser…

uniapp接入高德地图

下面代码兼容安卓APP和H5 高德地图官网&#xff1a;我的应用 | 高德控制台 &#xff0c;绑定服务选择《Web端(JS API)》 /utils/map.js 需要设置你自己的key和安全密钥 export function myAMap() {return new Promise(function(resolve, reject) {if (typeof window.onLoadM…

初识WGCLOUD - 监测磁盘空间还能使用多久

WGCLOUD是一款免费开源的运维监控软件&#xff0c;性能优秀&#xff0c;部署简单&#xff0c;轻巧使用&#xff0c;支持大部分的Linux和Windows、安卓、MacOS等平台安装部署 最近发布的新版本 v3.5.4&#xff0c;WGCLOUD新增了可以自动计算每个磁盘剩余空间的可使用天数&#x…

【Xbim+C#】创建圆盘扫掠IfcSweptDiskSolid

基础回顾 https://blog.csdn.net/liqian_ken/article/details/143867404 https://blog.csdn.net/liqian_ken/article/details/114851319 效果图 代码示例 在前文基础上&#xff0c;增加一个工具方法&#xff1a; public static IfcProductDefinitionShape CreateDiskSolidSha…

数据结构 ——— 堆排序算法的实现

目录 前言 向下调整算法&#xff08;默认建大堆&#xff09; 堆排序算法的实现&#xff08;默认升序&#xff09; 前言 在之前几章学习了如何用向上调整算法和向下调整算法对数组进行建大/小堆数据结构 ——— 向上/向下调整算法将数组调整为升/降序_对数组进行降序排序代码…