当前位置: 首页 > news >正文

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览

Jimmer是一个Java/Kotlin双语框架

  • 包含一个革命性的ORM

  • 以此ORM为基础打造了一套综合性方案解决方案,包括

    • DTO语言

    • 更全面更强大的缓存机制,以及高度自动化的缓存一致性

    • 更强大客户端文档和代码生成能力,包括Jimmer独创的远程异常

    • 快速创建GraphQL服务

    • 跨越微服务的远程实体关联

ORM部分

当前技术生态下,访问关系型数据库技术体系存在很大缺陷,请看下图。
在这里插入图片描述

1. 以JPA为代表的静态语言ORM

优点

便捷,代码安全(本身基于强类型语言,大部分代码是安全的。如果结合QueryDSL使用,则可以保证所有代码都是安全的)

缺点

缺乏灵活性

即使JPA从2.1开始支持EntityGraph,控制被查询数据格式的灵活性仍然非常有限。该方案粒度仍然太粗,控制能力远没GraphQL这类技术的细腻。

保存对象时,细节行为受普通属性的insertable、updateable和关联属性的cascade配置的控制,这类配置在实体类型中被硬编码固化,被保存的数据结构的格式是固定的,没有灵活性。

如果要发挥ORM的优势,就必须查询对象的大部分非关联属性 (少数@Basic(fetch = FetchType.Lazy)属性除外,它们多为lob设计);如果只想查询一部分属性,就必须放弃对象查询,转而使用这些属性的多列查询,丧失ORM本该有的便捷性和核心价值。

3. 以为ActiveRecord (Ruby) 为代表的动态语言ORM

优点

基于动态语言的ORM,只需将动态语言对象结构的灵活性和ORM的实现结合起来,就能兼顾便捷和灵活。

缺点

动态语言虽然既便捷又灵活,但是代码缺乏可维护性且不利于多人协同开发是众所周知的缺点。

现代软件往往是复杂的,需要团队协作来完成,是否利于团队成员之间协同,远比个人对编程的认知重要。

这里,不想过多地讨论动静之争,但是有一点需要指出:既然选择了静态语言Java/Kotlin,就应该以静态语言的方式使用它, 而不能使用以jFinal为代表的将静态语言当成动态语言用的方案,更不能在应用中频繁地使用java.util.Map来代替数据对象。 这类做法违背了选择Java/Kotlin的初衷,如果一定要怎么做,为什么不直接选动态语言呢?

4. 以MyBatis为代表的轻量级SQL Builder/Mapper

优点

直接编写SQL,随意且灵活;本身是强类型框架,具有代码安全性 (MyBatis生态也有强类型SQL DSL扩展,可以解决原生SQL字符串导致的代码不安全问题)

缺点

便捷性的严重缺失,重复劳动量极大。

MyBatis没有统一实体的概念,而是面对具体业务场景DTO,实现ResultSet和这些DTO的映射。由于业务场景多,各DTO类型之间相似却不同,冗余度很高,导致重复劳动量极高。

除了以孤单对象为载体的CRUD外,对多个对象彼此关联而成的复杂数据结构的支持较弱,缺乏必要抽象,导致太多繁重的低级任务被推卸给开发人员 (不少开发人员长期被这类繁重的任务所累,但自己一直没察觉)。

原生SQL真的是最好方案吗?
这个派别最引以为豪的观点是:“直接书写SQL会带来更直接的控制力,这种直接控制力优于任何ORM”。在这个领域长期的技术停滞中,不少开发人员对此深信不疑。

根本原因

上文中,我们阐述了关系型数据库领域的三种常见方案,但无论如何选择,我们都无法兼顾便捷性、灵活性和代码安全性。为什么会导致这样呢?

就JVM生态而言,POJO是导致这个问题的根本原因。

POJO*(也可以叫结构体)*缺乏必要的灵活性和表达力,却几乎被所有的JVM框架作为数据模型和核心,严重限制了JVM生态的技术创新。

