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

NC65数据库操作全攻略:前后台查询与增删改实战(附防SQL注入技巧)

NC65数据库操作全攻略:前后台查询与增删改实战(附防SQL注入技巧)

在NC65企业级应用开发中,数据库操作是最基础也是最重要的技能之一。不同于常规的JDBC或ORM框架,NC65平台提供了自己独特的数据库访问机制,涵盖了从前台UI层到后台服务层的完整解决方案。本文将深入剖析这些技术细节,帮助开发者快速掌握核心要领。

1. 前台数据库操作精要

前台操作通常指运行在客户端(如浏览器)的代码逻辑,NC65通过IUAPQueryBS服务提供标准化的查询能力。这个设计巧妙地将复杂的SQL执行过程封装成简单的API调用,同时支持多种结果处理方式。

基础查询示例

IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class); String sql = "SELECT * FROM bd_material WHERE nvl(dr,0)=0"; List<Map<String,Object>> result = queryBS.executeQuery(sql, new MapListProcessor());

常用的结果处理器包括:

  • MapListProcessor:返回List<Map>结构,适合动态字段场景
  • BeanListProcessor:自动映射到VO对象集合
  • ColumnProcessor:提取单列数据
  • ArrayListProcessor:原始Object[]数组格式

提示:前台查询应避免大结果集,建议通过WHERE条件精确控制数据量

对于单据类操作,推荐使用封装好的高阶API:

// 通过主键获取单据AGGVO SalesOrderVO billVO = HYPubBO_Client.queryBillVOByPrimaryKey( SalesOrderVO.class, "1001A110000000000ABC" );

2. 后台数据库操作深度解析

后台操作通常指服务端私有方法,具有更高的灵活性和性能优势。BaseDAO是核心工具类,支持完整的CRUD操作。

2.1 查询操作模式对比

方法返回类型适用场景示例
executeQuery+ArrayListProcessorList<Object[]>原始数据查询多表联合查询
executeQuery+MapProcessorMap<String,Object>单行记录主键精确查询
executeQuery+BeanListProcessorList业务对象集合单据列表查询
executeQuery+自定义Processor任意类型特殊数据处理树形结构构建

典型查询示例

// 获取单行记录 String sql = "SELECT * FROM bd_supplier WHERE pk_supplier=?"; SQLParameter param = new SQLParameter(); param.addParam("1001A110000000000XYZ"); Map<String,Object> supplier = (Map<String,Object>)baseDAO.executeQuery( sql, param, new MapProcessor() ); // 获取VO对象集合 String hql = "FROM MaterialVO WHERE materialType=?"; List<MaterialVO> materials = (List<MaterialVO>)baseDAO.executeQuery( hql, new SQLParameter("RAW"), new BeanListProcessor(MaterialVO.class) );

2.2 增删改操作要点

更新操作需要特别注意事务管理:

