Faunadb入门

news2024/9/21 10:42:38

Faunadb和google spanner都属于云分布式数据库天然支持分片(无需做分表分库操作,一库搞定,当然价格另说),国内的也有比如TiDB  Oceanbase等

本文使用java语言,其他语言可以跳过;有想直接使用的可以参考(无法访问外网,可以搞个vpn吧!!!,有时会遇到网络问题):GitHub - fauna/faunadb-jvm: Scala and Java driver for FaunaDB v4

此文旨在想了解的小伙伴看看(免费使用30天)

本文演示使用的jdk版本为jdk21

目录

1.登录账号

2.了解一下FQL

3. 创建数据库,创建集合

4.点击搜索框中的dashbord进入到控制台然后到控制台创建集合

5. 生成数据库秘钥

6.springboot整合项目

7.实体

8.service及接口

9.属性文件配置属性

10.controller

11.启动后postman试试


1.登录账号

使用github账号或者注册一个

Welcome to Fauna docs - Fauna Documentation

2.了解一下FQL

建议按照图看下去

3. 创建数据库,创建集合

最好是跟着官网文档走

4.点击搜索框中的dashbord进入到控制台然后到控制台创建集合

(参考:使用 Spring Boot 使用 Fauna 和 Java 开始构建_rxjava_云O生-云原生)

最新的不一样,使用下面语法

Collection.create({
  name: 'todos'
})

5. 生成数据库秘钥

记住不要到account哪里去申请

6.springboot整合项目

依赖

<dependency>
<groupId>com.faunadb</groupId>
<artifactId>faunadb-java</artifactId>
<version>4.4.0</version>
<scope>compile</scope>
</dependency>

实体\service\controller均参考博文:使用 Spring Boot 使用 Fauna 和 Java 开始构建_rxjava_云O生-云原生

7.实体

参考这个也行:GitHub - fauna/faunadb-jvm: Scala and Java driver for FaunaDB v4

import lombok.Data;

@Data
public abstract class Entity {
    protected  String id;
}
import java.util.List;
import java.util.Optional;

public class Page <T> {

    private List<T> data;
    private Optional<String> before;
    private Optional<String> after;


    public Page(List<T> data, Optional<String> before, Optional<String> after) {
        this.data = data;
        this.before = before;
        this.after = after;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public Optional<String> getBefore() {
        return before;
    }

    public void setBefore(Optional<String> before) {
        this.before = before;
    }

    public Optional<String> getAfter() {
        return after;
    }

    public void setAfter(Optional<String> after) {
        this.after = after;
    }
}
package com.rulecheck.entity;

import java.util.Optional;

public class PaginationOptions {
    private Optional<Integer> size;
    private Optional<String> before;
    private Optional<String> after;


    public PaginationOptions(Optional<Integer> size, Optional<String> before, Optional<String> after) {
        this.size = size;
        this.before = before;
        this.after = after;
    }

    public Optional<Integer> getSize() {
        return size;
    }

    public void setSize(Optional<Integer> size) {
        this.size = size;
    }

    public Optional<String> getBefore() {
        return before;
    }

    public void setBefore(Optional<String> before) {
        this.before = before;
    }

    public Optional<String> getAfter() {
        return after;
    }

    public void setAfter(Optional<String> after) {
        this.after = after;
    }
}


import com.faunadb.client.types.FaunaConstructor;
import com.faunadb.client.types.FaunaField;

public class TodoEntity extends Entity {

    @FaunaField
    private String title;

    @FaunaField
    private String description;