因此,在Jimmer中,ORM实体对象并非POJO。而是另外一种独特的万能数据对象*(后文会介绍)*,这种独特的实体对象撑起了Jimmer所有上层重大的变革,是整个框架的基石。

事实上,Jimmer实体对象不仅可以应用在ORM领域,它几乎可以用在任何以结构化数据维护为目的的场景,并提升各种技术栈的表达力。

目前,Jimmer实体仅在关系型数据库访问领域发挥出作用,只是因为精力不够所致。

完整的功能

在本文开头我们提到了,革命性的ORM只是Jimmer的一部分,Jimmer实际的能力范围早已超越了一个ORM。

现在,我们给出Jimmer的功能示意图,并逐个讲解
在这里插入图片描述

Business Model

在信息类系统中,存在两种对象。

实体:实体对象是全局统一的,对象之间的存在丰富彼此关联。

实体对象往往和数据库非常接近,具备极高的稳定性。

DTO:针对特定业务的输入/输出对象,通常是从全局实体关系网上撕下来的一个局部碎片,该碎片的大小和形状非常灵活。

DTO类型数量庞大,每一个业务接口对DTO对象的格式都有独特的需求,彼此可能相似但又不同,具备明显的。而且易受到需求变化的影响,不稳定。

Entity类型是全局统一数据存储模型,不易被需求变更影响,相对稳定,被视为高价值类型。

DTO类型作为每个业务输入/输出,相对随意,容易因需求变动而不稳定,被视为低价值类型。

Jimmer主张开发人员把精力集中在高价值的实体模式的设计上;对于低价值的DTO类型,有的时候并不需要,有的时候需要。
即使需要,也可以用极其廉价的方式自动生成。因此,基于Jimmer构建的项目具备优秀的抗需求变动的能力。

Jimmer Entity

Jimmer实体定义和JPA实体很接近。

之前讨论过,Jimmer实体并非POJO,所以,被声明为interface,而非class。

那么,谁负责实现此接口呢?是上图中的Jimmer Precompiler (对于Java而言,就是APT; 对于Kotlin而言,就是KSP)

Jimmer实体支持两个重要特征,动态性和不可变性

动态性

Jimmer对象在静态语言和动态语言之间寻求最佳平衡,把二者的优点结合起来:

  • 静态语言数据对象具有高性能、拼写安全、类型安全、甚至空安全*(如果使用Kotlin的话)*的优点,Jimmer实体吸收了这些优点。
  • 动态语言数据对象具有高度的灵活性,Jimmer实体吸收了这个优点,每个属性都可以缺失*(但是不能如同动态语言一样增加属性,因为这必然会破坏静态语言的特性,Jimmer也不需要此能力)*

对Jimmer而言,对象缺少某个属性 (其值未知) 和 对象的某个属性为null (其值已知) 是完全不同的两回事。

这种平衡设计,可以在享受静态语言好处的同时,为数据结构赋予。

这种绝对的灵活性,既可用于表达查询业务的输出格式,也可用于表达保存业务的输入格式。

这导致Jimmer拥有了崭新的定位:一个为任意形状数据结构设计的ORM。其所有功能都是为了操作任意形状的数据结构,而非一个个简单的实体对象。

不可变性

Jimmer对象是不可变对象。不可变对象的好处是多方面的

Jimmer选择不可变对象是为了让数据结构绝不包含循环引用。

这可以保证由Jimmer实体及彼此关联组合而成的数据结构一定能够被直接Jackson序列化,并不需要使用诡异的序列化技巧为JSON植入任何特殊的额外信息,任何编程语言都可以轻松理解。

然而,不可变对象也存在缺点。比如,现有一个很深的数据结构,那么基于它按照一些修改的愿望创建出新的数据结构会很困难,难度随着深度的变大急剧增加。

ORM和很深的数据结构打交道,而Java的record和Kotlin的data class不适合处理很深数据结构。

既对Java和Kotlin进行双语支持,又善于基于现有深层次数据结构按照一些修改的愿望创建出新的不可变数据结构的方案,目前的JVM生态没有。

