# 资产管理系统 — 整体代码设计思路 --- ## 一、分层设计思路 ### 1.1 四层职责划分 | 层次 | 包路径 | 职责 | 核心原则 | |------|--------|------|---------| | 表示层 | `view/` | 用户交互、数据展示、事件响应 | 只做展示与交互,不包含业务逻辑 | | 业务逻辑层 | `service/` | 业务规则校验、流程控制、事务协调 | 不含SQL,不包含UI逻辑 | | 数据访问层 | `dao/` | 数据库CRUD操作、SQL封装 | 只做数据存取,不含业务判断 | | 实体层 | `entity/` | 数据载体,与表结构对应 | 纯POJO,无业务逻辑 | ### 1.2 层间调用规则 ``` view ──调用──▶ service ──调用──▶ dao ──操作──▶ MySQL │ │ │ │ ├── util ├── util/DBUtil │ ├── entity ├── entity │ └── exception └── exception │ ├── util/ValidatorUtil(表单即时校验) └── entity(界面数据绑定) ``` **严格规则:** - view 只能调用 service,**禁止直接调用 dao** - service 只调用 dao 和 util,**禁止包含 Swing 组件引用** - dao 只操作数据库,**禁止包含业务判断逻辑** - entity 被所有层共享,**禁止依赖其他任何层** ### 1.3 数据流转示例(资产录入) ``` 用户填写表单 → AssetDialog收集输入 → 构造Asset对象 → ValidatorUtil校验字段 → AssetService.addAsset(asset) → 校验资产编号唯一性 → AssetDAO.insert(asset) → DBUtil获取连接 → PreparedStatement执行SQL → 释放资源 → 返回操作结果 → 界面刷新表格 + 提示成功/失败 ``` --- ## 二、核心类设计 ### 2.1 实体类(entity) **设计原则:** 一个实体对应一张表,属性名=字段名(驼峰转换),提供全参构造+getter/setter+toString。 #### User.java ```java // 字段:id, username, password, realName, role, status, createTime, updateTime // 角色:role取值 "admin" / "user" // 状态:status取值 1(启用) / 0(禁用) // 构造:注册用构造(不含id/time)、查询用全参构造 ``` #### Asset.java ```java // 字段:id, assetCode, assetName, categoryId, status, value, purchaseDate, location, description, createTime, updateTime // 状态:status取值 "available" / "borrowed" / "disposed" // 关联:categoryId关联Category,界面展示时需关联查询分类名称 ``` #### Category.java ```java // 字段:id, categoryCode, categoryName, description, createTime, updateTime // 用途:资产分类,如"办公设备"、"电子设备"、"家具"等 ``` #### Borrow.java ```java // 字段:id, assetId, userId, borrowDate, expectedReturnDate, actualReturnDate, reason, status, approverId, approveTime, approveRemark, createTime, updateTime // 状态流转:pending → approved / rejected,approved → returned / overdue ``` #### Disposal.java ```java // 字段:id, assetId, userId, reason, status, approverId, approveTime, approveRemark, disposalDate, createTime, updateTime // 状态流转:pending → approved / rejected ``` ### 2.2 DAO类(dao) #### BaseDAO.java — 通用CRUD模板 ```java // 设计思路:抽取所有DAO共用的增删改查操作为模板方法 // // 核心方法: // int update(String sql, Object... params) — 通用增删改 // T queryOne(String sql, RowMapper mapper, Object... params) — 查询单条 // List queryList(String sql, RowMapper mapper, Object... params) — 查询列表 // long count(String sql, Object... params) — 统计数量 // // RowMapper接口:将ResultSet行映射为实体对象(函数式接口) // @FunctionalInterface // interface RowMapper { T mapRow(ResultSet rs) throws SQLException; } // // 资源管理:所有方法内部保证Connection/PreparedStatement/ResultSet正确关闭 // 事务支持:提供getConnection()供Service层手动管理事务 ``` #### UserDAO.java ```java // 继承BaseDAO,实现用户特有查询 // // 核心方法: // User findByUsername(String username) — 按用户名查询(登录验证) // User findById(int id) — 按ID查询(关联查询用) // int insert(User user) — 新增用户 // int updatePassword(int id, String newPassword) — 修改密码 // int updateRole(int id, String role) — 修改角色 // int updateStatus(int id, int status) — 修改状态 // List findAll() — 查询所有用户 // long countByUsername(String username) — 用户名唯一性校验 ``` #### AssetDAO.java ```java // 继承BaseDAO,实现资产特有查询 // // 核心方法: // int insert(Asset asset) — 新增资产 // int update(Asset asset) — 修改资产 // int deleteById(int id) — 删除资产 // Asset findById(int id) — 按ID查询 // Asset findByAssetCode(String assetCode) — 按编号查询(唯一性校验) // List findAll() — 查询所有 // List findByCondition(String name, Integer categoryId, String status, String location) // — 多条件组合查询 // int updateStatus(int id, String status) — 更新资产状态 // long countByCategoryId(int categoryId) — 统计分类下资产数量(删除前检查) ``` #### CategoryDAO.java ```java // 继承BaseDAO,实现分类特有查询 // // 核心方法: // int insert(Category category) — 新增分类 // int update(Category category) — 修改分类 // int deleteById(int id) — 删除分类 // Category findById(int id) — 按ID查询 // List findAll() — 查询所有 // long countByCategoryCode(String code) — 编号唯一性校验 ``` #### BorrowDAO.java ```java // 继承BaseDAO,实现借用特有查询 // // 核心方法: // int insert(Borrow borrow) — 新增借用记录 // int updateStatus(int id, String status, Integer approverId, String remark) // — 更新借用状态(审批) // int updateReturn(int id, LocalDateTime returnDate) — 登记归还 // Borrow findById(int id) — 按ID查询 // List findByUserId(int userId) — 按借用人查询 // List findByAssetId(int assetId) — 按资产查询 // List findByStatus(String status) — 按状态查询 // List findAll() — 查询所有 // List findOverdue() — 查询逾期未还 ``` #### DisposalDAO.java ```java // 继承BaseDAO,实现报废特有查询 // // 核心方法: // int insert(Disposal disposal) — 新增报废记录 // int updateStatus(int id, String status, Integer approverId, String remark) // — 更新报废状态(审批) // Disposal findById(int id) — 按ID查询 // List findByUserId(int userId) — 按申请人查询 // List findByAssetId(int assetId) — 按资产查询 // List findByStatus(String status) — 按状态查询 // List findAll() — 查询所有 ``` ### 2.3 Service类(service) #### UserService.java ```java // 用户业务逻辑 // // 核心方法: // User login(String username, String password) // → 校验用户名非空、密码非空 // → MD5加密密码后与数据库比对 // → 检查账户状态(是否禁用) // → 失败抛出BusinessException // // void register(String username, String password, String realName) // → 校验用户名长度(3-20)、密码长度(6-20)、真实姓名非空 // → 校验用户名唯一性 // → MD5加密密码 // → 调用DAO插入,默认角色user、状态1 // // void changePassword(int userId, String oldPwd, String newPwd) // → 验证旧密码正确性 // → 校验新密码格式 // → MD5加密新密码后更新 // // List getAllUsers() // → 调用DAO查询所有用户 // // void updateUserRole(int userId, String role) // → 校验角色值合法性(admin/user) // → 调用DAO更新角色 // // void updateUserStatus(int userId, int status) // → 校验状态值合法性(0/1) // → 调用DAO更新状态 ``` #### AssetService.java ```java // 资产业务逻辑 // // 核心方法: // void addAsset(Asset asset) // → 校验必填项(编号、名称、分类、价值、购入日期) // → 校验资产编号唯一性 // → 校验价值为正数 // → 校验购入日期不晚于今天 // → 调用DAO插入 // // void updateAsset(Asset asset) // → 校验必填项 // → 调用DAO更新 // // void deleteAsset(int assetId) // → 检查资产状态,已被借用的不可删除 // → 调用DAO删除 // // Asset getAssetById(int id) // → 调用DAO查询 // // List getAllAssets() // → 调用DAO查询所有 // // List searchAssets(String name, Integer categoryId, String status, String location) // → 调用DAO多条件组合查询 // → 任意条件可为空(null表示不筛选) // // void updateAssetStatus(int assetId, String status) // → 校验状态值合法性 // → 调用DAO更新状态 ``` #### CategoryService.java ```java // 分类业务逻辑 // // 核心方法: // void addCategory(Category category) // → 校验分类名称非空、编号非空 // → 校验分类编号唯一性 // → 调用DAO插入 // // void updateCategory(Category category) // → 校验必填项 // → 调用DAO更新 // // void deleteCategory(int categoryId) // → 检查该分类下是否有资产(引用完整性) // → 有资产则抛出BusinessException,禁止删除 // → 无资产则调用DAO删除 // // List getAllCategories() // → 调用DAO查询所有 // // Category getCategoryById(int id) // → 调用DAO查询 ``` #### BorrowService.java ```java // 借用业务逻辑(核心业务,状态流转复杂) // // 核心方法: // void applyBorrow(int assetId, int userId, String reason, LocalDate expectedReturnDate) // → 校验资产状态必须为"available" // → 校验预计归还日期晚于今天 // → 校验借用原因非空 // → 创建Borrow记录(状态pending) // → 更新资产状态为"borrowed"(预占,审批通过后确认) // → 注意:此处需事务保证借用记录与资产状态一致 // // void approveBorrow(int borrowId, int approverId, boolean approved, String remark) // → 校验借用状态必须为"pending" // → 校验操作人为管理员 // → 若同意:状态改为approved,资产状态保持borrowed // → 若拒绝:状态改为rejected,资产状态恢复为available // → 记录审批人、审批时间、审批备注 // → 需事务保证 // // void returnAsset(int borrowId) // → 校验借用状态必须为"approved" // → 更新借用记录:状态改returned,记录实际归还日期 // → 更新资产状态为available // → 需事务保证 // // List getMyBorrows(int userId) // → 查询当前用户的借用记录 // // List getPendingBorrows() // → 查询待审批借用记录 // // List getAllBorrows() // → 查询所有借用记录 // // void checkOverdue() // → 批量检查逾期:approved状态+预计归还日期<今天 → 更新为overdue ``` #### DisposalService.java ```java // 报废业务逻辑 // // 核心方法: // void applyDisposal(int assetId, int userId, String reason) // → 校验资产状态必须为"available" // → 校验报废原因非空 // → 创建Disposal记录(状态pending) // → 需事务保证 // // void approveDisposal(int disposalId, int approverId, boolean approved, String remark) // → 校验报废状态必须为"pending" // → 校验操作人为管理员 // → 若同意:状态改approved,资产状态改为disposed,记录报废日期 // → 若拒绝:状态改rejected,资产状态保持available // → 需事务保证 // // List getMyDisposals(int userId) // → 查询当前用户的报废申请 // // List getPendingDisposals() // → 查询待审批报废记录 // // List getAllDisposals() // → 查询所有报废记录 ``` #### StatService.java ```java // 统计业务逻辑 // // 核心方法: // Map getCategoryStat() // → 按分类统计资产数量,返回{分类名: 数量} // → 用于饼图展示 // // Map getStatusStat() // → 按状态统计资产数量,返回{状态名: 数量} // → 用于柱状图展示 // // List> getBorrowFrequency(int topN) // → 统计借用次数TOP N的资产 // → 返回[{资产名, 借用次数}, ...] // // Map getValueStat() // → 按分类统计资产价值汇总 // → 返回{分类名: 总价值} // // int getTotalAssetCount() // → 资产总数 // // double getTotalAssetValue() // → 资产总价值 // // int getBorrowingCount() // → 当前借出数量 // // int getOverdueCount() // → 逾期未还数量 ``` ### 2.4 界面类(view) #### LoginFrame.java ```java // 登录窗口 — 程序启动入口界面 // 布局:居中显示,用户名/密码输入框 + 登录按钮 + 注册链接 // 事件: // 登录按钮 → 调用UserService.login() // 成功 → 隐藏LoginFrame,显示MainFrame(传入User对象) // 失败 → 弹出错误提示 // 注册链接 → 打开RegisterDialog // 窗口:setSize(400, 300),居中,关闭时退出程序 ``` #### RegisterDialog.java ```java // 注册对话框 — JDialog模态窗口 // 表单:用户名、密码、确认密码、真实姓名 + 注册/取消按钮 // 校验: // 用户名3-20位 → 即时校验 // 密码6-20位 → 即时校验 // 两次密码一致 → 提交时校验 // 真实姓名非空 → 提交时校验 // 提交 → 调用UserService.register() ``` #### MainFrame.java ```java // 主窗口 — 功能导航容器 // 布局:BorderLayout // 北部:顶部信息栏(欢迎语 + 当前用户 + 角色 + 修改密码按钮 + 退出按钮) // 西部:左侧导航菜单(JList或JButton组) // 菜单项:资产管理、分类管理、借用管理、报废管理、数据统计 // 管理员额外可见:用户管理 // 中部:右侧内容区(CardLayout切换各功能面板) // 切换逻辑: // 点击左侧菜单项 → CardLayout.show(对应Panel) // 切换面板时自动刷新数据 ``` #### panel/AssetPanel.java ```java // 资产管理面板 // 布局: // 顶部:搜索栏(名称输入 + 分类下拉 + 状态下拉 + 位置输入 + 搜索按钮 + 重置按钮) // 中部:JTable资产列表(编号/名称/分类/状态/价值/购入日期/位置) // 底部:操作按钮(新增/编辑/删除/详情) // 右下:分页控件(可选) // 事件: // 搜索 → 调用AssetService.searchAssets() → 刷新表格 // 新增 → 打开AssetDialog(mode=ADD) // 编辑 → 选中行 → 打开AssetDialog(mode=EDIT, asset) // 删除 → 选中行 → 确认对话框 → AssetService.deleteAsset() // 详情 → 选中行 → 打开AssetDialog(mode=VIEW, asset) ``` #### panel/CategoryPanel.java ```java // 分类管理面板 // 布局: // 中部:JTable分类列表(编号/名称/描述/资产数量/创建时间) // 底部:操作按钮(新增/编辑/删除) // 事件: // 新增 → 打开CategoryDialog(mode=ADD) // 编辑 → 选中行 → 打开CategoryDialog(mode=EDIT, category) // 删除 → 选中行 → 确认对话框 → CategoryService.deleteCategory() // → 捕获BusinessException提示"该分类下有资产,禁止删除" ``` #### panel/BorrowPanel.java ```java // 借用管理面板 // 布局: // 顶部:Tab切换(我的借用 / 待审批 / 全部记录)—— 根据角色显示不同Tab // 中部:JTable借用列表 // 底部:操作按钮(借用申请 / 审批 / 归还) // 事件: // 借用申请 → 打开BorrowDialog // 审批 → 选中待审批行 → 打开ApproveDialog(type=borrow) // 归还 → 选中已审批行 → 确认归还 → BorrowService.returnAsset() ``` #### panel/DisposalPanel.java ```java // 报废管理面板 // 布局: // 顶部:Tab切换(我的申请 / 待审批 / 全部记录) // 中部:JTable报废列表 // 底部:操作按钮(报废申请 / 审批) // 事件: // 报废申请 → 打开DisposalDialog // 审批 → 选中待审批行 → 打开ApproveDialog(type=disposal) ``` #### panel/StatPanel.java ```java // 数据统计面板 // 布局: // 顶部:Tab切换(分类统计 / 状态统计 / 借用排行 / 价值汇总) // 中部:JFreeChart图表区域 // 底部:汇总数据标签(资产总数/总价值/借出数/逾期数) // 图表: // 分类统计 → PieDataset + ChartFactory.createPieChart() // 状态统计 → DefaultCategoryDataset + ChartFactory.createBarChart() // 借用排行 → DefaultCategoryDataset + 横向柱状图 // 价值汇总 → DefaultCategoryDataset + 柱状图 ``` #### panel/UserPanel.java ```java // 用户管理面板(仅管理员可见) // 布局: // 中部:JTable用户列表(用户名/姓名/角色/状态/创建时间) // 底部:操作按钮(修改角色 / 启用禁用) // 事件: // 修改角色 → 下拉选择admin/user → UserService.updateUserRole() // 启用禁用 → 确认对话框 → UserService.updateUserStatus() ``` ### 2.5 工具类(util) #### DBUtil.java ```java // 数据库连接管理工具 // 设计思路:读取db.properties配置,提供连接获取与释放 // // 核心方法: // static Connection getConnection() — 获取数据库连接 // static void close(Connection conn) — 关闭连接 // static void close(ResultSet rs, PreparedStatement pstmt, Connection conn) // — 释放查询资源(重载) // // 实现要点: // 1. 类加载时读取db.properties,只读一次 // 2. getConnection()每次创建新连接(课程项目无需连接池) // 3. close方法判断null后再关闭,避免NPE // 4. 所有DAO方法通过DBUtil获取连接,finally块中释放 ``` #### MD5Util.java ```java // MD5加密工具 // // 核心方法: // static String encrypt(String input) — 返回32位小写MD5摘要 // // 实现:java.security.MessageDigest("MD5") + Hex转换 ``` #### ValidatorUtil.java ```java // 通用表单校验工具 // // 核心方法: // static boolean isEmpty(String str) — 判空(null或trim后为空) // static boolean isPositive(BigDecimal value) — 判断为正数 // static boolean isLengthInRange(String str, int min, int max) — 长度范围校验 // static boolean isDateAfter(LocalDate date, LocalDate after) — 日期先后校验 // static boolean isAlphanumeric(String str) — 字母数字校验(用户名) // static boolean isNumeric(String str) — 纯数字校验 // // 使用场景: // Service层校验 + View层即时校验 ``` #### DateUtil.java ```java // 日期工具类 // // 核心方法: // static String format(LocalDate date) — LocalDate → "yyyy-MM-dd" // static String format(LocalDateTime dateTime) — LocalDateTime → "yyyy-MM-dd HH:mm:ss" // static LocalDate parseDate(String str) — "yyyy-MM-dd" → LocalDate // static LocalDateTime parseDateTime(String str) — "yyyy-MM-dd HH:mm:ss" → LocalDateTime ``` ### 2.6 异常类(exception) #### BusinessException.java ```java // 业务异常,继承RuntimeException // 字段:errorCode(错误码)、message(错误描述) // 用途:Service层抛出,View层捕获并展示给用户 // 示例:throw new BusinessException("资产编号已存在") ``` #### DBException.java ```java // 数据库异常,继承RuntimeException // 字段:message(错误描述)、cause(原始SQLException) // 用途:DAO层抛出,Service层捕获后包装为BusinessException或直接向上传播 ``` --- ## 三、业务逻辑设计 ### 3.1 登录注册流程 ``` 登录流程: 用户输入 → ValidatorUtil判空 → UserService.login() → UserDAO.findByUsername() → 用户不存在?→ 抛异常"用户名或密码错误" → MD5Util.encrypt(输入密码) → 与数据库密码比对 → 不匹配?→ 抛异常"用户名或密码错误" → status==0?→ 抛异常"账户已被禁用" → 返回User对象 → LoginFrame隐藏 → MainFrame显示 注册流程: 用户输入 → ValidatorUtil校验格式 → 确认密码一致性 → UserService.register() → 用户名唯一性校验 → MD5加密密码 → UserDAO.insert() ``` ### 3.2 资产CRUD流程 ``` 录入:表单填写 → ValidatorUtil校验 → AssetService.addAsset() → 编号唯一性校验 → 价值正数校验 → 日期合理性校验 → AssetDAO.insert() 修改:选中行 → 回填表单 → 修改字段 → AssetService.updateAsset() → 校验必填项 → AssetDAO.update() 删除:选中行 → 确认对话框 → AssetService.deleteAsset() → 检查资产状态(borrowed不可删) → AssetDAO.deleteById() 查询:输入条件 → AssetService.searchAssets() → 任意条件为null则不筛选 → AssetDAO.findByCondition() → 返回结果列表 ``` ### 3.3 借用归还流程 ``` 借用申请: 选择可用资产 → 填写原因+预计归还日期 → BorrowService.applyBorrow() → 校验资产状态为available → 创建Borrow(pending) → 更新资产状态为borrowed → 事务提交 审批(管理员): 选中待审批记录 → 同意/拒绝 → BorrowService.approveBorrow() → 同意:Borrow.status → approved,资产保持borrowed → 拒绝:Borrow.status → rejected,资产恢复available → 事务提交 归还: 选中已审批记录 → 确认归还 → BorrowService.returnAsset() → Borrow.status → returned,记录实际归还日期 → 资产状态恢复available → 事务提交 逾期检查: BorrowService.checkOverdue() → approved + expectedReturnDate < 今天 → overdue ``` ### 3.4 报废流程 ``` 报废申请: 选择可用资产 → 填写报废原因 → DisposalService.applyDisposal() → 校验资产状态为available → 创建Disposal(pending) 审批(管理员): 选中待审批记录 → 同意/拒绝 → DisposalService.approveDisposal() → 同意:Disposal.status → approved,资产状态 → disposed → 拒绝:Disposal.status → rejected,资产状态保持available ``` ### 3.5 统计查询流程 ``` 分类统计:StatService.getCategoryStat() → SELECT c.category_name, COUNT(a.id) FROM t_asset a JOIN t_category c → PieDataset → 饼图 状态统计:StatService.getStatusStat() → SELECT status, COUNT(*) FROM t_asset GROUP BY status → DefaultCategoryDataset → 柱状图 借用排行:StatService.getBorrowFrequency(10) → SELECT a.asset_name, COUNT(b.id) FROM t_borrow b JOIN t_asset a GROUP BY a.id → TOP 10 价值汇总:StatService.getValueStat() → SELECT c.category_name, SUM(a.value) FROM t_asset a JOIN t_category c → 柱状图 ``` ### 3.6 表单校验设计 ``` 校验层级: 1. 即时校验(View层)— 输入时实时反馈 - JTextField.addKeyListener / FocusListener - 用户名长度、密码长度、数值格式等 2. 提交校验(Service层)— 提交时完整性校验 - 必填项非空 - 唯一性(用户名、资产编号) - 业务规则(资产状态、日期合理性) 3. 数据库校验(DAO层)— 数据库约束兜底 - UNIQUE约束 - NOT NULL约束 - 外键约束 校验反馈: - 即时校验:字段旁红色提示文字 - 提交校验:JOptionPane.showMessageDialog警告 - 数据库校验:捕获SQLException转为友好提示 ``` ### 3.7 数据可视化设计 ``` JFreeChart集成: 1. Maven依赖:org.jfreechart/jfreechart 2. 图表创建:ChartFactory + 数据集(PieDataset/CategoryDataset) 3. 图表展示:ChartPanel封装 → 添加到StatPanel 4. 样式定制:标题、颜色、字体、图例 四种图表: - 饼图(PieChart):分类数量占比,颜色区分各类别 - 柱状图(BarChart):状态数量对比,横向展示 - 排行图:借用频率TOP 10,降序横向柱状图 - 价值图:各分类资产价值汇总,柱状图 ``` --- ## 四、数据库交互设计 ### 4.1 JDBC连接管理 ```java // DBUtil核心逻辑 // 1. 静态初始化块加载db.properties static { Properties props = new Properties(); try (InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties")) { props.load(is); url = props.getProperty("db.url"); username = props.getProperty("db.username"); password = props.getProperty("db.password"); Class.forName(props.getProperty("db.driver")); } catch (Exception e) { throw new RuntimeException("数据库配置加载失败", e); } } // 2. 获取连接 public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } // 3. 释放资源 — 判断null后关闭,顺序:ResultSet → PreparedStatement → Connection ``` ### 4.2 PreparedStatement防注入 ```java // 所有SQL操作均使用PreparedStatement,禁止字符串拼接SQL // 示例: String sql = "SELECT * FROM t_user WHERE username = ? AND password = ?"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, username); // 参数化,防SQL注入 pstmt.setString(2, password); ResultSet rs = pstmt.executeQuery(); // ... } ``` ### 4.3 事务管理 ```java // 需要事务的操作:借用申请、借用审批、借用归还、报废审批 // 这些操作涉及多表更新,需保证原子性 // // 事务管理模式:手动事务控制 // Connection conn = null; // try { // conn = DBUtil.getConnection(); // conn.setAutoCommit(false); // 开启事务 // // // 执行多条SQL... // // conn.commit(); // 提交事务 // } catch (Exception e) { // if (conn != null) conn.rollback(); // 回滚事务 // throw new BusinessException("操作失败:" + e.getMessage()); // } finally { // if (conn != null) conn.setAutoCommit(true); // DBUtil.close(conn); // } ``` ### 4.4 BaseDAO通用操作封装 ```java // 通用更新(INSERT/UPDATE/DELETE) public int update(String sql, Object... params) { Connection conn = null; PreparedStatement pstmt = null; try { conn = DBUtil.getConnection(); pstmt = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { pstmt.setObject(i + 1, params[i]); } return pstmt.executeUpdate(); } catch (SQLException e) { throw new DBException("数据库操作失败", e); } finally { DBUtil.close(null, pstmt, conn); } } // 通用查询列表 public List queryList(String sql, RowMapper mapper, Object... params) { // 类似结构,ResultSet遍历 + mapper映射 } ``` --- ## 五、规范要求 ### 5.1 Java命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 类名 | 大驼峰 | AssetService, BorrowDAO | | 方法名 | 小驼峰 | findByUsername, addAsset | | 变量名 | 小驼峰 | assetList, currentUser | | 常量名 | 全大写下划线 | MAX_RETRY_COUNT | | 包名 | 全小写 | com.asset.service | | 数据库表名 | t_前缀+小写下划线 | t_asset, t_borrow | | 数据库字段名 | 小写下划线 | asset_code, create_time | ### 5.2 注释规范 ```java /** * 资产业务逻辑类 * 提供资产的增删改查、状态管理、数据校验等业务功能 * * @author 作者名 * @version 1.0 */ public class AssetService { /** * 新增资产 * 校验资产编号唯一性、必填项、价值正数后调用DAO插入 * * @param asset 资产实体对象 * @throws BusinessException 编号重复、校验不通过时抛出 */ public void addAsset(Asset asset) { // 校验资产编号唯一性 // ... } } ``` ### 5.3 异常处理思路 ``` 异常分层处理策略: DAO层:捕获SQLException → 包装为DBException向上抛出 Service层:捕获DBException → 转为BusinessException(对用户友好) Service层:业务规则不满足 → 直接抛BusinessException View层:捕获BusinessException → JOptionPane展示错误信息 View层:捕获未预期异常 → 记录日志 + 通用错误提示 禁止: - 禁止空catch块吞掉异常 - 禁止catch Exception后不做处理 - 禁止在DAO/Service层直接弹出UI对话框 ``` ### 5.4 AI代码校验优化要求 | 校验维度 | 检查要点 | |----------|---------| | 逻辑正确性 | 业务流程是否完整、边界条件是否处理 | | SQL安全性 | 是否使用PreparedStatement、参数是否正确绑定 | | 资源泄漏 | Connection/Statement/ResultSet是否正确关闭 | | 命名规范 | 是否符合Java命名规范 | | 异常处理 | 是否合理捕获/抛出、异常信息是否明确 | | 代码冗余 | 是否有重复代码可提取到BaseDAO或工具类 | | 业务完整性 | 状态流转是否正确、事务是否保证 | --- ## 六、课程评分匹配设计 ### 6.1 功能完整性(满分保障) | 课程要求 | 本系统实现 | |----------|-----------| | 用户登录注册 | ✅ 登录+注册+修改密码+角色权限 | | 资产数据增删改查 | ✅ 完整CRUD + 多条件组合查询 | | 数据可视化展示 | ✅ 4种JFreeChart图表 | | 表单数据校验 | ✅ 三层校验(即时+提交+数据库) | | 资产管理基础业务 | ✅ 借用/归还/报废全流程 | | 功能量级2-3倍 | ✅ 5张表、8个模块、审批流程、统计功能 | ### 6.2 代码质量 | 维度 | 保障措施 | |------|---------| | 分层清晰 | 严格四层架构,层间调用规则明确 | | 命名规范 | 遵循Java命名规范+阿里巴巴开发手册 | | 注释完整 | 类注释+方法注释+关键逻辑行内注释 | | 异常处理 | 自定义异常+分层处理+友好提示 | | SQL安全 | PreparedStatement+参数化查询 | | 资源管理 | finally块关闭+DBUtil统一释放 | ### 6.3 文档配套 | 文档 | 内容 | |------|------| | 架构设计文档 | 技术架构+功能模块+数据库设计+AI规范+感悟 | | 目录结构文档 | 项目结构+目录功能注释 | | 代码设计思路文档 | 本文档,完整设计思路 | | SQL脚本 | 建库建表+初始数据 | | 代码内注释 | 类/方法/逻辑三层注释 | ### 6.4 创新拓展 | 拓展点 | 说明 | |--------|------| | 审批流程 | 借用/报废均需管理员审批,非简单状态切换 | | 逾期自动检测 | 系统自动检测逾期借用记录 | | 多维度统计 | 分类/状态/借用/价值四维度可视化 | | 角色权限 | 管理员/普通用户功能差异化 | | 组合查询 | 资产支持多条件组合筛选 | | 数据关联完整性 | 删除分类检查资产引用、删除资产检查借用状态 |