基于Firebase引用的多数据查询:关联Patient与Appointment类需求
嘿,我来帮你搞定这个需求!你需要查询指定日期的所有预约记录,并且把每条预约对应的患者信息也关联上对吧?先看一下我整理后的实现方案:
实现方案:查询指定日期预约并关联患者信息
首先我们需要确保实体类有完整的访问方法(getter/setter),因为Java私有字段不能直接访问,然后通过服务类实现关联查询逻辑。
1. 完善实体类
Patient.java
public class Patient { private String name; private String phone; private String patientId; // 遵循Java驼峰命名规范,如果你坚持用patient_id也可以,记得统一命名 public Patient() { } public Patient(String name, String phone, String patientId) { this.name = name; this.phone = phone; this.patientId = patientId; } // 必须的Getter/Setter方法,用于访问私有字段 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getPatientId() { return patientId; } public void setPatientId(String patientId) { this.patientId = patientId; } }
Appointment.java
我帮你补全了必要的字段和方法,保留了你提到的@Exclude注解:
import java.time.LocalDate; public class Appointment { private String appointmentId; private String patientId; private LocalDate appointmentDate; private String department; @Exclude // 保留你原代码中的注解,假设是序列化时排除字段用的 public static final String SOME_STATIC_FIELD = "example"; // 补全未完成的静态字段定义 public Appointment() { } public Appointment(String appointmentId, String patientId, LocalDate appointmentDate, String department) { this.appointmentId = appointmentId; this.patientId = patientId; this.appointmentDate = appointmentDate; this.department = department; } // 必须的Getter/Setter方法 public String getAppointmentId() { return appointmentId; } public void setAppointmentId(String appointmentId) { this.appointmentId = appointmentId; } public String getPatientId() { return patientId; } public void setPatientId(String patientId) { this.patientId = patientId; } public LocalDate getAppointmentDate() { return appointmentDate; } public void setAppointmentDate(LocalDate appointmentDate) { this.appointmentDate = appointmentDate; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } }
2. 实现关联查询服务
创建一个AppointmentService类,里面包含核心的查询逻辑,我用内存列表模拟数据库数据,实际项目中你可以直接替换成数据库操作:
import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class AppointmentService { // 模拟数据库存储的患者和预约数据 private List<Patient> patientList = new ArrayList<>(); private List<Appointment> appointmentList = new ArrayList<>(); // 初始化模拟测试数据(实际项目中不需要这段) public void initSampleData() { patientList.add(new Patient("张三", "13800138000", "P001")); patientList.add(new Patient("李四", "13900139000", "P002")); patientList.add(new Patient("王五", "13700137000", "P003")); appointmentList.add(new Appointment("A001", "P001", LocalDate.of(2024, 5, 20), "内科")); appointmentList.add(new Appointment("A002", "P002", LocalDate.of(2024, 5, 20), "外科")); appointmentList.add(new Appointment("A003", "P001", LocalDate.of(2024, 5, 21), "眼科")); } // 核心方法:查询指定日期的预约并关联患者信息 public List<AppointmentWithPatient> getAppointmentsWithPatientByDate(LocalDate targetDate) { // 第一步:筛选出指定日期的所有预约记录 List<Appointment> dateFilteredAppointments = appointmentList.stream() .filter(appt -> targetDate.equals(appt.getAppointmentDate())) .collect(Collectors.toList()); // 第二步:为每个预约匹配对应的患者数据 return dateFilteredAppointments.stream() .map(appt -> { // 根据patientId查找患者,找不到时返回null(可根据业务需求改为抛出异常) Patient matchedPatient = patientList.stream() .filter(patient -> patient.getPatientId().equals(appt.getPatientId())) .findFirst() .orElse(null); return new AppointmentWithPatient(appt, matchedPatient); }) .collect(Collectors.toList()); } // DTO类:封装预约+患者的关联数据,避免修改原实体类,符合单一职责原则 public static class AppointmentWithPatient { private Appointment appointment; private Patient patient; public AppointmentWithPatient(Appointment appointment, Patient patient) { this.appointment = appointment; this.patient = patient; } // Getter方法,方便外部获取数据 public Appointment getAppointment() { return appointment; } public Patient getPatient() { return patient; } // 可选:重写toString方法,方便打印查看结果 @Override public String toString() { return String.format("预约ID: %s, 科室: %s, 患者姓名: %s, 患者电话: %s", appointment.getAppointmentId(), appointment.getDepartment(), patient != null ? patient.getName() : "未知患者", patient != null ? patient.getPhone() : "无联系方式"); } } // 测试用主方法,验证功能是否正常 public static void main(String[] args) { AppointmentService service = new AppointmentService(); service.initSampleData(); // 查询2024年5月20日的预约数据 List<AppointmentWithPatient> result = service.getAppointmentsWithPatientByDate(LocalDate.of(2024, 5, 20)); // 打印查询结果 System.out.println("=== 2024-05-20的预约及患者信息 ==="); result.forEach(System.out::println); } }
3. 关键说明
- 实体类的Getter/Setter:这是必须的,Java私有成员变量只能通过公共访问方法读取和修改;
- DTO类的作用:用
AppointmentWithPatient封装关联后的结果,不需要修改原有的Patient和Appointment类,代码更易维护; - Stream API的使用:用Stream来筛选和关联数据,代码简洁易读,也可以用普通for循环实现,效果一致;
- 实际项目适配:如果用JPA/MyBatis操作数据库,可以直接通过关联查询(比如JPA的
@ManyToOne注解)获取关联患者数据,不需要手动遍历匹配。
内容的提问来源于stack exchange,提问作者Karim Alaa
相关产品推荐
相关产品推荐

