# Crivia **Repository Path**: vmvm/Crivia ## Basic Information - **Project Name**: Crivia - **Description**: 提供基于泛微Ecology的开发支持,并对基于Crivia的程序提供一定运维支持 用法:将src内文件打成jar,或下载仓库内的crivia-*.jar,放入工程即可开发,部署到ecology即可运行 如需运维相关功能需配置crivia-mvc(e9以上仅展示) 功能: 1、流程action增强/dbo增强 2、ecology实施相关代码(流程/建模/对接json)生成 3、其它零星子功能 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: upgrade2025 - **Homepage**: https://gitee.com/theme_of_prontera/Crivia - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2025-12-04 - **Last Updated**: 2025-12-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Crivia开发指南 - 给务实开发者的选择 ## 🎯 框架定位 **「少写重复代码,专注业务逻辑」的务实方案**,经银行、OA等真实项目验证 > 如果你厌倦了每天写同样的CRUD代码,这个框架值得一试 --- ## 📦 安装即用 ```xml crivia.ymwddssb crivia 1-8-7-9 ``` --- ## 🆚 真实场景对比:为什么选择Crivia? ### 场景1:用户查询API - 每天都要写的CRUD #### ❌ 传统写法(35行样板代码,容易出错) ```java @RestController public class UserController { @GetMapping("/api/users") public String getUsers(@RequestParam String keyword, @RequestParam String status) { Map result = new HashMap<>(); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // 🔴 问题1:手动拼接SQL(容易SQL注入!) String sql = "SELECT * FROM users WHERE 1=1"; List params = new ArrayList<>(); if (keyword != null) { sql += " AND (name LIKE ? OR email LIKE ?)"; params.add("%" + keyword + "%"); params.add("%" + keyword + "%"); } if (status != null) { sql += " AND status = ?"; params.add(status); } sql += " ORDER BY create_time DESC"; // 🔴 问题2:繁琐的数据库操作 conn = dataSource.getConnection(); stmt = conn.prepareStatement(sql); for (int i = 0; i < params.size(); i++) { stmt.setObject(i + 1, params.get(i)); } rs = stmt.executeQuery(); // 🔴 问题3:重复的结果集映射 List> users = new ArrayList<>(); while (rs.next()) { Map user = new HashMap<>(); user.put("id", rs.getLong("id")); user.put("name", rs.getString("name")); user.put("email", rs.getString("email")); // ... 每个实体都要重复写这些 users.add(user); } // 🔴 问题4:手动拼装JSON响应 result.put("success", true); result.put("data", users); result.put("total", users.size()); } catch (Exception e) { result.put("success", false); result.put("error", e.getMessage()); } finally { // 🔴 问题5:容易忘记的资源释放 try { if (rs != null) rs.close(); } catch (Exception e) {} try { if (stmt != null) stmt.close(); } catch (Exception e) {} try { if (conn != null) conn.close(); } catch (Exception e) {} } // 🔴 问题6:还要处理JSON序列化 return new Gson().toJson(result); } } ``` #### ✅ Crivia写法(6行代码,专注业务) ```java @RestController public class UserController { private final CMD cmd = EcologyDB.db(); // 一次配置 @GetMapping("/api/users") public String getUsers(@RequestParam String keyword, @RequestParam String status) { // ✅ 解决方案1:类型安全的查询,自动防SQL注入 List users = SQL.list(cmd, User.class, SQL.cd.like("name", "%" + keyword + "%"), SQL.cd.equals("status", status), "create_time DESC"); // ✅ 解决方案2:自动JSON序列化,处理循环引用等细节 return JSONSwitcher.toJSON2(ApiResponse.success(users), 2); } } ``` **实际收益:** - ✅ **少写29行重复代码** - ✅ **消除SQL注入风险** - ✅ **自动资源管理** - ✅ **统一的JSON格式** --- ### 场景2:银行账单OCR处理 - 复杂业务逻辑 #### ❌ 传统写法(多层嵌套,容易出错) ```java public class BankBillService { public void processOcrResult(String ocrJson) throws Exception { // 🔴 问题1:手动解析复杂JSON结构 JSONObject root = new JSONObject(ocrJson); JSONObject item = root.getJSONObject("item"); JSONObject taskResult = item.getJSONObject("task_result"); JSONArray bodies = taskResult.getJSONArray("body"); Connection conn = dataSource.getConnection(); PreparedStatement stmt = null; try { // 🔴 问题2:容易晕的多层嵌套遍历 for (int i = 0; i < bodies.length(); i++) { JSONObject body = bodies.getJSONObject(i); JSONArray extractResults = body.getJSONArray("extract_result"); for (int j = 0; j < extractResults.length(); j++) { JSONObject extract = extractResults.getJSONObject(j); JSONArray tableFields = extract.getJSONArray("table_fields"); // 🔴 问题3:繁琐的表格数据提取 for (int k = 0; k < tableFields.length(); k++) { JSONArray row = tableFields.getJSONArray(k); // 🔴 问题4:重复的SQL拼接 String sql = "INSERT INTO bank_trades (id, acc_number, amount, trade_date) VALUES (?, ?, ?, ?)"; stmt = conn.prepareStatement(sql); // 🔴 问题5:容易出错的字段映射 stmt.setString(1, UUID.randomUUID().toString()); stmt.setString(2, findFieldValue(row, "卡号")); stmt.setString(3, findFieldValue(row, "交易金额")); stmt.setString(4, findFieldValue(row, "交易日期")); stmt.executeUpdate(); stmt.close(); } } } } finally { if (stmt != null) stmt.close(); if (conn != null) conn.close(); } } // 🔴 问题6:还要写一堆工具方法 private String findFieldValue(JSONArray row, String fieldName) { for (int i = 0; i < row.length(); i++) { JSONObject field = row.getJSONObject(i); if (fieldName.equals(field.getString("field"))) { return field.getString("text"); } } return null; } } ``` #### ✅ Crivia写法(业务逻辑清晰可见) ```java public class BankBillService { private final CMD cmd = EcologyDB.db(); public void processOcrResult(String ocrJson) throws Exception { // ✅ 解决方案1:复杂JSON一键映射为Java对象 Rj77 ocrResult = JSONSwitcher.castByOrgJson(ocrJson, Rj77.class); // ✅ 解决方案2:清晰的业务逻辑提取 List records = ocrResult.records(); // ✅ 解决方案3:简洁的数据入库 for (BankTradeRecord record : records) { SQL.insert(record.setId(RK.rk()), cmd, false); } } } // 清晰的业务实体定义(IDE可自动生成) public class Rj77 { public Item item = new Item(); public List records() { List records = new ArrayList<>(); // 🎯 现在你可以专注业务逻辑,而不是技术细节 for (var body : item.task_result.body) { for (var table : body.extract_result.get(0).table_fields) { for (var row : table) { BankTradeRecord record = new BankTradeRecord(); // 业务字段映射... records.add(record); } } } return records; } } ``` **实际收益:** - ✅ **代码可读性大幅提升** - ✅ **业务逻辑与技术细节分离** - ✅ **减少80%的JSON解析代码** - ✅ **统一的数据访问方式** --- ### 场景3:数据导出报表 - 经常要做的功能 #### ❌ 传统写法(每个报表都要重写一遍) ```java public class ReportService { public String exportUserReport() { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { String sql = "SELECT u.*, d.name as dept_name FROM users u " + "LEFT JOIN departments d ON u.dept_id = d.id " + "WHERE u.status = 'ACTIVE'"; conn = dataSource.getConnection(); stmt = conn.prepareStatement(sql); rs = stmt.executeQuery(); // 🔴 问题:重复的结果集映射 List> result = new ArrayList<>(); while (rs.next()) { Map row = new HashMap<>(); row.put("id", rs.getLong("id")); row.put("name", rs.getString("name")); row.put("email", rs.getString("email")); row.put("deptName", rs.getString("dept_name")); // ... 每个报表都要写这些映射代码 result.add(row); } Map report = new HashMap<>(); report.put("users", result); report.put("exportTime", new Date()); report.put("total", result.size()); return new Gson().toJson(report); } catch (Exception e) { return "{\"error\": \"" + e.getMessage() + "\"}"; } finally { // 🔴 问题:容易漏掉的资源释放 try { if (rs != null) rs.close(); } catch (Exception e) {} try { if (stmt != null) stmt.close(); } catch (Exception e) {} try { if (conn != null) conn.close(); } catch (Exception e) {} } } } ``` #### ✅ Crivia写法(专注数据,而非技术) ```java public class ReportService { private final CMD cmd = EcologyDB.db(); public String exportUserReport() { // ✅ 解决方案1:复杂SQL直接执行 String sql = "SELECT u.*, d.name as dept_name FROM users u " + "LEFT JOIN departments d ON u.dept_id = d.id " + "WHERE u.status = 'ACTIVE'"; // ✅ 解决方案2:自动结果处理,无需手动映射 DataSet data = SQL.q2.query(sql, cmd); // ✅ 解决方案3:智能JSON序列化 Map report = new HashMap<>(); report.put("users", data); // DataSet直接序列化 report.put("exportTime", new Date()); // 自动日期格式化 report.put("total", data.size()); // 自动统计 return JSONSwitcher.toJSON2(report, 2); // 自动处理循环引用等 } } ``` **实际收益:** - ✅ **报表开发速度提升3倍** - ✅ **统一的响应格式** - ✅ **自动处理技术细节** - ✅ **更少的bug** --- ## 🚀 如何开始使用? ### 第一步:定义实体(一次配置) ```java public class User implements Carry { private String id; private String name; private String email; // IDE可以自动生成这个方法 public void keyLinks(List keyLinks) { keyLinks.add(ValueField.c2d("id")); keyLinks.add(ValueField.c2d("name")); keyLinks.add(ValueField.c2d("email")); } // getters/setters... } ``` ### 第二步:写业务代码(告别重复) ```java @RestController public class UserApi { private final CMD cmd = EcologyDB.db(); // 查询:自动防SQL注入 @GetMapping("/api/users") public String findUsers(String name, String department) { List users = SQL.list(cmd, User.class, SQL.cd.like("name", "%" + name + "%"), SQL.cd.equals("department", department)); return JSONSwitcher.toJSON2(users, 2); } // 新增:自动主键生成 @PostMapping("/api/users") public String createUser(@RequestBody User user) { SQL.insert(user.setId(UUID.randomUUID().toString()), cmd, false); return "{\"success\": true}"; } // 关联查询:解决N+1问题 public String getUsersWithDepartments() { List users = SQL.list(cmd, User.class); SQL.orm_Carry(users, "department", cmd); // 自动批量加载 return JSONSwitcher.toJSON2(users, 2); } } ``` ### 第三步:与现有项目共存 ```java @Configuration public class ProjectConfig { // 原有代码完全不用改 @Bean public DataSource dataSource() { // 原有的数据源配置 } // 新增Crivia支持 @Bean public CMD criviaCmd(DataSource dataSource) { return new SpringCMD(dataSource); } } @Service public class HybridService { @Autowired private UserRepository userRepo; // 老代码 @Autowired private CMD cmd; // 新代码 public void business() { // 根据场景选择合适的技术 if (需要复杂业务逻辑) { // 用Crivia简化开发 List users = SQL.list(cmd, User.class, conditions); } else { // 用原有的方式 List users = userRepo.findByComplexCondition(...); } } } ``` --- ## 💡 使用建议:从简单开始 ### 🟢 推荐先用在这些地方: ```java // 1. 数据迁移脚本(没压力) public class DataMigration { public static void main(String[] args) { List oldList = SQL.list(cmd, OldData.class); // 迁移逻辑... } } // 2. 管理后台报表(影响小) @RestController public class ReportController { @GetMapping("/admin/report") public String generateReport() { DataSet data = SQL.q2.query(REPORT_SQL, cmd); return JSONSwitcher.toJSON2(data, 2); } } // 3. 第三方接口对接(JSON处理优势) public class ThirdPartyService { public void processApiResponse(String json) { ApiResponse response = JSONSwitcher.castByOrgJson(json, ApiResponse.class); // 业务处理... } } ``` ### 🟡 这些场景要谨慎: - 超高并发核心业务(先做性能测试) - 已有成熟ORM的重度使用项目(迁移成本高) - 需要特定数据库高级特性的场景 --- ## 📊 总结:Crivia给你带来的改变 | 方面 | 之前 | 之后 | 收益 | |------|------|------|------| | **代码量** | 100+行/功能 | 10-行/功能 | ⏱️ 节省80%时间 | | **SQL注入** | 需要时刻警惕 | 自动防护 | 🛡️ 更安全 | | **JSON处理** | 手动解析/拼接 | 自动序列化 | 🎯 更专注业务 | | **资源管理** | 容易忘记释放 | 自动管理 | 🔧 更少bug | | **关联查询** | N+1或复杂JOIN | 自动优化 | 🚀 更好性能 | ## 🎯 最后的选择 **如果你:** - ✅ 厌倦了每天写重复的CRUD代码 - ✅ 受够了手动处理JSON解析 - ✅ 想要更清晰的业务逻辑代码 - ✅ 愿意花1小时学习来节省100小时编码 **那么Crivia值得你一试。** **开始用Crivia,把时间花在解决问题上,而不是写重复代码上!** > 从一个小工具脚本开始体验,感受开发效率的提升