Files
java/Project/assetmanager/docs/code-design.md
2026-05-26 20:47:59 +08:00

32 KiB
Raw Permalink Blame History

资产管理系统 — 整体代码设计思路


一、分层设计思路

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

// 字段id, username, password, realName, role, status, createTime, updateTime
// 角色role取值 "admin" / "user"
// 状态status取值 1(启用) / 0(禁用)
// 构造:注册用构造(不含id/time)、查询用全参构造

Asset.java

// 字段id, assetCode, assetName, categoryId, status, value, purchaseDate, location, description, createTime, updateTime
// 状态status取值 "available" / "borrowed" / "disposed"
// 关联categoryId关联Category界面展示时需关联查询分类名称

Category.java

// 字段id, categoryCode, categoryName, description, createTime, updateTime
// 用途:资产分类,如"办公设备"、"电子设备"、"家具"等

Borrow.java

// 字段id, assetId, userId, borrowDate, expectedReturnDate, actualReturnDate, reason, status, approverId, approveTime, approveRemark, createTime, updateTime
// 状态流转pending → approved / rejectedapproved → returned / overdue

Disposal.java

// 字段id, assetId, userId, reason, status, approverId, approveTime, approveRemark, disposalDate, createTime, updateTime
// 状态流转pending → approved / rejected

2.2 DAO类dao

BaseDAO.java — 通用CRUD模板

// 设计思路抽取所有DAO共用的增删改查操作为模板方法
//
// 核心方法:
//   int update(String sql, Object... params)           — 通用增删改
//   <T> T queryOne(String sql, RowMapper<T> mapper, Object... params) — 查询单条
//   <T> List<T> queryList(String sql, RowMapper<T> mapper, Object... params) — 查询列表
//   long count(String sql, Object... params)           — 统计数量
//
// RowMapper接口将ResultSet行映射为实体对象函数式接口
//   @FunctionalInterface
//   interface RowMapper<T> { T mapRow(ResultSet rs) throws SQLException; }
//
// 资源管理所有方法内部保证Connection/PreparedStatement/ResultSet正确关闭
// 事务支持提供getConnection()供Service层手动管理事务

UserDAO.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<User> findAll()                          — 查询所有用户
//   long countByUsername(String username)          — 用户名唯一性校验

AssetDAO.java

// 继承BaseDAO实现资产特有查询
//
// 核心方法:
//   int insert(Asset asset)                       — 新增资产
//   int update(Asset asset)                       — 修改资产
//   int deleteById(int id)                        — 删除资产
//   Asset findById(int id)                        — 按ID查询
//   Asset findByAssetCode(String assetCode)       — 按编号查询(唯一性校验)
//   List<Asset> findAll()                         — 查询所有
//   List<Asset> findByCondition(String name, Integer categoryId, String status, String location)
//                                                 — 多条件组合查询
//   int updateStatus(int id, String status)       — 更新资产状态
//   long countByCategoryId(int categoryId)         — 统计分类下资产数量(删除前检查)

CategoryDAO.java

// 继承BaseDAO实现分类特有查询
//
// 核心方法:
//   int insert(Category category)                 — 新增分类
//   int update(Category category)                 — 修改分类
//   int deleteById(int id)                        — 删除分类
//   Category findById(int id)                     — 按ID查询
//   List<Category> findAll()                      — 查询所有
//   long countByCategoryCode(String code)         — 编号唯一性校验

BorrowDAO.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<Borrow> findByUserId(int userId)         — 按借用人查询
//   List<Borrow> findByAssetId(int assetId)       — 按资产查询
//   List<Borrow> findByStatus(String status)      — 按状态查询
//   List<Borrow> findAll()                        — 查询所有
//   List<Borrow> findOverdue()                    — 查询逾期未还

DisposalDAO.java

// 继承BaseDAO实现报废特有查询
//
// 核心方法:
//   int insert(Disposal disposal)                 — 新增报废记录
//   int updateStatus(int id, String status, Integer approverId, String remark)
//                                                 — 更新报废状态(审批)
//   Disposal findById(int id)                     — 按ID查询
//   List<Disposal> findByUserId(int userId)      — 按申请人查询
//   List<Disposal> findByAssetId(int assetId)     — 按资产查询
//   List<Disposal> findByStatus(String status)   — 按状态查询
//   List<Disposal> findAll()                      — 查询所有

2.3 Service类service

UserService.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<User> getAllUsers()
//     → 调用DAO查询所有用户
//
//   void updateUserRole(int userId, String role)
//     → 校验角色值合法性admin/user
//     → 调用DAO更新角色
//
//   void updateUserStatus(int userId, int status)
//     → 校验状态值合法性0/1
//     → 调用DAO更新状态