幸运的是,JavaScript/TypeScript领域存在一个足够强大的方案: immer,可以完美解决这个问题。该方案工作方式如下

基于现有不可变数据结构开启一个临时作用域。

在这个作用域内,开发人员可得到一个draft数据结构,该数据结构的形状和初始值和原数据结构完全一致,且可以被随意修改,包括修改任意深的子对象。

作用域结束后,draft数据结构会利用收集到的修改行为创建另外一个新的数据结构。其中,未被修改的局部会被优化处理,复用以前的旧对象。

Immer完美结合了不可变对象和可变对象的优点,代码简单、功能强大、性能卓越。因此,Jimmer选择为JVM生态移植了immer,项目名称也是对其致敬。

Generated DTO Type

前文谈到,Jimmer实体在静态语言数据对象和动态语言数据对象之间寻找最佳平衡,其中动态性带来了极大的灵活性,并以此决定了整个框架的定位。

Jimmer对象允许某些属性缺失,对象缺少某个属性 (其值未知) 和 对象的某个属性为null (其值已知) 是完全不同的两回事。

  • 对于Jackson序列化而言,缺失的属性会被自动忽略,就如同我们之前展示的那样。

    如果服务端自己并不使用查询得到的实体对象,而是直接写入到Http Response中。对于这种情况,无需DTO,直接使用实体对象很方便。

  • 如果直接用Java/Kotlin代码访问不存在的属性,会导致异常。

这并非由Jimmer制造的新问题,而是一个在静态语言ORM生态中早已存在和被接受的问题。然而,不可否认这的确对静态语言的安全性形成了破坏。

如果要追求100%的静态语言安全性,使用DTO对象是唯一的方法。然而,目前JVM生态的DTO映射技术存在很大缺陷。

  • 要么显式地映射属性*(例如纯手工映射和转化)*,这种做法工作量巨大,枯燥且容易出错。
  • 要么隐式地映射属性*(例如采用BeanUtils技术)*,这种做法会引入新的不安全问题,即,无法在编译发现的问题。

即使你使用强大的mapstruct,你所能做的也只是在这两个极端之间作出选择而已。

因此,Jimmer提供了DTO语言,用户使用该语言编写非常简单的代码,编译项目即可自动生成各种丰富的DTO类型定义。

DTO语言的设计目的,在于

让生成DTO类型的过程足够简单,从而让DTO类型足够廉价。

100%符合静态语言安全性,在编译时发现所有问题并报错。

理论概念先到这里

简单使用

我们做一个简单的查询demo,创建Springboot项目

引入依赖

<dependency><groupId>org.babyfish.jimmer</groupId><artifactId>jimmer-spring-boot-starter</artifactId><version>0.8.51</version></dependency>

编写Model

用户

@Entity
@Table(name = "User")
public interface User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)int id();String name();@NullableInteger age();@OneToMany(mappedBy = "user")List<UserDetail> details();
}

用户详情,一对多

@Entity
@Table(name = "user_detail")
public interface UserDetail {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)int id();@Key // 自己的核心数据自然就是第二个业务键String detail();@Key // 父级自然是一个业务键@OnDissociate(DissociateAction.DELETE) // 如果脱钩了,就把自身删除@ManyToOne@JoinColumn(name = "user_id",foreignKeyType = ForeignKeyType.FAKE)@NullableUser user();@IdView("user")Integer userId();}

配置数据库链接

applicantion.yml

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://myhost:3306/my_jimmerusername: rootpassword: rootjimmer:dialect: org.babyfish.jimmer.sql.dialect.MySqlDialectshow-sql: onpretty-sql: truedatabase-validation:schema: my_jimmer

构建

Maven build

查询

@RestController
@RequestMapping("/test")
public class TestController {@Autowiredprivate JSqlClient sqlClient;@RequestMapping("/user")public List<User> find(@RequestBody UserSpecification specification){UserTable userTable = UserTable.$;return sqlClient.createQuery(userTable).select(userTable).execute();}
}

超级查询

使用specification,可以提供灵活的复杂查询

