nestjs实战(五): 连接达梦数据库的两种方式(完整实战教程)

news2026/3/21 15:54:41
还在为 NestJS 项目接入达梦数据库发愁想用 TypeORM 优雅操作国产数据库却不知道如何配置今天这篇教程全程围绕 NestJS 与达梦数据库的集成展开从原生驱动连接到 TypeORM 整合详细解释每一步流程和核心代码并以 DMHR.CITY 表为例进行完整演示。1. 先搞懂为什么需要两种方式连接达梦达梦数据库是国内主流的国产关系型数据库但在 Node.js 生态中官方驱动dmdb是 C 插件TypeScript 类型支持不完善。NestJS 作为企业级框架追求代码规范与类型安全这就产生了两种常见方案方案适用场景优点缺点原生驱动方案简单查询、快速原型轻量、直接、无额外依赖类型不安全需手动管理连接TypeORM 方案复杂业务、团队协作ORM 映射、类型安全、迁移方便需配置typeorm-dm扩展2. 准备工作达梦数据库环境搭建2.1 安装达梦数据库从达梦官网下载对应操作系统的 DM8 安装包完成安装。本地测试可使用 Dockerbashdocker run -d -p 5236:5236 \ -e DM_USERSYSDBA \ -e DM_PASSWORDAa123456 \ --name dm8 \ dm8:latest2.2 确认表结构达梦数据库自带示例模式 DMHR包含 CITY 表和 REGION 表REGION 表地区表sqlCREATE TABLE DMHR.REGION ( REGION_ID INT PRIMARY KEY, REGION_NAME VARCHAR(50) ); INSERT INTO DMHR.REGION VALUES (1, 华北地区); INSERT INTO DMHR.REGION VALUES (2, 华东地区); INSERT INTO DMHR.REGION VALUES (3, 华南地区);CITY 表城市表REGION_ID 为外键2.3 安装依赖bashnpm install dmdb typeorm nestjs/typeorm reflect-metadata typeorm-dm注意dmdb是 C 插件需要 Node.js 编译环境Python、Visual Studio Build Tools 或 g。3. 方案一原生驱动连接详细流程3.1 核心代码解析javascriptconst dmdb require(dmdb); class NativeDbService { constructor() { this.logger new Logger(NativeDbService); this.pool null; } async onModuleInit() { try { // 【关键点1】解决 OpenSSL 兼容性问题 process.env.NODE_OPTIONS --openssl-legacy-provider; // 【关键点2】创建连接池 this.pool await dmdb.createPool({ connectionString: dm://SYSDBA:Aa123456localhost:5236/DAMENG?schemaDMHR, poolMax: 10, // 最大连接数 poolMin: 1, // 最小连接数 poolTimeout: 60, // 连接超时时间秒 }); // 【关键点3】测试连接 let testConn; try { testConn await this.pool.getConnection(); this.logger.log(✅ 原生驱动连接成功DMHR 模式); } finally { if (testConn) testConn.release(); // 必须释放连接 } } catch (error) { this.logger.error(❌ 原生驱动连接失败, error); throw error; } } // 【关键点4】获取连接 async getConnection() { return await this.pool.getConnection(); } // 【关键点5】执行 SQL 查询自动释放连接 async query(sql, params []) { const conn await this.getConnection(); try { if (params params.length 0) { const result await conn.execute(sql, params); return result; } else { const result await conn.execute(sql); return result; } } finally { conn.release(); // 无论成功失败都要释放连接 } } // 【关键点6】解析查询结果 async getAllCities() { const sql SELECT * FROM DMHR.CITY ORDER BY CITY_ID; const result await this.query(sql); // 达梦驱动返回的结果格式{ metaData: [...], rows: [...] } if (result result.rows) { const cities result.rows.map(row { const city {}; result.metaData.forEach((col, index) { city[col.name] row[index]; }); return city; }); return cities; } return result; } async onModuleDestroy() { if (this.pool) await this.pool.close(); // 关闭连接池 } }3.2 流程详解步骤1导入驱动使用require(dmdb)而非import因为dmdb没有 TypeScript 类型定义这样可以完全避开 TypeScript 的类型检查步骤2创建连接池createPool是异步方法返回连接池实例connectionString格式dm://用户名:密码主机:端口/数据库?schema模式名连接池参数poolMax最大连接数根据业务并发量设置poolMin最小连接数保持一定数量的活跃连接poolTimeout获取连接的超时时间步骤3测试连接从连接池获取一个连接执行简单查询验证连接有效性重要使用try/finally确保连接被释放步骤4执行查询从连接池获取连接执行 SQL 语句必须释放连接否则连接池会耗尽步骤5结果解析达梦驱动返回{ metaData, rows }格式metaData字段信息数组每个元素有name属性rows数据行数组每行是字段值的数组需要手动转换为对象数组4. 方案二TypeORM 整合详细流程4.1 核心代码解析javascriptconst { DmdbDataSource } require(typeorm-dm); const { EntitySchema } require(typeorm); require(reflect-metadata); // 【关键点1】定义实体使用 EntitySchema const CitySchema new EntitySchema({ name: City, // 实体名称 tableName: CITY, // 数据库表名 schema: DMHR, // 数据库模式名 columns: { CITY_ID: { primary: true, // 主键 type: varchar, // 字段类型 length: 3, // 长度限制 name: CITY_ID // 数据库字段名 }, CITY_NAME: { type: varchar, length: 50, name: CITY_NAME }, REGION_ID: { type: int, name: REGION_ID } } }); // 【关键点2】配置数据源 const typeormConfig { type: oracle, // 达梦兼容 Oracle 协议 innerType: dmdb, // 指定为达梦驱动 host: localhost, port: 5236, username: SYSDBA, password: Aa123456, schema: DMHR, // 默认模式 entities: [CitySchema, RegionSchema], synchronize: false, // 生产环境必须为 false logging: true, // 打印 SQL 日志 extra: { connectTimeout: 30000, } }; // 【关键点3】创建数据源实例 const AppDataSource new DmdbDataSource(typeormConfig); class TypeormDbService { constructor() { this.logger new Logger(TypeormDbService); this.dataSource null; } async onModuleInit() { try { // 【关键点4】初始化数据源 await AppDataSource.initialize(); this.dataSource AppDataSource; this.logger.log(✅ TypeORM 连接成功); // 测试连接 const cityRepo this.dataSource.getRepository(City); const cityCount await cityRepo.count(); this.logger.log(CITY 表中共有 ${cityCount} 条记录); } catch (error) { this.logger.error(❌ TypeORM 连接失败, error); throw error; } } // 【关键点5】使用 Repository 进行 CRUD async getAllCities() { const cityRepo this.dataSource.getRepository(City); return await cityRepo.find({ order: { CITY_ID: ASC } }); } async createCity(cityData) { const cityRepo this.dataSource.getRepository(City); const newCity cityRepo.create(cityData); return await cityRepo.save(newCity); } async onModuleDestroy() { if (this.dataSource) await this.dataSource.destroy(); } }4.2 流程详解步骤1定义实体EntitySchema 方式name实体名称用于getRepository(City)获取tableName数据库实际表名注意大小写schema数据库模式名达梦区分模式columns字段映射指定数据库字段名与实体属性的对应关系步骤2配置数据源type: oracle达梦兼容 Oracle 协议innerType: dmdb指定使用达梦驱动synchronize: false生产环境必须关闭避免误操作表结构logging: true开启后控制台打印执行的 SQL 语句便于调试步骤3初始化数据源initialize()是异步方法会建立数据库连接只有初始化成功后才能进行后续操作步骤4获取 RepositorygetRepository(City)根据实体名称获取操作对象Repository 提供find、findOne、save、update、delete等方法步骤5CRUD 操作create()创建实体实例不保存到数据库save()保存实体插入或更新find()查询多条记录findOne()查询单条记录update()更新记录delete()删除记录5. 完整代码运行/** * NestJS 连接达梦数据库的两种方式单文件实现 * 操作表DMHR.CITY实际表结构CITY_ID CHAR(3), CITY_NAME VARCHAR(50), REGION_ID INT * 注意REGION_ID 是外键必须存在于 DMHR.REGION 表中 */ const { Injectable, Logger } require(nestjs/common); // 方式一原生驱动连接 const dmdb require(dmdb); class NativeDbService { constructor() { this.logger new Logger(NativeDbService); this.pool null; } async onModuleInit() { try { process.env.NODE_OPTIONS --openssl-legacy-provider; this.pool await dmdb.createPool({ connectionString: dm://SYSDBA:Aa123456localhost:5236/DAMENG?schemaDMHR, poolMax: 10, poolMin: 1, poolTimeout: 60, }); let testConn; try { testConn await this.pool.getConnection(); this.logger.log(✅ 原生驱动连接成功DMHR 模式); } finally { if (testConn) testConn.release(); } } catch (error) { this.logger.error(❌ 原生驱动连接失败, error); throw error; } } async getConnection() { return await this.pool.getConnection(); } async onModuleDestroy() { if (this.pool) await this.pool.close(); } async query(sql, params []) { const conn await this.getConnection(); try { if (params params.length 0) { const result await conn.execute(sql, params); return result; } else { const result await conn.execute(sql); return result; } } finally { conn.release(); } } // 查询 REGION 表获取有效的 REGION_ID async getAllRegions() { const sql SELECT * FROM DMHR.REGION ORDER BY REGION_ID; const result await this.query(sql); if (result result.rows) { const regions result.rows.map(row { const region {}; result.metaData.forEach((col, index) { region[col.name] row[index]; }); return region; }); return regions; } return []; } // CITY 表专用方法 async getAllCities() { const sql SELECT * FROM DMHR.CITY ORDER BY CITY_ID; const result await this.query(sql); if (result result.rows) { const cities result.rows.map(row { const city {}; result.metaData.forEach((col, index) { city[col.name] row[index]; }); return city; }); return cities; } return result; } async getCityById(cityId) { const sql SELECT * FROM DMHR.CITY WHERE CITY_ID ${cityId}; const result await this.query(sql); if (result result.rows result.rows.length 0) { const city {}; result.metaData.forEach((col, index) { city[col.name] result.rows[0][index]; }); return city; } return null; } async getCitiesByRegion(regionId) { const sql SELECT * FROM DMHR.CITY WHERE REGION_ID ${regionId} ORDER BY CITY_ID; const result await this.query(sql); if (result result.rows) { const cities result.rows.map(row { const city {}; result.metaData.forEach((col, index) { city[col.name] row[index]; }); return city; }); return cities; } return []; } async createCity(cityData) { if (cityData.CITY_ID.length 3) { throw new Error(CITY_ID 长度不能超过 3 个字符当前: ${cityData.CITY_ID}); } const sql INSERT INTO DMHR.CITY (CITY_ID, CITY_NAME, REGION_ID) VALUES (${cityData.CITY_ID}, ${cityData.CITY_NAME}, ${cityData.REGION_ID}); const result await this.query(sql); return result; } async updateCity(cityId, cityData) { const sql UPDATE DMHR.CITY SET CITY_NAME ${cityData.CITY_NAME}, REGION_ID ${cityData.REGION_ID} WHERE CITY_ID ${cityId}; const result await this.query(sql); return result; } async deleteCity(cityId) { const sql DELETE FROM DMHR.CITY WHERE CITY_ID ${cityId}; const result await this.query(sql); return result; } } // 方式二TypeORM 整合 const { DmdbDataSource } require(typeorm-dm); const { EntitySchema } require(typeorm); require(reflect-metadata); // 使用 EntitySchema 定义 City 实体 const CitySchema new EntitySchema({ name: City, tableName: CITY, schema: DMHR, columns: { CITY_ID: { primary: true, type: varchar, length: 3, name: CITY_ID }, CITY_NAME: { type: varchar, length: 50, name: CITY_NAME }, REGION_ID: { type: int, name: REGION_ID } } }); // Region 实体用于查询有效的外键值 const RegionSchema new EntitySchema({ name: Region, tableName: REGION, schema: DMHR, columns: { REGION_ID: { primary: true, type: int, name: REGION_ID }, REGION_NAME: { type: varchar, length: 50, name: REGION_NAME } } }); // TypeORM 数据源配置 const typeormConfig { type: oracle, innerType: dmdb, host: localhost, port: 5236, username: SYSDBA, password: Aa123456, schema: DMHR, entities: [CitySchema, RegionSchema], synchronize: false, logging: true, extra: { connectTimeout: 30000, } }; // 创建 TypeORM 数据源实例 const AppDataSource new DmdbDataSource(typeormConfig); // TypeORM 服务封装 class TypeormDbService { constructor() { this.logger new Logger(TypeormDbService); this.dataSource null; } async onModuleInit() { try { await AppDataSource.initialize(); this.dataSource AppDataSource; this.logger.log(✅ TypeORM 连接成功DMHR 模式); const regionRepo this.dataSource.getRepository(Region); const regionCount await regionRepo.count(); this.logger.log(REGION 表中共有 ${regionCount} 条记录); const cityRepo this.dataSource.getRepository(City); const cityCount await cityRepo.count(); this.logger.log(CITY 表中共有 ${cityCount} 条记录); } catch (error) { this.logger.error(❌ TypeORM 连接失败, error); throw error; } } async onModuleDestroy() { if (this.dataSource) await this.dataSource.destroy(); } // CITY 表专用方法 async getAllCities() { const cityRepo this.dataSource.getRepository(City); return await cityRepo.find({ order: { CITY_ID: ASC } }); } async getCityById(cityId) { const cityRepo this.dataSource.getRepository(City); return await cityRepo.findOne({ where: { CITY_ID: cityId } }); } async getCitiesByRegion(regionId) { const cityRepo this.dataSource.getRepository(City); return await cityRepo.find({ where: { REGION_ID: regionId }, order: { CITY_ID: ASC } }); } async createCity(cityData) { if (cityData.CITY_ID.length 3) { throw new Error(CITY_ID 长度不能超过 3 个字符当前: ${cityData.CITY_ID}); } const cityRepo this.dataSource.getRepository(City); const newCity cityRepo.create(cityData); return await cityRepo.save(newCity); } async updateCity(cityId, cityData) { const cityRepo this.dataSource.getRepository(City); await cityRepo.update(cityId, cityData); return await this.getCityById(cityId); } async deleteCity(cityId) { const cityRepo this.dataSource.getRepository(City); const result await cityRepo.delete(cityId); return result.affected 0; } // REGION 表专用方法 async getAllRegions() { const regionRepo this.dataSource.getRepository(Region); return await regionRepo.find({ order: { REGION_ID: ASC } }); } async getRegionById(regionId) { const regionRepo this.dataSource.getRepository(Region); return await regionRepo.findOne({ where: { REGION_ID: regionId } }); } } // 业务服务 class CityService { constructor(nativeDbService, typeormDbService) { this.nativeDbService nativeDbService; this.typeormDbService typeormDbService; this.logger new Logger(CityService); } async queryCitiesWithNative() { try { this.logger.log(使用原生驱动查询所有城市...); const cities await this.nativeDbService.getAllCities(); this.logger.log(原生驱动查询到 ${cities.length} 个城市); return cities; } catch (error) { this.logger.error(原生驱动查询失败, error); throw error; } } async queryCitiesWithTypeorm() { try { this.logger.log(使用 TypeORM 查询所有城市...); const cities await this.typeormDbService.getAllCities(); this.logger.log(TypeORM 查询到 ${cities.length} 个城市); return cities; } catch (error) { this.logger.error(TypeORM 查询失败, error); throw error; } } async getValidRegions() { try { this.logger.log(查询有效的地区列表...); const regions await this.typeormDbService.getAllRegions(); return regions; } catch (error) { this.logger.error(查询地区失败, error); throw error; } } async createCityWithTypeorm(cityData) { try { this.logger.log(使用 TypeORM 创建城市${cityData.CITY_NAME}); const newCity await this.typeormDbService.createCity(cityData); this.logger.log(创建成功ID${newCity.CITY_ID}); return newCity; } catch (error) { this.logger.error(TypeORM 创建城市失败, error); throw error; } } async deleteCityWithTypeorm(cityId) { try { this.logger.log(使用 TypeORM 删除城市 ID: ${cityId}); const success await this.typeormDbService.deleteCity(cityId); this.logger.log(success ? 删除成功 : 删除失败可能不存在); return success; } catch (error) { this.logger.error(TypeORM 删除城市失败, error); throw error; } } } // 测试函数 async function testNativeDriver() { console.log(\n 测试方式一原生驱动DMHR.CITY ); const nativeService new NativeDbService(); try { await nativeService.onModuleInit(); // 0. 先查询有效的 REGION_ID console.log(\n--- 0. 查询有效的地区列表 ---); const regions await nativeService.getAllRegions(); console.log(有效地区, regions); // 使用第一个有效的 REGION_ID const validRegionId regions.length 0 ? regions[0].REGION_ID : 1; console.log(使用地区 ID: ${validRegionId}); // 1. 查询所有城市 console.log(\n--- 1. 查询所有城市 ---); const allCities await nativeService.getAllCities(); console.log(所有城市, allCities); // 2. 根据 ID 查询城市 console.log(\n--- 2. 根据 ID 查询城市 ---); const city await nativeService.getCityById(BJ); console.log(IDBJ 的城市, city); // 3. 根据地区查询城市 console.log(\n--- 3. 根据地区查询城市 ---); const regionCities await nativeService.getCitiesByRegion(validRegionId); console.log(地区 ID${validRegionId} 的城市, regionCities); // 4. 新增测试城市使用有效的 REGION_ID console.log(\n--- 4. 新增测试城市 ---); const testCityId T1; await nativeService.createCity({ CITY_ID: testCityId, CITY_NAME: 测试城市, REGION_ID: validRegionId }); console.log(新增城市成功ID: ${testCityId}); // 5. 查询验证新增 console.log(\n--- 5. 验证新增 ---); const testCity await nativeService.getCityById(testCityId); console.log(新增的城市, testCity); // 6. 删除城市 console.log(\n--- 6. 删除城市 ---); await nativeService.deleteCity(testCityId); console.log(删除成功); // 7. 验证删除 console.log(\n--- 7. 验证删除 ---); const deletedCity await nativeService.getCityById(testCityId); console.log(删除后的查询结果, deletedCity); } catch (error) { console.error(原生驱动测试失败, error); } finally { await nativeService.onModuleDestroy(); } } async function testTypeorm() { console.log(\n 测试方式二TypeORMDMHR.CITY ); const typeormService new TypeormDbService(); try { await typeormService.onModuleInit(); // 0. 获取有效的地区列表 console.log(\n--- 0. 查询有效的地区列表 ---); const regions await typeormService.getAllRegions(); console.log(有效地区, regions); const validRegionId regions.length 0 ? regions[0].REGION_ID : 1; console.log(使用地区 ID: ${validRegionId}); // 1. 查询所有城市 console.log(\n--- 1. 查询所有城市 ---); const allCities await typeormService.getAllCities(); console.log(所有城市, allCities); // 2. 根据 ID 查询城市 console.log(\n--- 2. 根据 ID 查询城市 ---); const city await typeormService.getCityById(BJ); console.log(IDBJ 的城市, city); // 3. 根据地区查询城市 console.log(\n--- 3. 根据地区查询城市 ---); const regionCities await typeormService.getCitiesByRegion(validRegionId); console.log(地区 ID${validRegionId} 的城市, regionCities); // 4. 新增测试城市使用有效的 REGION_ID console.log(\n--- 4. 新增测试城市 ---); const testCityId T2; const newCity await typeormService.createCity({ CITY_ID: testCityId, CITY_NAME: TypeORM测试城市, REGION_ID: validRegionId }); console.log(新增城市, newCity); // 5. 删除城市 console.log(\n--- 5. 删除城市 ---); const deleted await typeormService.deleteCity(testCityId); console.log(deleted ? 删除成功 : 删除失败); // 6. 验证删除 console.log(\n--- 6. 验证删除 ---); const finalCity await typeormService.getCityById(testCityId); console.log(删除后的查询结果, finalCity); } catch (error) { console.error(TypeORM 测试失败, error); } finally { await typeormService.onModuleDestroy(); } } async function testMixedUsage() { console.log(\n 测试混合使用DMHR.CITY ); const nativeService new NativeDbService(); const typeormService new TypeormDbService(); const cityService new CityService(nativeService, typeormService); try { await Promise.all([ nativeService.onModuleInit(), typeormService.onModuleInit() ]); // 0. 获取有效的地区列表 console.log(\n--- 0. 查询有效的地区列表 ---); const regions await cityService.getValidRegions(); console.log(有效地区, regions); const validRegionId regions.length 0 ? regions[0].REGION_ID : 1; console.log(使用地区 ID: ${validRegionId}); // 1. 使用 TypeORM 新增城市使用有效的 REGION_ID console.log(\n--- 1. 使用 TypeORM 新增城市 ---); const testCityId M1; await cityService.createCityWithTypeorm({ CITY_ID: testCityId, CITY_NAME: 混合测试城市, REGION_ID: validRegionId }); // 2. 使用原生驱动查询所有城市 console.log(\n--- 2. 使用原生驱动查询所有城市 ---); const nativeCities await cityService.queryCitiesWithNative(); console.log(原生驱动查询到 ${nativeCities.length} 个城市); // 3. 使用 TypeORM 查询所有城市 console.log(\n--- 3. 使用 TypeORM 查询所有城市 ---); const typeormCities await cityService.queryCitiesWithTypeorm(); console.log(TypeORM 查询到 ${typeormCities.length} 个城市); // 4. 使用 TypeORM 删除城市 console.log(\n--- 4. 使用 TypeORM 删除城市 ---); await cityService.deleteCityWithTypeorm(testCityId); // 5. 验证删除 console.log(\n--- 5. 验证删除 ---); const finalCities await cityService.queryCitiesWithTypeorm(); console.log(最终城市数量${finalCities.length}); } catch (error) { console.error(混合使用测试失败, error); } finally { await Promise.all([ nativeService.onModuleDestroy(), typeormService.onModuleDestroy() ]); } } async function main() { console.log( 达梦数据库连接测试启动); console.log(数据库配置localhost:5236, 用户:SYSDBA, 密码:Aa123456, 模式:DMHR); console.log(操作表DMHR.CITY外键约束REGION_ID 必须存在于 DMHR.REGION 表); const testMode process.argv[2] || all; switch (testMode) { case native: await testNativeDriver(); break; case typeorm: await testTypeorm(); break; case mixed: await testMixedUsage(); break; case all: default: await testNativeDriver(); await testTypeorm(); await testMixedUsage(); break; } console.log(\n✨ 所有测试完成); } if (require.main module) { main().catch(console.error); } module.exports { NativeDbService, TypeormDbService, CityService, typeormConfig, AppDataSource };将完整代码保存为dm-database.js运行测试bash# 运行所有测试 node dm-database.js # 只测试原生驱动 node dm-database.js native # 只测试 TypeORM node dm-database.js typeorm # 测试混合使用 node dm-database.js mixed预期输出text原生方式orm方式6. 常见问题与避坑指南6.1dmdb安装失败错误node-gyp编译失败解决bash# Windows npm install -g windows-build-tools # Ubuntu sudo apt-get install build-essential6.2 Node.js 版本兼容问题错误ERR_OSSL_EVP_UNSUPPORTED解决在代码开头设置环境变量javascriptprocess.env.NODE_OPTIONS --openssl-legacy-provider;6.3 外键约束问题错误违反引用约束[CITY_REG_FK]原因插入的 REGION_ID 在 REGION 表中不存在解决先查询有效的 REGION_IDjavascriptconst regions await nativeService.getAllRegions(); const validRegionId regions[0].REGION_ID;6.4 表名大小写问题达梦数据库对表名大小写敏感SQL 语句中使用大写sqlSELECT * FROM DMHR.CITY -- 正确 SELECT * FROM dmhr.city -- 可能出错6.5 连接池耗尽原因获取连接后没有释放解决使用try/finally确保释放javascriptconst conn await pool.getConnection(); try { await conn.execute(sql); } finally { conn.release(); // 必须执行 }6.6 TypeORM 实体找不到错误No metadata for City was found解决确保实体正确注册到entities数组使用EntitySchema方式定义实体确保name与getRepository参数一致7. 核心总结方案优点缺点推荐场景原生驱动性能好、轻量类型不安全、手动管理高性能、简单查询TypeORM类型安全、开发快性能略低、内存占用高复杂业务、团队协作接入三要素正确安装dmdb驱动配置正确的连接字符串注意 schema 参数处理好外键约束和表名大小写运行命令bash# 安装依赖 npm install dmdb typeorm nestjs/typeorm reflect-metadata typeorm-dm # 运行测试 node dm-database.js附录完整代码文件完整的dm-database.js文件已在上文提供可直接复制保存运行。代码包含原生驱动连接实现NativeDbService 类TypeORM 整合实现TypeormDbService 类业务服务封装CityService 类完整的测试函数三种测试模式导出供其他模块使用的接口

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…