AssetService.java

// 资产业务逻辑
//
// 核心方法:
//   void addAsset(Asset asset)
//     → 校验必填项(编号、名称、分类、价值、购入日期)
//     → 校验资产编号唯一性
//     → 校验价值为正数
//     → 校验购入日期不晚于今天
//     → 调用DAO插入
//
//   void updateAsset(Asset asset)
//     → 校验必填项
//     → 调用DAO更新
//
//   void deleteAsset(int assetId)
//     → 检查资产状态,已被借用的不可删除
//     → 调用DAO删除
//
//   Asset getAssetById(int id)
//     → 调用DAO查询
//
//   List<Asset> getAllAssets()
//     → 调用DAO查询所有
//
//   List<Asset> searchAssets(String name, Integer categoryId, String status, String location)
//     → 调用DAO多条件组合查询
//     → 任意条件可为空null表示不筛选
//
//   void updateAssetStatus(int assetId, String status)
//     → 校验状态值合法性
//     → 调用DAO更新状态

CategoryService.java

// 分类业务逻辑
//
// 核心方法:
//   void addCategory(Category category)
//     → 校验分类名称非空、编号非空
//     → 校验分类编号唯一性
//     → 调用DAO插入
//
//   void updateCategory(Category category)
//     → 校验必填项
//     → 调用DAO更新
//
//   void deleteCategory(int categoryId)
//     → 检查该分类下是否有资产(引用完整性)
//     → 有资产则抛出BusinessException禁止删除
//     → 无资产则调用DAO删除
//
//   List<Category> getAllCategories()
//     → 调用DAO查询所有
//
//   Category getCategoryById(int id)
//     → 调用DAO查询

BorrowService.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<Borrow> getMyBorrows(int userId)
//     → 查询当前用户的借用记录
//
//   List<Borrow> getPendingBorrows()
//     → 查询待审批借用记录
//
//   List<Borrow> getAllBorrows()
//     → 查询所有借用记录
//
//   void checkOverdue()
//     → 批量检查逾期approved状态+预计归还日期<今天 → 更新为overdue

DisposalService.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<Disposal> getMyDisposals(int userId)
//     → 查询当前用户的报废申请
//
//   List<Disposal> getPendingDisposals()
//     → 查询待审批报废记录
//
//   List<Disposal> getAllDisposals()
//     → 查询所有报废记录

StatService.java

// 统计业务逻辑
//
// 核心方法:
//   Map<String, Integer> getCategoryStat()
//     → 按分类统计资产数量,返回{分类名: 数量}
//     → 用于饼图展示
//
//   Map<String, Integer> getStatusStat()
//     → 按状态统计资产数量,返回{状态名: 数量}
//     → 用于柱状图展示
//
//   List<Map<String, Object>> getBorrowFrequency(int topN)
//     → 统计借用次数TOP N的资产
//     → 返回[{资产名, 借用次数}, ...]
//
//   Map<String, Double> getValueStat()
//     → 按分类统计资产价值汇总
//     → 返回{分类名: 总价值}
//
//   int getTotalAssetCount()
//     → 资产总数
//
//   double getTotalAssetValue()
//     → 资产总价值
//
//   int getBorrowingCount()
//     → 当前借出数量
//
//   int getOverdueCount()
//     → 逾期未还数量

2.4 界面类view

LoginFrame.java

// 登录窗口 — 程序启动入口界面
// 布局:居中显示,用户名/密码输入框 + 登录按钮 + 注册链接
// 事件:
//   登录按钮 → 调用UserService.login()
//     成功 → 隐藏LoginFrame显示MainFrame传入User对象
//     失败 → 弹出错误提示
//   注册链接 → 打开RegisterDialog
// 窗口setSize(400, 300),居中,关闭时退出程序

RegisterDialog.java

// 注册对话框 — JDialog模态窗口
// 表单:用户名、密码、确认密码、真实姓名 + 注册/取消按钮
// 校验:
//   用户名3-20位 → 即时校验
//   密码6-20位 → 即时校验
//   两次密码一致 → 提交时校验
//   真实姓名非空 → 提交时校验
// 提交 → 调用UserService.register()

MainFrame.java

// 主窗口 — 功能导航容器
// 布局BorderLayout
//   北部:顶部信息栏(欢迎语 + 当前用户 + 角色 + 修改密码按钮 + 退出按钮)
//   西部左侧导航菜单JList或JButton组
//     菜单项:资产管理、分类管理、借用管理、报废管理、数据统计
//     管理员额外可见:用户管理
//   中部右侧内容区CardLayout切换各功能面板
// 切换逻辑:
//   点击左侧菜单项 → CardLayout.show(对应Panel)
//   切换面板时自动刷新数据