定义dto

export com.example.myjimmer.entity.User-> package com.example.myjimmer.dto/*UserView {#allScalars(User)details {#allScalars(UserDetail)}
}*/specification UserSpecification {eq(name) as namelike(name) as likename
}

构建

Maven build

使用specification查询

@RestController
@RequestMapping("/test")
public class TestController {@Autowiredprivate JSqlClient sqlClient;@RequestMapping("/user")public List<User> find(@RequestBody UserSpecification specification){UserTable userTable = UserTable.$;return sqlClient.createQuery(userTable).where(specification).select(userTable).execute();}
}

相关文章:

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览 Jimmer是一个Java/Kotlin双语框架 包含一个革命性的ORM 以此ORM为基础打造了一套综合性方案解决方案&#xff0c;包括 DTO语言 更全面更强大的缓存机制&#xff0c;以及高度自动化的缓存一致性 更强大客户端文档和代码生成能力&#xff0c;包括Jimmer独创的远程异常 …...

如何修改DNS解析?

DNS(域名系统)就像互联网的“电话簿”&#xff0c;负责将我们输入的网址转换为计算机能够理解的IP地址。如果DNS解析出现问题&#xff0c;访问网站就会受到影响。那我们该如何修改DNS解析呢?接下来&#xff0c;我们就来介绍一下这个话题。 为什么要修改DNS解析? 使用默认的…...

使用 POI-TL 和 JFreeChart 动态生成 Word 报告

文章目录 前言一、需求背景二、方案分析三、 POI-TL JFreeChart 实现3.1 Maven 依赖3.3 word模板设置3.2 实现代码 踩坑 前言 在开发过程中&#xff0c;我们经常需要生成包含动态数据和图表的 Word 报告。本文将介绍如何结合 POI-TL 和 JFreeChart&#xff0c;实现动态生成 W…...

Python的那些事第十五篇:数据分析中的“三剑客”NumPy、Pandas与Matplotlib

数据分析中的“三剑客”&#xff1a;NumPy、Pandas与Matplotlib 在数据分析的世界里&#xff0c;有三位“大侠”常常携手并肩&#xff0c;共同应对各种复杂的数据挑战。它们就是NumPy、Pandas和Matplotlib。这三位“大侠”各怀绝技&#xff0c;相互配合&#xff0c;让数据分析…...

25/2/7 <机器人基础> 牛顿-欧拉递推公式,开闭环

牛顿-欧拉递推公式是用于计算刚体动力学中&#xff0c;刚体的角速度和角加速度的递推关系。这个公式是牛顿第二定律和欧拉旋转定理的结合&#xff0c;适用于描述刚体在空间中的旋转运动。 对于一个刚体&#xff0c;设其在某时刻的角速度为 ω&#xff0c;角加速度为 α&#xf…...

vue3父子组件传值方式

父子组件传值方式 在 Vue 3 中&#xff0c;父子组件之间传值主要有以下几种常见方式&#xff0c;下面将详细介绍并给出演示代码。 1. 父组件向子组件传值&#xff1a;使用 props 原理 props 是 Vue 中用于在父组件向子组件传递数据的机制。父组件通过在子组件标签上绑定属性…...

树和二叉树_6

树和二叉树_6 一、leetcode-105二、题解1.引库2.代码 一、leetcode-105 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节…...

使用wpa_supplicant和wpa_cli 扫描wifi热点及配网

一&#xff1a;简要说明 交叉编译wpa_supplicant工具后会有wpa_supplicant和wpa_cli两个程序生产&#xff0c;如果知道需要连接的wifi热点及密码的话不需要遍历及查询所有wifi热点的名字及信号强度等信息的话&#xff0c;使用wpa_supplicant即可&#xff0c;否则还需要使用wpa_…...

个人职业发展——效率为王:AI赋能前端开发

在竞争激烈的IT行业&#xff0c;个人职业发展至关重要。而提升工作效率&#xff0c;无疑是加速职业发展的关键引擎。对于前端开发者而言&#xff0c;面对日益复杂的项目需求、不断变化的技术栈以及大量重复性的工作&#xff0c;如何提升效率&#xff0c;成为一个亟待解决的难题…...