    @FaunaConstructor
    public TodoEntity(@FaunaField("id") String id,
                      @FaunaField("title") String title,
                      @FaunaField("description") String description) {
        this.id = id;
        this.title = title;
        this.description = description;

    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
package com.rulecheck.entity;

public class CreateOrUpdateTodoData {

    private String title;
    private String description;

    public CreateOrUpdateTodoData(String title, String description) {
        this.title = title;
        this.description = description;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

8.service及接口

package com.rulecheck.service;

import com.faunadb.client.FaunaClient;
import com.faunadb.client.errors.NotFoundException;
import com.faunadb.client.query.Expr;
import com.faunadb.client.query.Pagination;
import com.faunadb.client.types.Value;
import com.rulecheck.entity.Entity;
import com.rulecheck.entity.Page;
import com.rulecheck.entity.PaginationOptions;
import jakarta.annotation.Resource;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.faunadb.client.query.Language.*;

import java.lang.Class;

public abstract class FaunaRepository<T extends Entity > implements Repository<T>, IdentityFactory {

    @Resource
    private FaunaClient faunaClient;

    protected final Class<T> entityType;
    protected final String collectionName;
    protected final String collectionIndexName;


    protected FaunaRepository(Class<T> entityType, String collectionName, String collectionIndexName) {
        this.entityType = entityType;
        this.collectionName = collectionName;
        this.collectionIndexName = collectionIndexName;
    }

    // This method returns a unique valid Id leveraging Fauna's NewId function.
    @Override
    public CompletableFuture<String> nextId() {

        CompletableFuture<String> result =
                faunaClient.query(
                        NewId()
                )
                        .thenApply(value -> value.to(String.class).get());

        return result;
    }

    // This method saves an entity to the database using the saveQuery method below. It also returns the result of the saved entity.
    @Override
    public CompletableFuture<T> save(T entity) {
        CompletableFuture<T> result =
                faunaClient.query(
                        saveQuery(Value(entity.getId()), Value(entity))
                )
                        .thenApply(this::toEntity);

        return result;
    }

    // This method deletes from the data an entity(document) with the specified Id. 
    @Override
    public CompletableFuture<Optional<T>> remove(String id) {
        CompletableFuture<T> result =
                faunaClient.query(
                        Select(
                                Value("data"),
                                Delete(Ref(Collection(collectionName), Value(id)))
                        )
                )
                        .thenApply(this::toEntity);

        CompletableFuture<Optional<T>> optionalResult = toOptionalResult(result);

        return optionalResult;
    }

    // This method finds an entity by its Id and returns the entity result.
    @Override
    public CompletableFuture<Optional<T>> find(String id) {
        CompletableFuture<T> result =
                faunaClient.query(
                        Select(
                                Value("data"),
                                Get(Ref(Collection(collectionName), Value(id)))
                        )
                )
                        .thenApply(this::toEntity);

        CompletableFuture<Optional<T>> optionalResult = toOptionalResult(result);

        return optionalResult;
    }

    // This method returns all entities(documents) in the database collection using the paginationOptions parameters.
    @Override
    public CompletableFuture<Page<T>> findAll(PaginationOptions po) {
        Pagination paginationQuery = Paginate(Match(Index(Value(collectionIndexName))));
        po.getSize().ifPresent(size -> paginationQuery.size(size));
        po.getAfter().ifPresent(after -> paginationQuery.after(Ref(Collection(collectionName), Value(after))));
        po.getBefore().ifPresent(before -> paginationQuery.before(Ref(Collection(collectionName), Value(before))));

        CompletableFuture<Page<T>> result =
                faunaClient.query(
                        Map(
                                paginationQuery,
                                Lambda(Value("nextRef"), Select(Value("data"), Get(Var("nextRef"))))
                        )
                ).thenApply(this::toPage);

        return result;
    }


    // This is the saveQuery expression method used by the save method to persist the database.
    protected Expr saveQuery(Expr id, Expr data) {
        Expr query =
                Select(
                        Value("data"),
                        If(
                                Exists(Ref(Collection(collectionName), id)),
                                Replace(Ref(Collection(collectionName), id), Obj("data", data)),
                                Create(Ref(Collection(collectionName), id), Obj("data", data))
                        )
                );

        return query;
    }

    // This method converts a FaunaDB Value into an Entity.
    protected T toEntity(Value value) {
        return value.to(entityType).get();
    }

    // This method returns an optionalResult from a CompletableFuture<T> result.
    protected CompletableFuture<Optional<T>> toOptionalResult(CompletableFuture<T> result) {
        CompletableFuture<Optional<T>> optionalResult =
                result.handle((v, t) -> {
                    CompletableFuture<Optional<T>> r = new CompletableFuture<>();
                    if(v != null) r.complete(Optional.of(v));
                    else if(t != null && t.getCause() instanceof NotFoundException) r.complete(Optional.empty());
                    else r.completeExceptionally(t);
                    return r;
                }).thenCompose(Function.identity());

        return optionalResult;
    }

    // This method converts a FaunaDB Value into a Page with the Entity type.
    protected Page<T> toPage(Value value) {

        Optional<String> after = value.at("after").asCollectionOf(Value.RefV.class).map(c -> c.iterator().next().getId()).getOptional();
        Optional<String> before = value.at("before").asCollectionOf(Value.RefV.class).map(c -> c.iterator().next().getId()).getOptional();

        List<T> data = value.at("data").collect(entityType).stream().collect(Collectors.toList());

        Page<T> page = new Page(data, before, after);

        return page;
    }

}

import java.util.concurrent.CompletableFuture;

public interface IdentityFactory {

    CompletableFuture<String> nextId();
}


import com.rulecheck.entity.Entity;
import com.rulecheck.entity.Page;
import com.rulecheck.entity.PaginationOptions;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;

public interface Repository<T extends Entity> {

    // This method saves the given Entity into the Repository.
    CompletableFuture<T> save(T entity);

    // This method finds an Entity for the given Id
    CompletableFuture<Optional<T>> find(String id);

    // This method retrieves a Page of TodoEntity entities for the given PaginationOptions
    CompletableFuture<Page<T>> findAll(PaginationOptions po);

    // This method finds the Entity for the given Id and removes it. If no Entity can be found for the given Id an empty result is returned.
    CompletableFuture<Optional<T>> remove(String id);
}
import com.rulecheck.entity.TodoEntity;
import org.springframework.stereotype.Repository;
@Repository
public class TodoRepository extends FaunaRepository<TodoEntity> {

    public TodoRepository(){
        super(TodoEntity.class, "todos", "all_todos");
    }

    //-- Custom repository operations specific to the TodoEntity will go below --//

}



import com.rulecheck.entity.CreateOrUpdateTodoData;
import com.rulecheck.entity.Page;
import com.rulecheck.entity.PaginationOptions;
import com.rulecheck.entity.TodoEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;

@Service
public class TodoService {

    @Autowired
    private TodoRepository todoRepository;

    public CompletableFuture<TodoEntity> createTodo(CreateOrUpdateTodoData data) {
        CompletableFuture<TodoEntity> result =
                todoRepository.nextId()
                        .thenApply(id -> new TodoEntity(id, data.getTitle(), data.getDescription()))
                        .thenCompose(todoEntity -> todoRepository.save(todoEntity));

        return result;
    }

    public CompletableFuture<Optional<TodoEntity>> getTodo(String id) {
        return todoRepository.find(id);
    }

    public CompletableFuture<Optional<TodoEntity>> updateTodo(String id, CreateOrUpdateTodoData data) {
        CompletableFuture<Optional<TodoEntity>> result =
                todoRepository.find(id)
                        .thenCompose(optionalTodoEntity ->
                                optionalTodoEntity
                                        .map(todoEntity -> todoRepository.save(new TodoEntity(id, data.getTitle(), data.getDescription())).thenApply(Optional::of))
                                        .orElseGet(() -> CompletableFuture.completedFuture(Optional.empty())));

        return result;
    }

    public CompletableFuture<Optional<TodoEntity>> deleteTodo(String id) {
        return todoRepository.remove(id);
    }

    public CompletableFuture<Page<TodoEntity>> getAllTodos(PaginationOptions po) {
        return todoRepository.findAll(po);
    }
}
import com.faunadb.client.FaunaClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;


/**
 * description:
 */

@Slf4j
@SpringBootApplication
public class RuleCheckApplication {

    @Value("${fauna-db.secret}")
    private String serverKey;

    @Bean
    @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
    public FaunaClient faunaConfiguration() {
        log.info("serverKey:{}", serverKey);
        FaunaClient faunaClient = FaunaClient.builder()
                .withSecret(serverKey)
                .build();

        return faunaClient;
    }

    public static void main(String[] args) {
        SpringApplication.run(RuleCheckApplication.class, args);
    }

}

9.属性文件配置属性

fauna-db.secret=fnAFN6K4SxAAQWm.........  自己生成数据库秘钥,非账户秘钥或者密码

10.controller

package com.rulecheck.controller;


import com.rulecheck.entity.CreateOrUpdateTodoData;
import com.rulecheck.entity.Page;
import com.rulecheck.entity.PaginationOptions;
import com.rulecheck.entity.TodoEntity;
import com.rulecheck.service.TodoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;

@RestController
public class TodoRestController {

    @Autowired
    private TodoService todoService;


    @PostMapping("/todos")
    public CompletableFuture<ResponseEntity> createTodo(@RequestBody CreateOrUpdateTodoData data) {

        return todoService.createTodo(data)
                .thenApply(todoEntity -> new ResponseEntity(todoEntity, HttpStatus.CREATED));
    }


    @GetMapping("/todos/{id}")
    public CompletableFuture<ResponseEntity> getTodo(@PathVariable("id") String id) {
        CompletableFuture<ResponseEntity> result =
                todoService.getTodo(id)
                        .thenApply(optionalTodoEntity ->
                                optionalTodoEntity
                                        .map(todoEntity -> new ResponseEntity(todoEntity, HttpStatus.OK))
                                        .orElseGet(() -> new ResponseEntity(HttpStatus.NOT_FOUND))
                        );
        return result;
    }


    @PutMapping("/todos/{id}")
    public CompletableFuture<ResponseEntity> updateTodo(@PathVariable("id") String id, @RequestBody CreateOrUpdateTodoData data) {
        CompletableFuture<ResponseEntity> result =
                todoService.updateTodo(id, data)
                        .thenApply(optionalTodoEntity ->
                                optionalTodoEntity
                                        .map(todoEntity -> new ResponseEntity(todoEntity, HttpStatus.OK))
                                        .orElseGet(() -> new ResponseEntity(HttpStatus.NOT_FOUND)
                                        )
                        );
        return result;
    }

    @DeleteMapping(value = "/todos/{id}")
    public CompletableFuture<ResponseEntity> deletePost(@PathVariable("id")String id) {
        CompletableFuture<ResponseEntity> result =
                todoService.deleteTodo(id)
                        .thenApply(optionalTodoEntity ->
                                optionalTodoEntity
                                        .map(todo -> new ResponseEntity(todo, HttpStatus.OK))
                                        .orElseGet(() -> new ResponseEntity(HttpStatus.NOT_FOUND)
                                        )
                        );
        return result;
    }

    @GetMapping("/todos")
    public CompletableFuture<Page<TodoEntity>> getAllTodos(
            @RequestParam("size") Optional<Integer> size,
            @RequestParam("before") Optional<String> before,
            @RequestParam("after") Optional<String> after) {
        PaginationOptions po = new PaginationOptions(size, before, after);
        CompletableFuture<Page<TodoEntity>> result = todoService.getAllTodos(po);
        return result;
    }
}

11. 参考pom依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.3</version>
        <relativePath></relativePath>
    </parent>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <mybatis-plus-boot-starter>3.5.3.1</mybatis-plus-boot-starter>
        <mysql-connector-java>8.0.28</mysql-connector-java>
        <commons-io>2.11.0</commons-io>
    </properties>
<!--    <packaging>jar</packaging>-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-boot-starter}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
           <version>${mysql-connector-java}</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatis-plus-boot-starter}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons-io}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.faunadb</groupId>
            <artifactId>faunadb-java</artifactId>
            <version>4.4.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

11.启动后postman试试

http://localhost:8080/todos

{

    "title":"create a job",

    "description":"this post request is todos"

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp开发h5,解决项目启动时,Network: unavailable问题

网上搜了很多&#xff0c;发现都说是要禁用掉电脑多余的网卡&#xff0c;这方法我试了没有好&#xff0c;不晓得为啥子&#xff0c;之后在网上看&#xff0c;uniapp的devServer vue2的话对标的就是webpack4的devserver&#xff08;除了复杂的函数配置项&#xff09;&#xff0c…

牛客: BM5 合并k个已排序的链表

牛客: BM5 合并k个已排序的链表 文章目录 牛客: BM5 合并k个已排序的链表题目描述题解思路题解代码 题目描述 题解思路 合并链表数组中的前两条链表,直到链表数组的长度为一, 返回这个唯一的链表 题解代码 package main/** type ListNode struct{* Val int* Next *ListN…

一个十分好用且美观的vue3后台管理系统框架

给大家推荐一个十分好用且美观的vue3后台管理系统框架 码云地址 项目完全开源&#xff0c;另外还给想学习框架搭建的同学&#xff0c;准备了学习视频&#xff0c;价格美丽&#xff0c;保证物美价廉。 试看视频 项目技术栈 Vue3Vite4Typescript5piniaelement plusUnocsspnp…

Git的基本操作:分支管理

8 分支管理 这里主要体现的git的功能的分离&#xff0c;这才是真正的git吧。每一个分支都是一个单独的可以分离的工作单位。每个用户可以建立不同的分支进行工作&#xff0c;最终提交到同一个开发分支上。一个用户可以建立不同的分支实现不同的功能&#xff0c;最终提交到同一…

CPU的三级缓存

CPU缓存&#xff08;Cache Memory&#xff09;是位于CPU与内存之间的临时存储器&#xff0c;它的容量比内存小的多但是交换速度却比内存要快得多。高速缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾&#xff0c;因为CPU运算速度要比内存读写速度快很多&#…

Python语言学习实战-内置函数filter()的使用(附源码和实现效果)

实现功能 filter()函数是Python的内置函数之一&#xff0c;用于过滤序列中的元素。它接受两个参数&#xff1a;一个是函数&#xff0c;用于判断每个元素是否符合条件&#xff1b;另一个是可迭代对象&#xff0c;包含要过滤的元素。filter()函数返回一个迭代器&#xff0c;其中包…

Spring MVC里的DispatchServlet(结合Spring官网翻译)

Spring MVC里的DispatchServlet 前言1.Spring Web MVC1.1 DispatcherServlet&#xff08;中央调度器&#xff09;1.1.1 Context Hierarchy&#xff08;上下文层次结构&#xff09;1.1.2 Special Bean Types&#xff08;特定的bean类型&#xff09;1.1.3 Web MVC Config1.1.4 Se…

c++基础第三章:数值类型

数值类型 int类型最大最小值 INT_MIN :最小值 INT_MAX &#xff1a;最大值unsigned int 类型最大是&#xff1a; UINT_MAXlong类型的最大最小 LONG_MIN LONG_MAX 无符号的long类型大小 ULONG_MAXlong long 类型大小 LLONG_MIN LLONG_MAX 无符号类型 ULLONG_MAX 整型&am…

npm常用命令系统介绍

npm常用命令系统介绍 npm helpnpm initpackage.json 文件package.json 文件属性说明默认 package.json 文件--参数[-yes|-y]设置 package.json 中字段的默认值package-lock.json 文件 npm [config|c]设置源 npm [install|i]可选参数&#xff1a;全局安装的特性 包的删除npm uni…

蓝桥杯 题库 简单 每日十题 day1

01 空间 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝准备用 256MB 的内存空间开一个数组&#xff0c;数组的每个元素都是 32 位 二进制整数&#xff0c;如果不考虑程序占用的空间和维护内存需要的辅助空间&#xff…

设置HTTP代理隧道

在网络世界中&#xff0c;使用HTTP代理IP可以帮助我们实现一些有趣的功能&#xff0c;比如突破网络封锁、访问被限制的内容、隐藏真实IP等。现在&#xff0c;我将为你详细介绍如何设置HTTP代理服务器&#xff0c;让你轻松掌握这项技能&#xff01; 步骤一&#xff1a;了解HTTP…

腾讯mini项目-【指标监控服务重构】2023-08-17

今日已办 定位昨日发现的问题 来回测试发现依然出现该问题 将 pub/sub 的库替换为原来官方基于 sarama 的实现&#xff0c;发现问题解决了&#xff0c;所以问题的根本是 kafkago 这个库本身存在问题 依据官方的实现&#xff0c;尝试自定义实现 pub/sub sarama 与 kafka-go …

【Java 基础篇】深入了解Java的File类:文件和目录操作指南

在Java编程中&#xff0c;处理文件和目录是一项常见的任务。Java提供了java.io.File类&#xff0c;用于在文件系统中创建、访问和操作文件和目录。本文将深入探讨Java的File类&#xff0c;向您介绍如何使用它来进行文件和目录的操作&#xff0c;从基础到高级的用法都将一一介绍…

Visual Studio 调试上传文件时自动停止运行的解决方法

进入&#xff1a;选项&#xff0c;项目和解决方案&#xff0c;Web项目&#xff0c; 找到在浏览器窗口关闭时停止调试程序&#xff0c;在调试停止时关闭浏览器 将它不要勾关闭&#xff0c;然后重新启动下Visual Studio&#xff0c;上传文件时就可以调试了

Windows 打包 Docker 提示环境错误: no DOCKER_HOST environment variable

这个问题应该还是比较常见的。 [ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.40.2:build (default) on project mq-service: Execution default of goal io.fabric8:docker-maven-plugin:0.40.2:build failed: No <dockerHost> given, no DOCKER_H…

机器视觉Halcon-焊点提取排序设计思路一

目录 一.内容提要①本文是Blob示例之一,利用二值化原理阈值分割的方法,进行焊点检出的思路。二.问题分析及设计思路①.对图形窗口字体设置②.通过亮背景提取暗特征,提取焊点③.图像处理④.显示排序数字一.内容提要 ①本文是Blob示例之一,利用二值化原理阈值分割的方法,进…

GIS前端—Popup标注视图

GIS前端—Popup标注视图 Popup标注视图聚合标注 Popup标注视图 即根据需求实现个性化的弹框标注视图。Leaflet提供了L.Popup对象&#xff0c;用于添加Popup标注视图&#xff0c;通过setLatLng()方法设置Popup标注视图的位置&#xff0c;通过setContent()方法设置Popup标注视图…

Python爬虫如何使用代理IP进行抓取

前言 Python爬虫是一种非常强大的工具&#xff0c;可以用于抓取各种网站的数据。但是&#xff0c;在一些情况下&#xff0c;我们需要使用代理IP来完成数据抓取&#xff0c;如绕过IP限制或保护隐私信息等。本文将介绍如何使用Python爬虫抓取数据时使用代理IP&#xff0c;并提供…

Vuex详解:Vue.js的状态管理方案

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Wordtune:文本编辑工具

【产品介绍】 名称 Wordtune 上线时间 成立于2018年。​ 具体描述 Wordtune是一款基于人类智能的文本编辑工具&#xff0c;它可以帮助用户快速修改和重写英文&#xff0c;以改进文本的清晰度、流畅度和可读性。Wordtune使用先进的自然语言处理技术&#x…