panel/AssetPanel.java

// 资产管理面板
// 布局:
//   顶部:搜索栏(名称输入 + 分类下拉 + 状态下拉 + 位置输入 + 搜索按钮 + 重置按钮)
//   中部JTable资产列表编号/名称/分类/状态/价值/购入日期/位置)
//   底部:操作按钮(新增/编辑/删除/详情)
//   右下:分页控件(可选)
// 事件:
//   搜索 → 调用AssetService.searchAssets() → 刷新表格
//   新增 → 打开AssetDialog(mode=ADD)
//   编辑 → 选中行 → 打开AssetDialog(mode=EDIT, asset)
//   删除 → 选中行 → 确认对话框 → AssetService.deleteAsset()
//   详情 → 选中行 → 打开AssetDialog(mode=VIEW, asset)

panel/CategoryPanel.java

// 分类管理面板
// 布局:
//   中部JTable分类列表编号/名称/描述/资产数量/创建时间)
//   底部:操作按钮(新增/编辑/删除)
// 事件:
//   新增 → 打开CategoryDialog(mode=ADD)
//   编辑 → 选中行 → 打开CategoryDialog(mode=EDIT, category)
//   删除 → 选中行 → 确认对话框 → CategoryService.deleteCategory()
//     → 捕获BusinessException提示"该分类下有资产,禁止删除"

panel/BorrowPanel.java

// 借用管理面板
// 布局:
//   顶部Tab切换我的借用 / 待审批 / 全部记录)—— 根据角色显示不同Tab
//   中部JTable借用列表
//   底部:操作按钮(借用申请 / 审批 / 归还)
// 事件:
//   借用申请 → 打开BorrowDialog
//   审批 → 选中待审批行 → 打开ApproveDialog(type=borrow)
//   归还 → 选中已审批行 → 确认归还 → BorrowService.returnAsset()

panel/DisposalPanel.java

// 报废管理面板
// 布局:
//   顶部Tab切换我的申请 / 待审批 / 全部记录)
//   中部JTable报废列表
//   底部:操作按钮(报废申请 / 审批)
// 事件:
//   报废申请 → 打开DisposalDialog
//   审批 → 选中待审批行 → 打开ApproveDialog(type=disposal)

panel/StatPanel.java

// 数据统计面板
// 布局:
//   顶部Tab切换分类统计 / 状态统计 / 借用排行 / 价值汇总)
//   中部JFreeChart图表区域
//   底部:汇总数据标签(资产总数/总价值/借出数/逾期数)
// 图表:
//   分类统计 → PieDataset + ChartFactory.createPieChart()
//   状态统计 → DefaultCategoryDataset + ChartFactory.createBarChart()
//   借用排行 → DefaultCategoryDataset + 横向柱状图
//   价值汇总 → DefaultCategoryDataset + 柱状图

panel/UserPanel.java

// 用户管理面板(仅管理员可见)
// 布局:
//   中部JTable用户列表用户名/姓名/角色/状态/创建时间)
//   底部:操作按钮(修改角色 / 启用禁用)
// 事件:
//   修改角色 → 下拉选择admin/user → UserService.updateUserRole()
//   启用禁用 → 确认对话框 → UserService.updateUserStatus()

2.5 工具类util

DBUtil.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

// MD5加密工具
//
// 核心方法:
//   static String encrypt(String input) — 返回32位小写MD5摘要
//
// 实现java.security.MessageDigest("MD5") + Hex转换

ValidatorUtil.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

// 日期工具类
//
// 核心方法:
//   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

// 业务异常继承RuntimeException
// 字段errorCode错误码、message错误描述
// 用途Service层抛出View层捕获并展示给用户
// 示例throw new BusinessException("资产编号已存在")

DBException.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连接管理

// 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防注入

// 所有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 事务管理

// 需要事务的操作:借用申请、借用审批、借用归还、报废审批
// 这些操作涉及多表更新,需保证原子性
//
// 事务管理模式:手动事务控制
//   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通用操作封装

// 通用更新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 <T> List<T> queryList(String sql, RowMapper<T> 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 注释规范

/**
 * 资产业务逻辑类
 * 提供资产的增删改查、状态管理、数据校验等业务功能
 *
 * @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 创新拓展

拓展点 说明
审批流程 借用/报废均需管理员审批,非简单状态切换
逾期自动检测 系统自动检测逾期借用记录
多维度统计 分类/状态/借用/价值四维度可视化
角色权限 管理员/普通用户功能差异化
组合查询 资产支持多条件组合筛选
数据关联完整性 删除分类检查资产引用、删除资产检查借用状态