【Android】Android开发应用如何开启任务栏消息通知

Android开发应用如何开启任务栏消息通知 1. 获取通知权限2.编写通知工具类3. 进行任务栏消息通知 1. 获取通知权限 在 AndroidManifest.xml 里加上权限配置&#xff0c;如下。 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android…...

c语言:取绝对值

假设我们有一个 long 类型的变量 l&#xff0c;我们希望恢复其绝对值。以下是两种方法的对比&#xff1a; 方法1&#xff1a;使用条件语句 这个很好理解&#xff0c;负数时取负运算 &#xff0c;用于数值的符号反转。 long abs_value(long l) {if (l < 0) {return -l;} e…...

HTML应用指南:利用GET请求获取全国盒马门店位置信息

随着新零售业态的发展&#xff0c;门店位置信息的获取变得至关重要。作为新零售领域的先锋&#xff0c;盒马鲜生不仅在商业模式创新上持续领先&#xff0c;还积极构建广泛的门店网络&#xff0c;以支持其不断增长的用户群体。本篇文章&#xff0c;我们将继续探究GET请求的实际应…...

MongoDB 深度教程:当 NoSQL 遇上幽默

MongoDB 深度教程&#xff1a;当 NoSQL 遇上幽默 欢迎来到这个 MongoDB 的奇妙冒险&#xff01;如果你已经了解了 MongoDB 的基础知识&#xff0c;比如 CRUD 操作、数据库和集合的概念&#xff0c;但总觉得自己只是停留在门口徘徊&#xff0c;那么今天这篇教程就是为你量身定做…...

windows安装linux子系统【ubuntu】操作步骤

1.在windows系统中开启【适用于Linux的Windows子系统】 控制面板—程序—程序和功能—启用或关闭Windows功能—勾选适用于Linux的Windows子系统–确定 2.下载安装Linux Ubuntu 22.04.5 LTS系统 Ununtu下载链接 3.安装完Ununtu系统后更新系统 sudo apt update4.进入/usr/l…...

通过k8s请求selfsubjectrulesreviews查询权限

当前是通过kubelet进行查询 curl --cacert /etc/kubernetes/pki/ca.crt \ --cert /var/lib/kubelet/pki/kubelet-client-current.pem \ --key /var/lib/kubelet/pki/kubelet-client-current.pem \ -d - \ -H "Content-Type: application/json" \ -H Accept: applicat…...

如何参与开源项目

目的 就是说一下如何参与开源的项目&#xff0c;通过参与QXlsx来说明开源项目是如何参与的&#xff0c;其它的github上的开源项目&#xff0c;也是这样的流程。 关于GitHub: GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行…...

Java 大视界 -- Java 大数据在智能金融监管中的应用与实践(77)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

使用deepseek快速创作ppt

目录 1.在DeekSeek生成PPT脚本2.打开Kimi3.最终效果 DeepSeek作为目前最强大模型&#xff0c;其推理能力炸裂&#xff0c;但是DeepSeek官方没有提供生成PPT功能&#xff0c;如果让DeepSeek做PPT呢&#xff1f; 有个途径&#xff1a;在DeepSeek让其深度思考做出PPT脚本&#xf…...

如何在Python中创建和访问列表

在Python中&#xff0c;列表&#xff08;list&#xff09;是一种用于存储一系列有序项目的数据结构。这些项目可以是不同类型的&#xff0c;比如整数、浮点数、字符串&#xff0c;甚至是其他列表&#xff08;形成嵌套列表&#xff09;。以下是如何在Python中创建和访问列表的基…...

多线程下jdk1.7的头插法导致的死循环问题

20250208 多线程下jdk1.7的头插法导致的死循环问题 多线程下jdk1.7的头插法导致的死循环问题 【新版Java面试专题视频教程&#xff0c;java八股文面试全套真题深度详解&#xff08;含大厂高频面试真题&#xff09;】 jdk1.7在hashmap扩容时使用的是头插法&#xff0c;所以扩容…...

