java: DDD using oracle 21c
项目结构:
domain
--entities
----school.java
--repositories
----school.java
infrastructure
--database
-----duoraclehelper.java
--model
----school.java
--repositories
----school.java
application
--server
-----school.java
presentation
--controllers
----school.java
--views
----school.java
main.java
domain:
/** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 17:51 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : domain.entities/School.java * explain : 学习 类 **/ package domain.entities; import java.util.Objects; /** * */ public class School { private String schoolId; private String schoolName; private String schoolTelNo; public School(String schoolId, String schoolName, String schoolTelNo) { this.schoolId = schoolId; this.schoolName = schoolName; this.schoolTelNo = schoolTelNo; } // Getters and Setters public String getSchoolId() { return schoolId; } public String getSchoolName() { return schoolName; } public String getSchoolTelNo() { return schoolTelNo; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public void setSchoolTelNo(String schoolTelNo) { this.schoolTelNo = schoolTelNo; } // 领域行为 public void updateContactInfo(String newName, String newTelNo) { if (newName != null && !newName.isEmpty()) { this.schoolName = newName; } if (newTelNo != null && !newTelNo.isEmpty()) { this.schoolTelNo = newTelNo; } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; School school = (School) o; return schoolId.equals(school.schoolId); } @Override public int hashCode() { return Objects.hash(schoolId); } } /** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 18:47 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : domain.entities/QueryParams.java * explain : 学习 类 **/ package domain.entities; /** * */ public class QueryParams { private String searchTerm; // 搜索关键词 private int pageNumber; // 当前页码 private int pageSize; // 每页大小 /** * * @param searchTerm * @param pageNumber * @param pageSize */ public QueryParams(String searchTerm, int pageNumber, int pageSize) { this.searchTerm = searchTerm; this.pageNumber = pageNumber; this.pageSize = pageSize; } // Getters public String getSearchTerm() { return searchTerm; } public int getPageNumber() { return pageNumber; } public int getPageSize() { return pageSize; } public int getOffset() { return (pageNumber - 1) * pageSize; } } /** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 17:53 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : domain/repositories/SchoolRepository.java * explain : 学习 类 **/ package domain.repositories; import domain.entities.School; import domain.entities.QueryParams; import java.util.List; /** * */ public interface SchoolRepository { List<School> findAll(int page, int pageSize); // 新增支持查询条件的方法 List<School> findByParams(QueryParams params); int countByParams(QueryParams params); int countAll(); School findById(String schoolId); void save(School school); void delete(String schoolId); }
infrastructure:
/** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 18:03 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : SchoolRepositoryImpl.java * explain : 学习 类 **/ package infrastructure.repositories; import domain.entities.School; import domain.entities.QueryParams; import domain.repositories.SchoolRepository; import infrastructure.database.DuOracleHelper; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class SchoolRepositoryImpl implements SchoolRepository { @Override public List<School> findAll(int page, int pageSize) { System.out.println("开始分页查询,页码: " + page + ",每页大小: " + pageSize); List<School> schools = new ArrayList<>(); String sql = "SELECT * FROM School ORDER BY SchoolId " + "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; try (Connection conn = DuOracleHelper.getConnection()) { System.out.println("成功获取数据库连接"); try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setInt(1, (page - 1) * pageSize); pstmt.setInt(2, pageSize); System.out.println("执行SQL: " + sql); System.out.println("参数1: " + (page - 1) * pageSize); System.out.println("参数2: " + pageSize); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { schools.add(mapToDomain(rs)); } System.out.println("查询成功,返回 " + schools.size() + " 条记录"); } } } catch (SQLException | IOException e) { System.err.println("数据库操作异常: " + e.getMessage()); e.printStackTrace(); // 打印完整堆栈信息 throw new RuntimeException("查询学校列表失败", e); } return schools; } @Override public int countAll() { String sql = "SELECT COUNT(*) FROM School"; try (Connection conn = DuOracleHelper.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { if (rs.next()) { return rs.getInt(1); } } catch (SQLException | IOException e) { throw new RuntimeException("统计学校数量失败", e); } return 0; } @Override public List<School> findByParams(QueryParams params) { List<School> schools = new ArrayList<>(); StringBuilder sql = new StringBuilder( "SELECT * FROM School WHERE 1=1 " ); // 构建查询条件 if (params.getSearchTerm() != null && !params.getSearchTerm().isEmpty()) { sql.append("AND (SchoolId LIKE ? OR SchoolName LIKE ?) "); } // 添加排序和分页 sql.append("ORDER BY SchoolId OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"); try (Connection conn = DuOracleHelper.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql.toString())) { int paramIndex = 1; // 设置查询参数 if (params.getSearchTerm() != null && !params.getSearchTerm().isEmpty()) { String searchTerm = "%" + params.getSearchTerm() + "%"; pstmt.setString(paramIndex++, searchTerm); pstmt.setString(paramIndex++, searchTerm); } // 设置分页参数 pstmt.setInt(paramIndex++, params.getOffset()); pstmt.setInt(paramIndex, params.getPageSize()); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { schools.add(mapToDomain(rs)); } } } catch (SQLException | IOException e) { throw new RuntimeException("按条件查询学校失败", e); } return schools; } @Override public int countByParams(QueryParams params) { StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM School WHERE 1=1 "); // 构建查询条件 if (params.getSearchTerm() != null && !params.getSearchTerm().isEmpty()) { sql.append("AND (SchoolId LIKE ? OR SchoolName LIKE ?)"); } try (Connection conn = DuOracleHelper.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql.toString())) { int paramIndex = 1; // 设置查询参数 if (params.getSearchTerm() != null && !params.getSearchTerm().isEmpty()) { String searchTerm = "%" + params.getSearchTerm() + "%"; pstmt.setString(paramIndex++, searchTerm); pstmt.setString(paramIndex, searchTerm); } try (ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { return rs.getInt(1); } } } catch (SQLException | IOException e) { throw new RuntimeException("统计符合条件的学校数量失败", e); } return 0; } // 其他方法实现... @Override public School findById(String schoolId) { String sql = "SELECT * FROM School WHERE SchoolId = ?"; try (Connection conn = DuOracleHelper.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, schoolId); try (ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { return mapToDomain(rs); } } } catch (SQLException | IOException e) { throw new RuntimeException("查找学校失败", e); } return null; } @Override public void save(School school) { // 检查是插入还是更新 if (findById(school.getSchoolId()) == null) { insertSchool(school); } else { updateSchool(school); } } private void insertSchool(School school) { String sql = "INSERT INTO School (SchoolId, SchoolName, SchoolTelNo) VALUES (?, ?, ?)"; try (Connection conn = DuOracleHelper.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, school.getSchoolId()); pstmt.setString(2, school.getSchoolName()); pstmt.setString(3, school.getSchoolTelNo()); pstmt.executeUpdate(); } catch (SQLException | IOException e) { throw new RuntimeException("添加学校失败", e); } } private void updateSchool(School school) { String sql = "UPDATE School SET SchoolName = ?, SchoolTelNo = ? WHERE SchoolId = ?"; try (Connection conn = DuOracleHelper.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, school.getSchoolName()); pstmt.setString(2, school.getSchoolTelNo()); pstmt.setString(3, school.getSchoolId()); pstmt.executeUpdate(); } catch (SQLException | IOException e) { throw new RuntimeException("更新学校失败", e); } } @Override public void delete(String schoolId) { String sql = "DELETE FROM School WHERE SchoolId = ?"; try (Connection conn = DuOracleHelper.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, schoolId); pstmt.executeUpdate(); } catch (SQLException | IOException e) { throw new RuntimeException("删除学校失败", e); } } private School mapToDomain(ResultSet rs) throws SQLException { return new School( rs.getString("SchoolId"), rs.getString("SchoolName"), rs.getString("SchoolTelNo") ); } } /** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 18:02 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : SchoolDto.java * explain : 学习 类 **/ package infrastructure.model; /** * */ public class SchoolDto { private String schoolId; private String schoolName; private String schoolTelNo; // Getters and Setters public String getSchoolId() { return schoolId; } public void setSchoolId(String schoolId) { this.schoolId = schoolId; } public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public String getSchoolTelNo() { return schoolTelNo; } public void setSchoolTelNo(String schoolTelNo) { this.schoolTelNo = schoolTelNo; } }
application:
/** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 18:08 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : application/server/SchoolService.java * explain : 学习 类 **/ package application.server; import domain.entities.QueryParams; import domain.entities.School; import domain.repositories.SchoolRepository; import infrastructure.repositories.SchoolRepositoryImpl; import java.util.List; public class SchoolService { private final SchoolRepository repository; public SchoolService() { this.repository = new SchoolRepositoryImpl(); } // 分页查询 public PagedResult<School> getSchoolsByPage(int page, int pageSize) { List<School> schools = repository.findAll(page, pageSize); int totalCount = repository.countAll(); return new PagedResult<>( schools, page, pageSize, (int) Math.ceil((double) totalCount / pageSize), totalCount ); } /** * 新增支持搜索的分页查询方法 * @param searchTerm * @param page * @param pageSize * @return */ public PagedResult<School> getSchoolsByPageAndSearch(String searchTerm, int page, int pageSize) { QueryParams params = new QueryParams(searchTerm, page, pageSize); List<School> schools = repository.findByParams(params); int totalCount = repository.countByParams(params); return new PagedResult<>( schools, page, pageSize, (int) Math.ceil((double) totalCount / pageSize), totalCount ); } // 其他业务方法... public void saveSchool(School school) { if (school.getSchoolId() == null || school.getSchoolId().isEmpty()) { // 生成新ID的逻辑 String newId = generateSchoolId(); school = new School(newId, school.getSchoolName(), school.getSchoolTelNo()); } repository.save(school); } public void updateSchool(School school) { repository.save(school); // 假设save方法可以处理更新 } public void deleteSchool(String schoolId) { repository.delete(schoolId); } public int getTotalSchoolCount() { return repository.countAll(); } // 生成学校ID的辅助方法 private String generateSchoolId() { // 简单实现,实际应用中可能需要更复杂的ID生成策略 return "S" + System.currentTimeMillis(); } public int getTotalSchoolCount(String searchTerm) { QueryParams params = new QueryParams(searchTerm, 1, 10); return repository.countByParams(params); } // 分页结果类 public static class PagedResult<T> { private final List<T> items; private final int currentPage; private final int pageSize; private final int totalPages; private final int totalItems; public PagedResult(List<T> items, int currentPage, int pageSize, int totalPages, int totalItems) { this.items = items; this.currentPage = currentPage; this.pageSize = pageSize; this.totalPages = totalPages; this.totalItems = totalItems; } // Getters public List<T> getItems() { return items; } public int getCurrentPage() { return currentPage; } public int getPageSize() { return pageSize; } public int getTotalPages() { return totalPages; } public int getTotalItems() { return totalItems; } public boolean hasNextPage() { return currentPage < totalPages; } public boolean hasPreviousPage() { return currentPage > 1; } } }
presentation:
/** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 18:10 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : SchoolController.java * explain : 学习 类 **/ package presentation.controllers; import application.server.SchoolService; import application.server.SchoolService.PagedResult; import domain.entities.School; import presentation.views.SchoolView; public class SchoolController { private final SchoolService service; private final SchoolView view; /** * * @param view */ public SchoolController(SchoolView view) { this.service = new SchoolService(); this.view = view; } /** * * @param searchTerm * @param page * @param pageSize */ public void loadSchools(String searchTerm, int page, int pageSize) { PagedResult<School> result = service.getSchoolsByPageAndSearch(searchTerm, page, pageSize); view.displaySchools(result); } /** * * @param school */ public void addSchool(School school) { service.saveSchool(school); // 重新加载数据,保持当前搜索条件和分页 loadSchools(view.getCurrentSearchTerm(), 1, view.getPageSize()); } /** * * @param school */ public void updateSchool(School school) { service.updateSchool(school); // 重新加载当前页 loadSchools(view.getCurrentSearchTerm(), view.getCurrentPage(), view.getPageSize()); } /** * * @param schoolId */ public void deleteSchool(String schoolId) { // 获取当前分页信息 String searchTerm = view.getCurrentSearchTerm(); int currentPage = view.getCurrentPage(); int pageSize = view.getPageSize(); // 执行删除 service.deleteSchool(schoolId); // 获取删除后的总记录数 int totalRecords = service.getTotalSchoolCount(searchTerm); // 计算删除后应该显示的页码 int totalPages = Math.max(1, (int) Math.ceil((double) totalRecords / pageSize)); int newPage = Math.min(currentPage, totalPages); // 加载正确的页 loadSchools(searchTerm, newPage, pageSize); } /* public void deleteSchool(String schoolId) { // 获取当前分页信息 String searchTerm = view.getCurrentSearchTerm(); int currentPage = view.getCurrentPage(); int pageSize = view.getPageSize(); // 执行删除 service.deleteSchool(schoolId); // 获取删除后的总记录数 int totalRecords = service.getTotalSchoolCount(searchTerm); // 计算删除后应该显示的页码 int totalPages = Math.max(1, (int) Math.ceil((double) totalRecords / pageSize)); int newPage = Math.min(currentPage, totalPages); // 加载正确的页 loadSchools(searchTerm, newPage, pageSize); }*/ } /** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 18:12 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : SchoolView.java * explain : 学习 类 **/ package presentation.views; import application.server.SchoolService.PagedResult; import domain.entities.School; import presentation.controllers.SchoolController; import javax.swing.*; import javax.swing.table.AbstractTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import javax.swing.GroupLayout.Alignment; import javax.swing.LayoutStyle.ComponentPlacement; public class SchoolView extends JFrame { private final SchoolController controller; private JTable schoolTable; private SchoolTableModel tableModel; private JButton firstPageBtn, prevPageBtn, nextPageBtn, lastPageBtn; private JButton addButton,editButton,deleteButton,refreshButton; private JLabel pageInfoLabel; private int currentPage = 1; private int pageSize = 10; private String currentSearchTerm = null; // 新增:当前搜索关键词 private JTextField searchField; // 新增:搜索输入框 public SchoolView() { this.controller = new SchoolController(this); initComponents(); loadInitialData(); // 添加按钮事件 addButton.addActionListener(e -> showAddSchoolDialog()); editButton.addActionListener(e -> showEditSchoolDialog()); deleteButton.addActionListener(e -> performDeleteSchool()); } private void initComponents() { setTitle("学校管理系统"); setSize(800, 600); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 创建工具栏和按钮 JToolBar toolBar = new JToolBar(); refreshButton = new JButton("刷新"); addButton = new JButton("添加"); editButton = new JButton("编辑"); deleteButton = new JButton("删除"); toolBar.add(refreshButton); toolBar.add(addButton); toolBar.add(editButton); toolBar.add(deleteButton); // 创建搜索面板 JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); JLabel searchLabel = new JLabel("搜索:"); searchField = new JTextField(20); JButton searchButton = new JButton("搜索"); searchButton.addActionListener(e -> performSearch()); searchPanel.add(searchLabel); searchPanel.add(searchField); searchPanel.add(searchButton); // 初始化表格 tableModel = new SchoolTableModel(); schoolTable = new JTable(tableModel); JScrollPane scrollPane = new JScrollPane(schoolTable); // 添加按钮事件 refreshButton.addActionListener(e -> loadInitialData()); addButton.addActionListener(e -> showAddSchoolDialog()); editButton.addActionListener(e -> showEditSchoolDialog()); deleteButton.addActionListener(e -> performDeleteSchool()); // 初始化分页控件 initPaginationControls(); // 布局 setLayout(new BorderLayout()); add(toolBar, BorderLayout.NORTH); add(searchPanel, BorderLayout.SOUTH); add(scrollPane, BorderLayout.CENTER); add(createPaginationPanel(), BorderLayout.SOUTH); } /** * 添加 */ private void showAddSchoolDialog() { JDialog dialog = new JDialog(this, "添加学校", true); dialog.setSize(400, 300); dialog.setLocationRelativeTo(this); // 创建表单组件 JLabel idLabel = new JLabel("学校ID:"); JTextField idField = new JTextField(20); JLabel nameLabel = new JLabel("学校名称:"); JTextField nameField = new JTextField(20); JLabel telLabel = new JLabel("联系电话:"); JTextField telField = new JTextField(20); JButton saveButton = new JButton("保存"); JButton cancelButton = new JButton("取消"); // 设置布局 GroupLayout layout = new GroupLayout(dialog.getContentPane()); dialog.getContentPane().setLayout(layout); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); layout.setHorizontalGroup( layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(idLabel) .addComponent(nameLabel) .addComponent(telLabel)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(idField) .addComponent(nameField) .addComponent(telField))) .addGroup(Alignment.TRAILING, layout.createSequentialGroup() .addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(cancelButton) .addPreferredGap(ComponentPlacement.RELATED) .addComponent(saveButton)) ); layout.setVerticalGroup( layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(idLabel) .addComponent(idField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(nameLabel) .addComponent(nameField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(telLabel) .addComponent(telField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED, 40, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(saveButton) .addComponent(cancelButton))) ); // 添加按钮事件 saveButton.addActionListener(e -> { String id = idField.getText().trim(); String name = nameField.getText().trim(); String tel = telField.getText().trim(); if (id.isEmpty() || name.isEmpty()) { JOptionPane.showMessageDialog(dialog, "学校ID和学校名称不能为空", "输入错误", JOptionPane.ERROR_MESSAGE); return; } controller.addSchool(new School(id, name, tel)); dialog.dispose(); }); cancelButton.addActionListener(e -> dialog.dispose()); dialog.setVisible(true); } /** * 修改 */ private void showEditSchoolDialog() { int selectedRow = schoolTable.getSelectedRow(); if (selectedRow == -1) { JOptionPane.showMessageDialog(this, "请先选择要修改的学校", "提示", JOptionPane.INFORMATION_MESSAGE); return; } // 获取选中的学校数据 String schoolId = (String) schoolTable.getValueAt(selectedRow, 0); String schoolName = (String) schoolTable.getValueAt(selectedRow, 1); String schoolTel = (String) schoolTable.getValueAt(selectedRow, 2); JDialog dialog = new JDialog(this, "修改学校", true); dialog.setSize(400, 300); dialog.setLocationRelativeTo(this); // 创建表单组件 JLabel idLabel = new JLabel("学校ID:"); JTextField idField = new JTextField(schoolId, 20); idField.setEditable(false); // ID不可编辑 JLabel nameLabel = new JLabel("学校名称:"); JTextField nameField = new JTextField(schoolName, 20); JLabel telLabel = new JLabel("联系电话:"); JTextField telField = new JTextField(schoolTel, 20); JButton saveButton = new JButton("保存"); JButton cancelButton = new JButton("取消"); // 设置布局(与添加对话框类似) GroupLayout layout = new GroupLayout(dialog.getContentPane()); dialog.getContentPane().setLayout(layout); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); layout.setHorizontalGroup( layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(idLabel) .addComponent(nameLabel) .addComponent(telLabel)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(idField) .addComponent(nameField) .addComponent(telField))) .addGroup(Alignment.TRAILING, layout.createSequentialGroup() .addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(cancelButton) .addPreferredGap(ComponentPlacement.RELATED) .addComponent(saveButton)) ); layout.setVerticalGroup( layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(idLabel) .addComponent(idField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(nameLabel) .addComponent(nameField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(telLabel) .addComponent(telField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(ComponentPlacement.RELATED, 40, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(saveButton) .addComponent(cancelButton))) ); // 添加按钮事件 saveButton.addActionListener(e -> { String id = idField.getText().trim(); String name = nameField.getText().trim(); String tel = telField.getText().trim(); if (name.isEmpty()) { JOptionPane.showMessageDialog(dialog, "学校名称不能为空", "输入错误", JOptionPane.ERROR_MESSAGE); return; } controller.updateSchool(new School(id, name, tel)); dialog.dispose(); }); cancelButton.addActionListener(e -> dialog.dispose()); dialog.setVisible(true); } /** * 删除 */ private void performDeleteSchool() { int selectedRow = schoolTable.getSelectedRow(); if (selectedRow == -1) { JOptionPane.showMessageDialog(this, "请先选择要删除的学校", "提示", JOptionPane.INFORMATION_MESSAGE); return; } // 获取选中的学校ID String schoolId = (String) schoolTable.getValueAt(selectedRow, 0); String schoolName = (String) schoolTable.getValueAt(selectedRow, 1); // 确认对话框 int confirm = JOptionPane.showConfirmDialog( this, "确定要删除学校 [" + schoolName + "] 吗?", "确认删除", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE ); if (confirm == JOptionPane.YES_OPTION) { controller.deleteSchool(schoolId); } } private void loadInitialData() { controller.loadSchools(currentSearchTerm, currentPage, pageSize); } private void performSearch() { currentSearchTerm = searchField.getText(); currentPage = 1; // 搜索时重置到第一页 controller.loadSchools(currentSearchTerm, currentPage, pageSize); } private void initPaginationControls() { firstPageBtn = new JButton("首页"); prevPageBtn = new JButton("上一页"); nextPageBtn = new JButton("下一页"); lastPageBtn = new JButton("末页"); pageInfoLabel = new JLabel("第 1 页,共 0 页"); firstPageBtn.addActionListener(e -> goToFirstPage()); prevPageBtn.addActionListener(e -> goToPreviousPage()); nextPageBtn.addActionListener(e -> goToNextPage()); lastPageBtn.addActionListener(e -> goToLastPage()); } private JPanel createPaginationPanel() { JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER)); panel.add(firstPageBtn); panel.add(prevPageBtn); panel.add(pageInfoLabel); panel.add(nextPageBtn); panel.add(lastPageBtn); return panel; } public void displaySchools(PagedResult<School> result) { tableModel.setSchools(result.getItems()); tableModel.fireTableDataChanged(); currentPage = result.getCurrentPage(); updatePageInfo(result); } private void updatePageInfo(PagedResult<School> result) { pageInfoLabel.setText(String.format("第 %d 页,共 %d 页,总计 %d 条记录", result.getCurrentPage(), result.getTotalPages(), result.getTotalItems())); // 启用/禁用按钮 firstPageBtn.setEnabled(result.hasPreviousPage()); prevPageBtn.setEnabled(result.hasPreviousPage()); nextPageBtn.setEnabled(result.hasNextPage()); lastPageBtn.setEnabled(result.hasNextPage()); } // 获取总页数的辅助方法 private int getTotalPages() { String text = pageInfoLabel.getText(); try { // 从"第 X 页,共 Y 页,总计 Z 条记录"中提取Y String[] parts = text.split(","); if (parts.length >= 2) { String totalPagesPart = parts[1].trim(); // 提取"共 Y 页"中的Y String totalPagesStr = totalPagesPart.substring( totalPagesPart.indexOf("共") + 1, totalPagesPart.indexOf("页") ).trim(); // 去除可能的空格 // 增加调试输出 System.out.println("提取的总页数字符串: '" + totalPagesStr + "'"); return Integer.parseInt(totalPagesStr); } } catch (Exception e) { System.err.println("解析总页数失败: " + e.getMessage()); e.printStackTrace(); } return 1; // 默认返回1页 } // 添加获取当前搜索词的方法 public String getCurrentSearchTerm() { return currentSearchTerm; } // 修复导航方法,传递搜索参数 private void goToPreviousPage() { if (currentPage > 1) { controller.loadSchools(currentSearchTerm, currentPage - 1, pageSize); } } // 其他导航方法也需要类似修改 private void goToNextPage() { if (currentPage < getTotalPages()) { controller.loadSchools(currentSearchTerm, currentPage + 1, pageSize); } } private void goToFirstPage() { controller.loadSchools(currentSearchTerm, 1, pageSize); } private void goToLastPage() { int totalPages = getTotalPages(); if (totalPages > 0) { controller.loadSchools(currentSearchTerm, totalPages, pageSize); } } // Getters for pagination state public int getCurrentPage() { return currentPage; } public int getPageSize() { return pageSize; } // 表格模型 private static class SchoolTableModel extends AbstractTableModel { private List<School> schools = new ArrayList<>(); private final String[] columnNames = {"学校ID", "学校名称", "联系电话"}; public void setSchools(List<School> schools) { this.schools = schools; } @Override public int getRowCount() { return schools.size(); } @Override public int getColumnCount() { return columnNames.length; } @Override public String getColumnName(int column) { return columnNames[column]; } @Override public Object getValueAt(int rowIndex, int columnIndex) { School school = schools.get(rowIndex); switch (columnIndex) { case 0: return school.getSchoolId(); case 1: return school.getSchoolName(); case 2: return school.getSchoolTelNo(); default: return null; } } } }
调用:
/** * encoding: utf-8 * 版权所有 2025 ©涂聚文有限公司 ® * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 * 描述: * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2025 - 2025/7/13 - 17:51 * User : geovindu * Product : IntelliJ IDEA * Project : oracleDDDDemo * File : main.java * explain : 学习 类 **/ import presentation.views.SchoolView; public class Main { public static void main(String[] args) { // 使用SwingUtilites确保在事件调度线程上创建和操作GUI javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { SchoolView view = new SchoolView(); view.setVisible(true); } }); System.out.println("Hello, Geovin Du!"); } }
输出:
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)