做 Java 持久层的人应该都遇到过这种时刻本地跑得好好的推到 CI 上编译直接红一片日志里滚着几十行cannot find symbol: class UserDaoImpl。第一次遇到会怀疑人生第二次遇到就知道——大概率不是代码写错而是 DOMA 的注解处理器没干活。DOMA 这个框架的特点很鲜明它在编译期就把 DAO 的实现类生成好、把 SQL 文件解析校验完好处是运行期几乎没有反射开销坏处是问题全部前移到构建阶段报错信息往往指向生成物而不是根因。这篇内容我把这些年处理 DOMA 相关问题的经验整理出来覆盖构建链路、SQL 文件定位、2-way SQL 写法、实体映射、事务管理、主键与批量、Spring Boot 集成、日志与代码生成八个方面。适合正在用或者准备用 DOMA 做数据访问的同学从刚上手的新人到已经在生产环境跑了一年的人应该都能从里面找到一两条自己没注意过的细节。1. 编译期就崩的 DAO先在构建链路里找原因DOMA 的 DAO 是接口你写Dao注解的接口编译时由注解处理器生成接口名Impl的实现类。运行期注入的、被调用的都是这个生成类。所以只要生成环节出问题你看到的报错永远是找不到 Impl而不是处理器没跑。这个信息差是排查的第一道坎。1.1 实现类不是运行时生成的很多人第一反应是去检查依赖有没有引进来这没错但方向容易跑偏。doma-core是运行期需要的东西负责 SQL 执行、实体映射、方言支持真正生成实现类的是doma-processor它只在编译期存在运行期完全不需要。这两者的区别决定了它们的依赖作用域必须分开写。如果你的构建脚本里把处理器写成了implementation或者compileOnly会出现两种截然不同的症状。写成implementation时处理器会被打进最终产物能跑通但你会带着几百 KB 完全用不上的东西上线而且某些构建工具在增量编译时会因为类路径变化反复触发全量编译。写成compileOnly更麻烦它在编译期看似可见但很多构建工具从某个版本开始不再把compileOnly的内容传递到注解处理器路径上结果就是处理器压根没被调用最后报找不到 Impl。正确的写法是按构建工具区分。用 Gradle 的话处理器要放在annotationProcessor配置里dependencies { implementation doma-core:x.y.z annotationProcessor doma-processor:x.y.z }用 Maven 的话处理器要写进编译插件的annotationProcessorPaths而不是当成普通依赖plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId configuration annotationProcessorPaths path artifactIddoma-processor/artifactId versionx.y.z/version /path /annotationProcessorPaths /configuration /plugin注意如果项目里同时用了其他注解处理器比如生成样板代码的那类工具annotationProcessorPaths里要把它们都列上只列 DOMA 会把其他的挤掉然后你会看到一堆本来正常的 setter 方法集体消失。1.2 依赖作用域写错处理器根本不参与编译上面说的是显式写法还有一种更隐蔽的情况项目用了构建工具的 BOM 或者父 POM 统一管理版本你在子模块里只写annotationProcessor doma-processor不写版本号结果父级没有对这个坐标做版本仲裁构建工具要么报无法解析版本要么静默跳过。后者的表现和没加处理器一模一样。排查这类问题有个笨但快的办法编译时加上-X打开构建工具的详细日志搜索doma-processor这个关键字看它有没有出现在 processor path 里。如果只在 classpath 里、不在 processor path 里那就是作用域问题跑再多次clean也没用。另一个办法是去build/classes或target/classes下找生成物DOMA 默认把 Impl 生成在 DAO 接口所在包的impl子包里你去看那个目录是不是空的一眼就知道处理器有没有干活。顺带说一下 Kotlin 项目。Kotlin 用的是 kapt或者新版构建工具里的 KSP但 DOMA 目前对 kapt 的支持更成熟处理器要配在kapt配置里而不是annotationProcessor并且kapt的配置项里要显式声明处理器路径。Kotlin 还有一个额外坑Entity标注的 data class 属性必须是var且可赋值用val会导致生成的映射代码无法赋值编译期报错信息会指向生成类很难一眼看出是实体定义的问题。1.3 IDE 里那几处容易漏掉的开关命令行能编译过、IDE 里却满屏红这是最典型的注解处理器未启用症状。主流 IDE 对注解处理器的处理方式不完全一致有的默认开启、有的需要手动勾选有的还要单独配置处理器路径。如果你看到找不到 Impl的红线但构建工具构建正常先去设置里搜annotation processing确认是启用状态并且确认处理器没有被限定在某些模块上。还有一种情况是 IDE 的增量编译缓存脏了。注解处理器生成的文件在增量编译时可能没有被正确刷新表现是改完 SQL 或者实体之后Impl 里还是旧的方法签名。处理方式不是重启 IDE而是先做一次完整的重新构建让生成目录重建。我一般会把这个动作写进排错清单只要涉及实体字段增删、DAO 方法签名变更就先完整重建一次再判断是不是真的有问题。1.4 版本错位引发的连锁报错doma-core和doma-processor的版本必须严格一致。这条看起来是常识但实际踩到的人不少因为版本不一致时的报错非常有迷惑性。处理器生成的 Impl 会调用 core 里的类和方法如果 core 的某个方法签名在版本间发生了变化你看到的报错会是找不到符号方法 xxx报错位置在生成类里而生成类你根本没写过。更麻烦的是依赖传递带来的隐式升级。比如 A 模块依赖了 B 模块B 模块内部引了较新版本的 core而你的处理器还是老版本冲突就出现了。这种情况要靠构建工具的依赖树命令去查看doma-core最终解析到的是哪个版本和你显式声明的处理器版本对不对得上。对不上就在根项目统一版本别指望各个模块各管各的。2. SQL 文件的定位规则路径差一个字符就找不到DOMA 把 SQL 从 Java 代码里挪到了独立的.sql文件里这个设计让 SQL 可以单独格式化、单独审阅、单独交给 DBA 评审是它最实用的特性之一。代价是路径规则必须记准一旦错位编译期直接报SQL 文件未找到不会给你模糊匹配的机会。2.1 从 Dao 全限定名反推路径默认规则很机械META-INF DAO 接口所在的包路径点换成斜杠 接口简单名 方法名 .sql。假设你有com.example.app.dao.UserDao接口里面有个selectById方法那么在资源目录下的完整路径就是src/main/resources/META-INF/com/example/app/dao/UserDao/selectById.sql这条规则里最容易出错的不是包名而是方法名的对应关系。如果 DAO 方法有重载同名不同参数DOMA 是按方法名找 SQL 文件的重载方法会指向同一个文件这时候必须用Sql显式指定路径来区分。另外接口名的大小写必须和文件名完全一致Windows 上不敏感、Linux 上敏感本地开发一切正常、一上容器就报找不到这类问题排查起来很耗时间。2.2 注解里显式指定路径更省心包路径一长默认规则就容易写错。我的做法是能不依赖默认规则就不依赖直接在方法上加Sql指定相对路径Sql(META-INF/sql/user/selectById.sql) Select User selectById(Integer id);这样做的好处是把 SQL 目录结构从必须镜像 Java 包结构里解放出来可以按业务模块组织比如META-INF/sql/user/、META-INF/sql/order/。多个 DAO 共用同一段 SQL 的时候也方便直接指向同一个文件就行不用复制粘贴三份再各自维护。代价是路径写错时编译器只能告诉你找不到这个文件不会帮你猜。所以我一般会在项目初始化阶段就把这套目录约定固化下来写进团队的项目结构说明里新人接手不用再猜。2.3 资源目录与打包方式SQL 文件必须最终落在 classpath 的META-INF下。用 Maven 或者 Gradle 的默认结构src/main/resources会自动打进产物没问题。但如果项目自定义了资源目录或者用了多模块结构把资源集中放到了某个公共模块就要确认这些资源确实被包含在最终 classpath 里。多模块项目里有个高频坑SQL 文件放在 A 模块的 resources 下DAO 接口在 B 模块B 依赖了 A。这种情况能不能找到取决于 A 的资源有没有被打进 B 的运行期 classpath。implementation依赖会传递但如果你在 A 里把资源排除掉了有些项目为了减小产物体积会配exclude运行时就会报文件不存在。这类问题的特征是编译期不报错因为编译期看的是源码路径运行期才炸。所以 SQL 文件的检查不能只看编译通过还要跑一次集成测试。2.4 编码与 BOM 造成的解析失败SQL 文件里如果有中文注释、中文别名编码必须统一成 UTF-8。DOMA 在编译期解析 SQL 文件如果读进来的字节流按错误编码解释会出现乱码严重时直接解析失败。更隐蔽的是 BOM某些编辑器保存 UTF-8 时会带 BOM 头这个隐藏字符会跟在 SQL 语句最前面导致解析器认不出第一条语句。另外说一个和换行符有关的坑。SQL 文件里的行注释--在某些情况下会把后续内容一起吞掉如果你在拼接动态 SQL 时行注释写在了指令中间解析结果可能和你肉眼看到的完全不一样。我的习惯是 SQL 文件里一律用/* */块注释不用--虽然多敲两个字符但省下来的排查时间远不止这些。3. 2-way SQL 的实用写法与常见误用2-way SQL 是 DOMA 最有辨识度的能力带有/*%if */这类指令的 SQL 文件既能当作纯 SQL 直接在数据库客户端里跑指令部分被当成注释忽略又能被框架解析成动态 SQL。这个双向可用的特性对调试帮助极大但也意味着指令的语法必须严格错一个符号就从能跑变成编译失败。3.1 绑定变量占位符的样例值不是废代码SQL 文件里你会看到这种写法select id, name, age from users where id /* id */1/* id */后面那个1看起来像随手写的其实是占位符的样例值。它的作用是让这条 SQL 在数据库客户端里能直接执行——把/* id */换成实际值的位置就是这里。DOMA 解析时会把它替换成真正的绑定参数值本身不参与执行。理解这一点很重要因为它解释了为什么占位符的位置必须精确where id /* id */1是对的where id 1 /* id */就不对解析器认不出绑定变量会把它当成字面量。我之前接手过一个项目SQL 里全是后一种写法测试环境数据量小一直没暴露上生产后因为无法使用索引直接超时排查了半天才发现是绑定变量根本没生效。3.2 条件分支里最容易写错的空值判断动态条件的标准写法select * from users where 1 1 /*%if name ! null and name ! */ and name like /* name */%a% /*%end*/几个容易翻车的点。第一表达式里用and还是两种写法框架都支持但同一个文件里混用容易出错选一种固定下来。第二字符串比较用还是双引号SQL 文件里的表达式遵循的是框架的表达式语法字符串字面量用单引号这一点和 Java 不一样。第三也是最容易忽略的/*%if */和/*%end*/必须成对出现嵌套时尤其容易漏。漏了的后果不是运行时报错而是编译期解析失败报错信息会告诉你哪个文件的哪个位置括号不匹配但行号有时会偏移得对着文件慢慢数。我自己的应对办法是给每个条件块加注释标号比如/*%if ... */ -- c1/*%end*/ -- c1嵌套三层以上时全靠这个对齐。3.3 IN 展开与空列表保护IN 查询是最容易写出问题的场景。传一个列表进去指望它自动展开成in (1, 2, 3)需要两个配合参数上加In注解SQL 里用展开指令select * from users where id in /*%expand*/(/* ids */1, 2)这里有个必须处理的边界列表为空。空列表展开后得到的是in ()语法错误。所以外面要套一层条件判断/*%if ids ! null and ids.size() 0 */ and id in /*%expand*/(/* ids */1, 2) /*%end*/有人会说空列表直接返回空结果不就行了逻辑上确实如此但在 DAO 层做判断会让每个调用方都得记得处理不如把保护写进 SQL 模板里一次写好终身受益。另外IN 列表的元素数量也要有上限意识某些数据库对 IN 里的元素个数有限制超过会报错或者性能骤降。遇到大批量 ID 的场景老老实实分批查别硬塞。3.4 LIKE 转义与 Escape模糊查询里如果用户输入了%或者_直接拼进 LIKE 会变成通配符搜50%可能把全表都捞出来。DOMA 提供了专门的处理方式参数上加Escape注解指定转义字符框架会自动对%、_和转义字符本身做处理。Select ListUser searchByName(Escape(escapeChar \\) String name);对应的 SQL 里要写escape \声明转义字符两边必须一致。这一点经常被漏掉Java 侧加了注解SQL 里没写escape子句转义字符就被当成普通字符匹配了结果就是搜不到东西但又不报错非常难查。3.5 动态排序不要硬拼字符串order by后面跟列名这个位置不能放绑定变量大部分数据库不支持order by ?所以不能简单写成order by /* sortColumn */id。常见的处理方式是分支穷举order by /*%if sortKey name */ name /*%elseif sortKey age */ age desc /*%else*/ id /*%end*/看起来啰嗦但这是最安全的做法——列名来自白名单不可能被注入。如果排序维度很多穷举会很冗长可以用展开指令配合服务端的白名单校验但白名单校验一定要做在服务端别把列名直接从请求参数透传到 SQL 层。4. 实体映射的四个高频坑实体映射是 DOMA 里配置量最大的部分也是看着能跑、实际有隐患最集中的地方。很多问题不会立刻报错等到数据出问题才暴露。4.1 驼峰属性与下划线列名Java 属性习惯驼峰数据库列名习惯下划线两者对不上就会导致映射失败或者映射到空值。DOMA 的处理方式有两种一是每个属性显式加Column(name user_name)二是配置全局的命名策略。显式注解最稳缺点是字段多的时候啰嗦。全局命名策略省事但要确认你用的版本支持哪种枚举值不同版本的枚举名可能不一样。我的建议是核心业务表用显式注解日志表、配置表这类字段稳定的用全局策略。理由很实际——核心表的字段变更频率高映射关系写在代码里一眼可见改的时候不容易漏边缘表字段几年不动省点代码量更划算。还有一个容易忽略的点如果查询结果的列名和实体属性对不上DOMA 不会抛异常对应属性就是 null 或默认值。这种静默错位比报错危险得多所以上线前一定要跑一次真实数据的查询验证。4.2 基本类型和包装类型的取舍实体里用int还是Integer这个选择有实质影响。数据库列允许 NULL 时如果用基本类型查出来的 NULL 没法表达行为取决于框架的具体实现可能是默认值 0可能是报错。更麻烦的是更新操作一个int字段你无法区分用户主动设为 0和这个字段没查出来。我的原则很简单实体字段一律用包装类型除非这个字段确定非空且业务上有明确的默认语义。代价是多几个 null 判断收益是避免了一整类数据莫名其妙变成 0的线上问题。这个规则在金额、计数、状态位这几类字段上尤其重要金额变成 0 的后果不用多说。4.3 只更新改动字段OriginalStates 的正确姿势默认的更新语句是全字段更新也就是把实体里所有映射字段都写进set子句。这在高并发场景下有问题两个请求同时读同一条记录A 改了字段 xB 改了字段 y全字段更新会导致后提交的把先提交的覆盖掉。DOMA 的解法是在实体里加一个特殊字段并用注解标记Entity public class User { Id Integer id; String name; String email; OriginalStates User originalStates; }加了之后更新时框架会对比当前值和快照值只把变化的字段写进set子句。听起来很美好但有个前提实体必须是从数据库查出来的。如果你手动new一个实体、只填了 id 和要改的字段originalStates是 null行为就退化成全字段更新没填的字段会被写成 null。这个坑我见过不止一次表现是更新一个字段结果其他字段全空了。正确姿势是先selectById查出完整实体改字段再update。多一次查询换来的是更新语义的安全性。4.4 乐观锁 Version 的更新条件Version标注的字段会自动参与更新条件SQL 大致是update ... set version version 1 where id ? and version ?。更新影响的记录数为 0 就说明版本冲突了业务层要处理这个返回值。这里有个细节返回 0 不等于出错。很多代码把update返回值直接判断为成功/失败遇到版本冲突时抛出数据不存在的异常误导排查方向。正确做法是区分记录不存在和版本冲突前者查一次就能确认后者要考虑重试或者提示用户。另外乐观锁字段的初始值要和数据库列默认值一致。见过数据库默认 0、实体初始化成 1 的配置结果第一次更新就冲突因为条件里带的是version 1但库里存的是 0。5. 事务与连接独立运行和容器托管的差别事务这块的问题通常不是事务不生效而是事务生效了但用了不该用的连接。表现是连接池被打满、或者同一段逻辑里两次查询看到的数据不一致。5.1 独立场景下的事务边界不用任何容器、纯 Java 应用里跑 DOMA事务要靠框架自带的事务管理器通过required、requiresNew这类传播行为来划定边界TransactionManager tm new TransactionManager(config); tm.required(() - { dao.insert(a); dao.insert(b); });这里的关键是同一个事务管理器实例必须复用。如果每次调用都new一个事务边界就是断的两次插入各自提交出异常也回滚不了。这类写法在工具类里特别容易出问题因为工具类往往是每次调用都新建对象。5.2 和 Spring 混管时的连接泄漏把 DOMA 放进 Spring 环境后事务通常交给 Spring 管理DOMA 的事务管理器就不该再参与了。两者混用会出现看起来有事务、实际是两个连接的情况Spring 开了事务拿到连接 ADOMA 自带的事务管理器又去数据源要了连接 B两条连接各自持有事务锁等待、死锁、连接池耗尽全来了。判断方法很直接在事务方法里打印当前连接对象看两次数据库操作的连接是不是同一个。不是同一个就是混管了。修复方式是把 DOMA 的配置接到 Spring 管理的连接上让框架感知 Spring 的事务上下文而不是自己开事务。还有一个相关的坑是只读查询也开事务。严格来说读操作不需要事务但在 Spring 里如果方法上挂了事务注解就会占用一个连接直到方法结束。批量查询、报表导出这类耗时操作一旦开了事务连接被长时间占用并发一高就打满池子。读操作单独配置只读事务或者干脆不开事务能省下不少连接。6. 主键、批量与分页三件事这三块都属于能用但容易用错的典型用错了不报错只是性能差或者数据不对。6.1 自增主键的三种生成策略DOMA 支持三种主键生成方式数据库自增IDENTITY、序列SEQUENCE、表模拟序列TABLE。选择依据主要是数据库本身的能力和你对批量插入的需求。策略适用场景主要限制IDENTITY单条插入为主需要立刻拿到主键批量插入时主键回填不可靠性能受限SEQUENCE批量插入、需要预分配主键依赖数据库序列对象部分数据库不支持TABLE数据库不支持序列时的替代方案每次取值都要访问表并发下有锁竞争选 IDENTITY 最省心但如果你有批量导入的需求就要提前想清楚批量插入时自增主键无法逐条回填实体对象里的 id 是空的。后面如果要用这个 id 做关联就得换个策略。这个决策要在表设计阶段做中途换代价很大。6.2 批量插入的注解选择DOMA 提供两种批量插入一种是 JDBC 层面的批量执行框架的批量插入注解一条 SQL 反复绑定参数另一种是拼成一条多值insert ... values (...), (...), (...)的语句。前者兼容性好、内存占用低后者在数据量大时往返次数少、通常更快。选择依据不只是性能。多值插入在不同数据库上对 SQL 长度有限制一次塞几千行可能触发报文大小限制批量执行则受限于驱动是否支持批量重写。我的经验是几百行以内用多值插入上千行分批走批量执行批次大小控制在 500 到 1000 之间太大反而因为日志和锁的原因变慢。还有一点容易忽略批量操作放在一个事务里和每条单独提交性能差一个数量级。批量写之前确认事务边界包住了整个批次否则等于一条一条提交。6.3 分页不要自己拼 limitDOMA 的分页是通过额外的参数对象把 limit 和 offset 传给框架由方言决定具体的 SQL 语法。Oracle 用rownum、MySQL 用limit、SQL Server 用offset fetch这些差异框架帮你处理了。自己拼limit的后果是换数据库就崩。ListUser selectAll(SelectOptions options); // 调用 dao.selectAll(SelectOptions.get().limit(20).offset(40));分页还有个隐藏问题深分页。offset很大时数据库要扫描并丢弃前面的行越翻越慢。这种情况改用游标分页带上一次的最后一条记录的排序键能解决但那就不在框架的分页能力范围内了需要自己写 SQL。7. Spring Boot 集成时的配置边界Spring Boot 环境用 DOMA一般是通过官方提供的 starter 自动配置省掉大量手工装配。但自动配置的边界如果不清楚出问题时反而无从下手。7.1 starter 帮你做了哪些自动配置starter 主要做三件事读取配置项构造框架的运行配置对象、注册数据源和事务管理的桥接、扫描 DAO 接口注册成 Bean。这三件事的顺序是有依赖的所以配置项写错时报错往往出现在第二、三步而不是第一步。常见的配置项包括数据源引用、方言、SQL 日志类型、异常日志类型。方言要显式配置因为框架没法可靠地从连接元数据推断出你要用哪种分页和主键获取方式——同一个数据库在不同模式下行为可能不同。这点很多人忽略觉得连上了就行了结果分页语法不对。7.2 多数据源下 Config 与 Dao 的隔离单数据源很舒服多数据源就开始出问题。核心是两件事每个数据源要有一套独立的运行配置每个 DAO 要明确归属到哪套配置上。如果两个数据源的 DAO 混在同一个包下扫描很容易出现A 库的 DAO 用了 B 库的连接。症状是查询报表不存在因为确实在错误的库里查了。解决办法是按包隔离配置扫描规则把每个数据源的 DAO 放在独立包下配套独立的配置类和事务管理器。7.3 方言配错引发的隐蔽错误方言配错的典型表现不是报错而是行为异常分页返回的行数不对、IN 列表展开的语法不对、批量插入报语法错误。因为框架生成 SQL 时依赖方言决定语法方言和实际数据库不匹配时生成的 SQL 可能语法正确但语义不对比如用 MySQL 的方言连 PostgreSQLlimit ?也能跑但序列取值、字符串拼接这些细节会出问题。判断方法打开 SQL 日志看实际执行的语句是不是你要的语法。这条建议适用所有怀疑方言的问题。8. 把日志和代码生成用起来问题少一半最后这块不讲问题讲两个能显著降低问题出现率的实践。8.1 打开 SQL 日志的正确粒度框架的 SQL 日志分几个级别不打、打原始 SQL带?占位、打可读 SQL参数已代入。开发环境用可读形式一眼能看出参数对不对生产环境用原始形式避免日志里大量敏感数据。配置上就是把 DOMA 根包对应的 logger 级别调到 DEBUG。根包名在依赖里翻一下注解源码就能看到配的时候注意别写到子包上否则部分日志会漏掉。另外异常发生时框架也会输出 SQL这个开关单独控制建议生产环境打开——异常时的 SQL 往往是排查问题的关键线索。注意日志里打印参数意味着任何敏感信息都会落盘。涉及凭证、身份信息的表生产环境的 SQL 日志要评估后再开或者只开异常场景。8.2 用代码生成对齐表结构框架配套的代码生成工具能从数据库表结构反向生成实体和 DAO这在接手老项目或者表结构频繁变更时非常好用。配置好驱动、连接信息、表名过滤规则和目标目录执行生成任务就行。生成完之后一定要重新编译一次因为注解处理器需要读到新的实体和 DAO 接口才会生成 Impl。这算是我踩过的一个小坑生成代码后直接跑测试报找不到 Impl以为是生成工具出问题其实只是没重新编译处理器还没跑。现在我把生成和编译串成一个命令省得每次都忘。
企业数字化 ERP 产品动态
相关推荐
VoiceStudio实战:中文语音合成与零样本声音克隆完整指南 前阵子把我手头一个叫VoiceStudio的语音合成项目从想法折腾到了能稳定出活的版本,整个过程踩坑不少,但收获也很大。今天不聊PPT上的架构图,就实打实聊聊这个项目到底在做什么、语音合成的关键环节怎么拆、以及整套流程落地时那些文档里不会写… · 2026/11/2 14:31:40
城市基础设施中的技术镜像与跨场景应用 1. 城市基础设施中的技术镜像现象上周五早高峰,我在北京西二旗地铁站看到这样一幕:一位乘客用手机NFC功能刷闸机时,设备反应延迟了约1.5秒。这个看似普通的场景,让我突然意识到城市不同场景的技术系统正在发生奇妙的"镜像映射… · 2026/11/2 14:31:40
Pytest缓存机制:优化自动化测试数据传递 1. 为什么需要测试结果缓存 在自动化测试实践中,我们经常会遇到这样的场景:测试用例A生成的数据需要在测试用例B中使用,或者某个前置操作产生的标识符需要在后续多个测试步骤中传递。传统做法是通过全局变量或者外部存储来实现,但… · 2026/11/2 14:30:40
Kornia 中值模糊(Median Blur)并行化分析与 CPU 快速路径实现详解 计算机视觉深度学习图像处理 【免费下载链接】kornia 🐍 Geometric Computer Vision Library for Spatial AI 项目地址: https://gitcode.com/GitHub_Trending/ko/kornia 点击查看 免费下载 中值模糊是图像去噪中的经典非线性算子,但在深度学… · 2026/11/2 15:04:37
wkhtmltopdf HTML转PDF 实战指南:从 HTML 文件到成品 PDF wkhtmltopdf HTML转PDF 实战指南:从 HTML 文件到成品 PDF 【免费下载链接】wkhtmltopdf Convert HTML to PDF using Webkit (QtWebKit) 项目地址: https://gitcode.com/gh_mirrors/wk/wkhtmltopdf
wkhtmltopdf 是一款基于 QT Webkit 渲染引擎的无头命令行工具… · 2026/11/2 15:03:31
Harmony OS C++实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 15:03:31
九联UNT402A刷机改造指南:闲置S905L3机顶盒,20分钟变身24小时在线的Armbian服务器 九联UNT402A刷机改造指南:闲置S905L3机顶盒,20分钟变身24小时在线的Armbian服务器 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d… · 2026/11/2 15:03:31
支持手机端夸克不限速 - 免费永久解析直链~满速下载!! 今天教大家一招能解决夸克网盘限制的在线工具。这个工具也是完全免费使用的。下面让大家看看我用这个工具的下载速度咋样。地址获取:放在这里了,可以直接获取 这个速度还是不错的把。对于平常不怎么下载的用户还是很友好的。下面开始今天的教学 输入我给… · 2026/11/2 15:03:31
Dolphin-Mistral 24B威尼斯版:掌控你的无审查AI Dolphin-Mistral 24B威尼斯版:掌控你的无审查AI
导语:Dolphin-Mistral 24B威尼斯版正式发布,这款由dphn.ai与Venice.ai联合打造的大语言模型以"无审查"和"用户控制权"为核心卖点,挑战现有AI服务模式ÿ… · 2026/11/2 15:03:31
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18
雷达信号调制技术解析:从LFM到伪线性调频原理与应用 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
基于MAX14431与TM4C123的工业SPI隔离电路设计全攻略 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
PLFM_RADAR:相位线性调频雷达信号处理框架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18