低代码系统-插件功能分析( 某道云)

本文主要把其的插件进行了简单分析&#xff0c;不做业务上的梳理&#xff0c;不做推荐。 可大致分为&#xff1a; 群机器人 信息查询 智能识别 实名验证类 数据库类 通知类 通知类 aPaas增强 考勤同步 财务类 类别 插件名称 功能简介 群机器人类 某钉机器人 即在表单处完…...

手搓基于CNN的Chest X-ray图像分类

数据集Chest X-ray PD Dataset 数据集介绍 - 知乎https://zhuanlan.zhihu.com/p/661311561 CPU版本 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader from torchvision import transforms, models import …...

Golang 并发机制-7:sync.Once实战应用指南

Go的并发模型是其突出的特性之一&#xff0c;但强大的功能也带来了巨大的责任。sync.Once是由Go的sync包提供的同步原语。它的目的是确保一段代码只执行一次&#xff0c;而不管有多少协程试图执行它。这听起来可能很简单&#xff0c;但它改变了并发环境中管理一次性操作的规则。…...

java nio 底层使用的是select 、poll还是epoll

在 Java NIO 中&#xff0c;底层使用的 I/O 多路复用机制取决于操作系统和 JDK 的实现。 &#x1f680; Java NIO 底层使用机制概述 操作系统默认多路复用机制系统调用Linuxepollepoll_create、epoll_ctl、epoll_waitWindowsselect 或 WSAPollselect() 或 WSAPoll()macOS / B…...

Kotlin协程详解——协程取消与超时

目录 一、协程取消 1.取消协程的执行 2.使计算代码可取消 3.在finally中释放资源 4.运行不能取消的代码块 二、协程超时 异步超时与资源管理 一、协程取消 1.取消协程的执行 在一个长时间运行的应用程序中&#xff0c;你也许需要对你的后台协程进行细粒度的控制。 比如…...

双向链表、内核链表和gdb(20250208)

单向链表 节点 数据域 指针域&#xff08;后继节点&#xff09; 双向链表 相比于单项指针&#xff0c;双向指针存有前驱节点的地址&#xff0c;使链表的灵活性更高。 内核链表 在内核中 offsetof&#xff1a;获取结构体某个成员到结构体开头的偏移量container_of:根据结…...

全程Kali linux---CTFshow misc入门(38-50)

第三十八题&#xff1a; ctfshow{48b722b570c603ef58cc0b83bbf7680d} 第三十九题&#xff1a; 37换成1&#xff0c;36换成0&#xff0c;就得到长度为287的二进制字符串&#xff0c;因为不能被8整除所以&#xff0c;考虑每7位转换一个字符&#xff0c;得到flag。 ctfshow{5281…...

MySQL 8.0.41安装教程(2025年2月8号)

下载网址&#xff1a;https://www.mysql.com/cn/downloads/ 点击 我选择的是第二个离线安装 点击之后&#xff0c;选择直接下载&#xff1a; 下载完成双击&#xff1a; 我选择的是自定义安装&#xff1a; 右边默认已经存在我选择的8.0.41 点击红框中的&#xff0c;自定义安装路…...

【自学笔记】Deepseek的基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Deepseek知识点总览一、Deepseek简介二、Deepseek的三大适用模式1. 基础模型&#xff08;V3&#xff09;2. 深度思考&#xff08;R1&#xff09;3. 联网搜索模式 三…...

10N10-ASEMI中低压N沟道MOS管10N10

编辑&#xff1a;ll 10N10-ASEMI中低压N沟道MOS管10N10 型号&#xff1a;10N10 品牌&#xff1a;ASEMI 封装&#xff1a;TO-252 最大漏源电流&#xff1a;10A 漏源击穿电压&#xff1a;100V 批号&#xff1a;最新 RDS&#xff08;ON&#xff09;Max&#xff1a;135mΩ …...

2025年2月8日(Adafruit_PCA9685详细使用)