try { baseDAO.startTransaction(); // 插入操作 String insertSQL = "INSERT INTO bd_department(pk_dept,dept_code) VALUES(?,?)"; SQLParameter insertParam = new SQLParameter(); insertParam.addParam(UUID.randomUUID().toString()); insertParam.addParam("DEPT_001"); baseDAO.executeUpdate(insertSQL, insertParam); // 更新操作 String updateSQL = "UPDATE bd_department SET dept_name=? WHERE pk_dept=?"; SQLParameter updateParam = new SQLParameter(); updateParam.addParam("研发中心"); updateParam.addParam("1001A110000000000KKK"); baseDAO.executeUpdate(updateSQL, updateParam); baseDAO.commit(); } catch(Exception e) { baseDAO.rollback(); throw e; }

3. 前后台通用操作方案

对于需要前后台复用的数据库逻辑,NC65提供了中间层服务抽象。IBillQueryService是最常用的接口之一:

// 获取服务实例 IBillQueryService queryService = NCLocator.getInstance().lookup(IBillQueryService.class); // 执行分页查询 PageCond page = new PageCond(1, 20); String countSQL = "SELECT COUNT(*) FROM bd_customer"; String dataSQL = "SELECT * FROM bd_customer"; SQLParameter param = new SQLParameter(); param.addParam("ACTIVE"); QueryResult result = queryService.queryWithPage( countSQL, dataSQL, param, page, new MapListProcessor() );

性能优化建议

  1. 对于大数据量查询,务必使用分页机制
  2. 频繁访问的数据考虑使用平台缓存
  3. 复杂查询建议在后台实现

4. SQL注入防御实战

安全是数据库操作的重中之重,NC65提供了多重防护机制:

4.1 参数化查询标准写法

StringBuilder sql = new StringBuilder(); sql.append("SELECT * FROM bd_user "); sql.append("WHERE user_code=? "); sql.append("AND nvl(dr,0)=?"); SQLParameter param = new SQLParameter(); param.addParam("admin"); // 用户输入参数 param.addParam(0); // 系统参数 List<UserVO> users = (List<UserVO>)baseDAO.executeQuery( sql.toString(), param, new BeanListProcessor(UserVO.class) );

4.2 动态SQL安全构建

对于条件不固定的查询,推荐使用安全拼接方式:

SQLBuilder builder = new SQLBuilder("SELECT * FROM bd_warehouse WHERE 1=1"); if(StringUtils.isNotEmpty(warehouseCode)){ builder.append(" AND warehouse_code=:code"); builder.setParameter("code", warehouseCode); } if(StringUtils.isNotEmpty(warehouseType)){ builder.append(" AND warehouse_type=:type"); builder.setParameter("type", warehouseType); } List<WarehouseVO> warehouses = (List<WarehouseVO>)baseDAO.executeQuery( builder.toString(), builder.getParameters(), new BeanListProcessor(WarehouseVO.class) );

4.3 输入验证策略

  1. 白名单校验:对编码类字段使用正则验证

    if(!Pattern.matches("[A-Z0-9_]{1,20}", userInput)){ throw new BusinessException("输入格式不符合要求"); }
  2. 类型强制转换:数字型参数必须转换

    try { Integer.parseInt(inputQty); } catch(NumberFormatException e) { // 异常处理 }
  3. 长度限制:防止超长字符串攻击

    if(inputString.length() > 100){ inputString = inputString.substring(0,100); }

5. 高级技巧与最佳实践

5.1 批量操作优化

对于大批量数据操作,建议使用批处理模式:

baseDAO.startTransaction(); try { String sql = "UPDATE bd_inventory SET qty=qty+? WHERE pk_material=?"; BatchSQLParameter batchParam = new BatchSQLParameter(); for(InventoryUpdate item : updateList){ SQLParameter param = new SQLParameter(); param.addParam(item.getDeltaQty()); param.addParam(item.getMaterialId()); batchParam.addBatch(param); } int[] results = baseDAO.executeBatch(sql, batchParam); baseDAO.commit(); } catch(Exception e) { baseDAO.rollback(); throw e; }

5.2 存储过程调用

NC65平台支持存储过程的标准调用方式:

String callSQL = "{call pkg_business.proc_calculate(?,?,?)}"; SQLParameter param = new SQLParameter(); param.addParam("202301"); param.addParam("FACTORY_001"); param.addParam(0); // 输出参数注册 Object result = baseDAO.executeQuery(callSQL, param, new ColumnProcessor());

5.3 元数据查询技巧

获取表结构信息:

String metaSQL = "SELECT column_name,data_type FROM user_tab_columns WHERE table_name=?"; List<Map<String,Object>> columns = (List<Map<String,Object>>)baseDAO.executeQuery( metaSQL, new SQLParameter("BD_MATERIAL"), new MapListProcessor() );

在实际项目中,我们发现将常用查询封装成工具方法可以显著提升开发效率。比如创建一个DBUtil类,包含各种标准的单条查询、列表查询、分页查询等方法。这样既保证了代码规范,又减少了重复劳动。

http://www.jsqmd.com/news/520653/

相关文章:

  • 手把手教你搞定JBI投稿:从Statement of Significance到Declaration Statement的保姆级避坑指南
  • Ryujinx模拟器实战指南:探索4个核心价值实现Switch游戏跨平台体验
  • 全球半导体材料会议精选名单,专业度与行业价值全面评估 - 品牌2026
  • 【嵌入式C代码合规性生死线】:ISO 26262/IEC 61508项目中,为什么92%的团队在验证阶段返工超3轮?
  • 突破设备壁垒:无需VR头显的3D视频实时转换技术
  • Silicon字体配置深度解析:多语言和特殊字符完美显示
  • [特殊字符] Local Moondream2个性化应用:构建个人专属图像知识库
  • 大模型部署避坑指南:Qwen2.5依赖版本核对清单
  • APKUpdater终极指南:一键聚合8大应用商店更新检测神器
  • Qwen3-0.6B轻松部署:跟着教程一步步来,快速体验智能对话
  • Qwen3模型Git版本控制实践:协作开发与模型迭代管理
  • Hunyuan-MT-7B实战落地:国际NGO少数民族地区项目文档本地化
  • Jetson Orin Nano开发者必看:PyTorch环境搭建避坑指南(附最新whl下载)
  • Z-Image-Turbo_Sugar脸部Lora与黑马点评项目结合:为用户生成个性化点评头像
  • 魔兽争霸3终极兼容性解决方案:WarcraftHelper完整使用指南
  • minimatch开发者进阶指南:自定义匹配器与扩展功能开发
  • 抖音无水印视频批量下载:内容创作者的终极工具指南 [特殊字符]
  • DDColor开源可部署价值:替代商业软件,年省数万元影像处理成本
  • Pistache错误处理与日志系统:构建健壮API的完整方案
  • NGINX Docker社区贡献指南:从代码提交到镜像发布全流程
  • 避坑指南:Livox Mid-360连接ROS2 Humble时,点云不显示的5个常见原因及解决方法
  • 亿佰特NT1模块在工业物联网中的5个典型应用场景(含配置避坑指南)
  • 2026年热门的35千伏预制舱厂家推荐:升压站预制舱公司精选 - 品牌宣传支持者
  • GLM-OCR赋能微信小程序:实现拍照即识别的身份证核验功能
  • GPT-OSS-20B部署避坑指南:从环境配置到流畅运行,一篇搞定
  • 利用Multisim构建可调式信号发生器的实践指南
  • Leather Dress Collection 算法优化指南:提升Transformer推理效率的实用技巧
  • 如何快速上手Nano-Banana:新手必看的10个核心技巧
  • PDF-Parser-1.0真实案例:如何批量处理企业报表PDF
  • Gemma-3-12b-it惊艳效果:交通标志识别+法规解释+事故责任链推理展示