Adafruit_PCA9685 是一个 Python 模块&#xff0c;用于与 PCA9685 驱动芯片进行通信&#xff0c;该芯片常用于控制多个伺服电机。PCA9685 是一个 16 通道的 PWM&#xff08;脉宽调制&#xff09;驱动器&#xff0c;常用于需要精确控制多个伺服电机的应用。 以下是详细的使用方…...

MR30分布式IO模块:驱动智能制造工厂的工业互联与高效控制新范式

在工业4.0与智能制造浪潮的推动下&#xff0c;传统制造业正经历着从“机械驱动”向“数据驱动”的深刻转型。作为工业数据连接领域的领军者&#xff0c;明达技术凭借其自主研发的MR30分布式IO模块&#xff0c;以创新的技术架构与卓越的性能表现&#xff0c;为全球制造企业构建了…...

Reqable使用实践

一、背景 日常开发中&#xff0c;难免要抓取请求数据&#xff0c;查看接口数据&#xff0c;从而更好定位问题&#xff0c;基于这个原因&#xff0c;查找了一些抓包工具&#xff0c;例如&#xff1a; HttpCanary、 Steam 、Fiddler等&#xff0c;不是要钱&#xff0c;就是只对苹…...

数据可视化基本套路总结

首先从维基百科上搬出数据可视化的概念&#xff1a; 数据可视化是关于数据之视觉表现形式的研究&#xff1b;其中&#xff0c;这种数据的视觉表现形式被定义为一种以某种概要形式抽提出来的信息&#xff0c;包括相应信息单位的各种属性和变量。 用人话简单来说&#xff0c;数据…...

TensorFlow域对抗训练DANN神经网络分析MNIST与Blobs数据集梯度反转层提升目标域适应能力可视化...

全文链接&#xff1a;https://tecdat.cn/?p39656 本文围绕基于TensorFlow实现的神经网络对抗训练域适应方法展开研究。详细介绍了梯度反转层的原理与实现&#xff0c;通过MNIST和Blobs等数据集进行实验&#xff0c;对比了不同训练方式&#xff08;仅源域训练、域对抗训练等&am…...

DNS劫持和HTTPDNS

DNS 劫持是一种网络攻击手段&#xff0c;攻击者通过篡改域名系统&#xff08;DNS&#xff09;解析过程&#xff0c;将用户请求的域名重定向到恶意网站或其他不正确的地址。这种攻击可以用于多种目的&#xff0c;例如窃取用户数据、传播恶意软件或进行钓鱼攻击。 举个例子 假设…...

云原生微服务

能够认识到云原生微服务对应用程序设计的影响&#xff0c;描述无状态微服务&#xff0c;并比较单体和微服务架构。要充分利用运营模式&#xff0c;您需要以不同的方式思考应用程序设计。您需要考虑云原生微服务。此图像显示了一个应用程序&#xff0c;该应用程序被设计为小型微…...

【deepSeek R1】Ollama 更改模型安装位置 以及应用安装位置

【deepSeek R1】Ollama 更改模型安装位置 以及应用安装位置 本地版部署deepSeek R1 可以参考文章 3分钟教你搭建属于自己的本地大模型 DeepSeek R1 Ollama 是一个开源工具&#xff0c;旨在帮助用户轻松在本地计算机上运行、部署和管理大型语言模型&#xff08;LLMs&#xff09;…...

windows + visual studio 2019 使用cmake 编译构建静、动态库并调用详解

环境 windows visual studio 2019 visual studio 2019创建cmake工程 1. 静态库.lib 1.1 静态库编译生成 以下是我创建的cmake工程文件结构&#xff0c;只关注高亮文件夹部分 libout 存放编译生成的.lib文件libsrc 存放编译用的源代码和头文件CMakeLists.txt 此次编译CMak…...

使用Feign代替RestTemplet

Feign RestTemplet存在的问题 String url "http: //userservice/user/" order.getUserId(); User user restTemplate.getFor0bject(url, User.class);可读性差参数复杂URL难以维护 Feign声明式的Http客户端&#xff0c;官方地址&#xff1a;https://github.com…...

苹果笔记本安装jmeter

下载并安装jmeter即可&#xff0c;jmeter官网下载地址&#xff1a;Apache JMeter - Download Apache JMeter 参考以下文章&#xff1a;“https://blog.csdn.net/weixin_51664828/article/details/145008755”...

设备通过国标GB28181接入EasyCVR,显示在线但视频无法播放的原因排查

安防监控EasyCVR平台支持多种视频源接入&#xff0c;包括但不限于IP摄像头、NVR、编码器、流媒体服务器等。平台采用高效的视频流接入技术&#xff0c;支持大规模视频流的并发接入&#xff0c;确保视频流的稳定性和流畅性。 有用户反馈&#xff0c;项目现场使用国标GB28181接入…...

为什么我喜欢在 CSS 中使用 RegEx

说到正则&#xff08;RegEx&#xff09;&#xff0c;我们第一反应往往是“在编程中用来匹配或验证字符串”&#xff0c;比如做表单验证。但其实在 CSS 中&#xff0c;也能用到与正则类似的选择器特性&#xff0c;为我们的样式管理带来诸多便利。别怀疑&#xff0c;以下就是如何…...

深度剖析 Redisson 分布式锁:原理、实现与应用实践

文章目录 写在文章开头详解Redisson 分布式锁使用和实现前置准备工作分布式锁的基本使用公平锁的使用联锁的使用读写锁基本使用常见问题Redisson和Jedis有什么区别redisson如何实现分布式锁redisson如何实现分布式锁的可重入redisson如何实现公平锁Redisson的watchdog机制是什么…...

今日AI和商界事件(2025-02-08)

今日AI领域的重大事件主要包括以下几个方面&#xff1a; 一、DeepSeek引发的行业震动 事件概述&#xff1a;DeepSeek作为近期崛起的AI模型&#xff0c;以其低成本、高性能的推理能力引发了广泛关注。其开源策略、独特的出身以及强大的算力表现&#xff0c;使得微软、英伟达等…...

Mac 基于Ollama 本地部署DeepSeek离线模型

最近节日期间最火的除了《哪吒》就是deepseek了&#xff0c;毕竟又让西方各个层面都瑟瑟发抖的产品。DeepSeek凭借其强大的AI能力真的是在全球多个领域展现出强大的影响力。由于受到外部势力的恶意攻击倒是deepseek官方服务不稳定&#xff0c;国内其他厂家的适配版本也不是很稳…...

Python截图轻量化工具

这是用Python做到截图工具&#xff0c;不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境&#xff1b; 如果要提升其跨平台性的话&#xff0c;需要考虑替换ctypes的一些专属于W…...

怎麼在Chrome中設置代理伺服器?

出於隱私、安全或者訪問特定網路資源的需求&#xff0c;設置代理伺服器顯得尤為重要。本文將詳細介紹如何在Chrome流覽器中進行代理伺服器的設置。 代理伺服器是介於電腦和互聯網之間的一道“中間牆”。幫助間接訪問互聯網資源&#xff0c;這樣實際的IP地址被代理伺服器的IP地…...

【数据结构中链表常用的方法实现过程】

线性表 线性表包括:顺序表、链表、栈&#xff0c;队列等&#xff0c;本节我们先学习顺序表。 顺序表 利用新的数据类型——顺序表&#xff0c;操作数组 顺序表的本质就是对数组的增删改查。 /*** 打印顺序表中的所有元素*/Overridepublic void display() {for (int i 0; i…...

语言月赛 202308【小粉兔处理题解审核志愿者轮换】题解(AC)

》》》点我查看「视频」详解》》》 [语言月赛 202308] 小粉兔处理题解审核志愿者轮换 题目背景 又到了一周的周日&#xff0c;扶苏又像催命一样开始催促小粉兔处理题解审核志愿者的轮换。但是懒狗小粉兔总是把这项工作拖到第二天凌晨。 【这里有一张内部群聊图&#xff0c;…...