1
\$\begingroup\$

I have a Java program which simulates a hospital. For this, I have two different databases, MySql and MS SQL, with tables to manage the patients. The user can decide which database he wants to use.

For each database type, I created a PatientRepository which implements my PatientRepository interface, both of which work with a JDBC template.

Because some of the syntax differs between these databases (for example, SELECT TOP 1 * FROM tbl_patient ORDER BY NEWID() vs. SELECT * FROM tbl_patient ORDER BY RAND() LIMIT 1) I wrote two implementations of PatientRepository. But I see there is a lot of redundant code, which I like to avoid.

PatientRepository implementations:

public class PatientRepositoryMSSqlImpl implements PatientRepository {

private JdbcTemplate template;
private PatientGenerator patientGenerator;


public PatientRepositoryMSSqlImpl(DataSource dataSource, PatientGenerator patientGenerator) {
    this.patientGenerator = patientGenerator;
    this.template = new JdbcTemplate(dataSource);
}


public void insertPatient(Patient patient) {
    template.update("INSERT INTO tbl_patient(lastname, firstname, gender, birthday) VALUES(?,?,?,?)",
            patient.getLastname(), patient.getFirstname(), patient.getGender(), patient.getBirthday().toString());
}

public void insertListOfPatients(List<Patient> allPatients) {
    for (Patient patient : allPatients) {
        insertPatient(patient);
    }
}

public Patient getRandomPatient() {
    String sql = "SELECT TOP 1 * FROM tbl_patient ORDER BY NEWID()";
    Patient patient = (Patient) template.queryForObject(sql, new PatientRowMapper());
    return patient;
}

public Patient admitRandomPatient() {
    Patient patient = getRandomPatient();
    patient.setDepartment(patientGenerator.getRandomDepartment());
    patient.setWard(patientGenerator.getRandomWard());
    patient.setAdmissionDateTime(LocalDateTime.now());
    patient.setStatus("I");
    template.update(
            "INSERT INTO tbl_inpatients(id, ward, department, admissionDate, patientStatus) VALUES(?,?,?,?,?)",
            patient.getId(), patient.getWard(), patient.getDepartment(), patient.getAdmissionDateTime().toString(),
            patient.getStatus());
    return patient;
}

public Patient getRandomInpatient() {
    String sql = "SELECT TOP 1 * FROM tbl_inpatients ip, tbl_patient p WHERE p.id = ip.id ORDER BY NEWID()";
    Patient patient = (Patient) template.queryForObject(sql, new Object[] {}, new InPatientRowMapper());
    setPatientBasicData(patient);
    return patient;
}

public Patient setPatientBasicData(Patient patient) {
    String sql = "SELECT * FROM tbl_patient WHERE id = '" + patient.getId() + "'";
    Patient patientNew = (Patient) template.queryForObject(sql, new Object[] {}, new PatientRowMapper());
    patient.setLastname(patientNew.getLastname());
    patient.setFirstname(patientNew.getFirstname());
    patient.setGender(patientNew.getGender());
    patient.setBirthday(patientNew.getBirthday());
    return patient;
}

public Patient transferRandomPatient() {
    Patient patient = getRandomInpatient();
    patient.setPriorWard(patient.getWard());
    patient.setPriorDepartment(patient.getPriorDepartment());
    patient.setDepartment(patientGenerator.getRandomDepartment());
    patient.setWard(patientGenerator.getRandomWard());
    template.update("UPDATE tbl_inpatients SET ward = ?, department = ? WHERE id = ?", patient.getWard(),
            patient.getDepartment(), patient.getId());
    return patient;
}

public Patient dischargeRandomPatient() {
    Patient patient = getRandomInpatient();
    patient.setDischargeDateTime(LocalDateTime.now());
    insertFormerPatient(patient);
    template.update("DELETE FROM tbl_inpatients WHERE instance= ?", patient.getInstance());
    return patient;
}

public void insertFormerPatient(Patient patient) {
    template.update(
            "INSERT INTO tbl_formerpatients(instance, id, ward, department, admissionDate, dischargeDate) VALUES('"
                    + patient.getInstance() + "', '" + patient.getId() + "', '" + patient.getWard() + "', '"
                    + patient.getDepartment() + "', '" + patient.getAdmissionDateTime().toString() + "', '"
                    + patient.getDischargeDateTime().toString() + "')");
}

public int countPatients() {
    String sql = "SELECT COUNT(id) AS numberOfPatients FROM tbl_patient";
    return template.queryForObject(sql, Integer.class);
}

public int countInpatients() {
    String sql = "SELECT COUNT(id) AS numberOfPatients FROM tbl_inpatients";
    return template.queryForObject(sql, Integer.class);
}

public LocalDate parseBirthday(String birthday) {
    LocalDate localDate = LocalDate.parse(birthday);
    return localDate;
}

}

public class PatientRepositoryMySqlImpl implements PatientRepository {


    private JdbcTemplate template;
    private PatientGenerator patientGenerator;


    public PatientRepositoryMySqlImpl(DataSource dataSource, PatientGenerator patientGenerator) {
        this.patientGenerator = patientGenerator;
        this.template = new JdbcTemplate(dataSource);
    }


    public void insertPatient(Patient patient) {
        template.update("INSERT INTO tbl_patient(lastname, firstname, gender, birthday) VALUES(?,?,?,?)",
                patient.getLastname(), patient.getFirstname(), patient.getGender(), patient.getBirthday().toString());
    }

    public void insertListOfPatients(List<Patient> allPatients) {
        for (Patient patient : allPatients) {
            insertPatient(patient);
        }
    }

    public Patient getRandomPatient() {
        String sql = "SELECT * FROM tbl_patient ORDER BY RAND() LIMIT 1";
        Patient patient = (Patient) template.queryForObject(sql, new PatientRowMapper());
        return patient;
    }

    public Patient admitRandomPatient() {
        Patient patient = getRandomPatient();
        patient.setDepartment(patientGenerator.getRandomDepartment());
        patient.setWard(patientGenerator.getRandomWard());
        patient.setAdmissionDateTime(LocalDateTime.now());
        patient.setStatus("I");
        template.update(
                "INSERT INTO tbl_inpatients(id, ward, department, admissionDate, patientStatus) VALUES(?,?,?,?,?)",
                patient.getId(), patient.getWard(), patient.getDepartment(), patient.getAdmissionDateTime().toString(),
                patient.getStatus());
        return patient;
    }

    public Patient getRandomInpatient() {
        String sql = "SELECT * FROM tbl_inpatients ORDER BY RAND() LIMIT 1";
        Patient patient = (Patient) template.queryForObject(sql, new Object[] {}, new InPatientRowMapper());
        setPatientBasicData(patient);
        return patient;
    }

    public Patient setPatientBasicData(Patient patient) {
        String sql = "SELECT * FROM tbl_patient WHERE id = '" + patient.getId() + "'";
        Patient patientNew = (Patient) template.queryForObject(sql, new Object[] {}, new PatientRowMapper());
        patient.setLastname(patientNew.getLastname());
        patient.setFirstname(patientNew.getFirstname());
        patient.setGender(patientNew.getGender());
        patient.setBirthday(patientNew.getBirthday());
        return patient;
    }

    public Patient transferRandomPatient() {
        Patient patient = getRandomInpatient();
        patient.setPriorWard(patient.getWard());
        patient.setPriorDepartment(patient.getPriorDepartment());
        patient.setDepartment(patientGenerator.getRandomDepartment());
        patient.setWard(patientGenerator.getRandomWard());
        template.update("UPDATE tbl_inpatients SET ward = ?, department = ? WHERE id = ?", patient.getWard(),
                patient.getDepartment(), patient.getId());
        return patient;
    }

    public Patient dischargeRandomPatient() {
        Patient patient = getRandomInpatient();
        patient.setDischargeDateTime(LocalDateTime.now());
        insertFormerPatient(patient);
        template.update("DELETE FROM tbl_inpatients WHERE `instance`= ?", patient.getInstance());
        return patient;
    }

    public void insertFormerPatient(Patient patient) {
        template.update(
                "INSERT INTO tbl_formerpatients(`instance`, `id`, ward, department, admissionDate, dischargeDate) VALUES('"
                        + patient.getInstance() + "', '" + patient.getId() + "', '" + patient.getWard() + "', '"
                        + patient.getDepartment() + "', '" + patient.getAdmissionDateTime().toString() + "', '"
                        + patient.getDischargeDateTime().toString() + "')");
    }

    public int countPatients() {
        String sql = "SELECT COUNT(*) FROM tbl_patient";
        return template.queryForObject(sql, Integer.class);
    }

    public int countInpatients() {
        String sql = "SELECT COUNT(*) FROM tbl_inpatients";
        return template.queryForObject(sql, Integer.class);
    }

    public LocalDate parseBirthday(String birthday) {
        LocalDate localDate = LocalDate.parse(birthday);
        return localDate;

    }

    }
\$\endgroup\$
2
  • 2
    \$\begingroup\$ That's where single responsibility principle come to play. imagine a set of classes that only do one thing : e.g. : db classes only read and write from db and nothing else \$\endgroup\$
    – nafas
    Jan 10 '18 at 9:08
  • \$\begingroup\$ If you want something lihter than an ORM (JPA, Hibernate, etc.), you should have a look at JOOQ - jooq.org \$\endgroup\$
    – Boschi
    Jan 10 '18 at 9:09
1
\$\begingroup\$

You could use an abstract class that contained your shared implementation code, and use the derived classes to implement those methods that change depending on implementation

 public abstract class AbstractPatientRepository
 {
      public void insertListOfPatients(List<Patient> allPatients) {
          for (Patient patient : allPatients) {
              insertPatient(patient);
      }

      public abstract Patient getRandomPatient();
 }

 public class PatientRepositoryMSSqlImpl extends AbstractPatientRepository
 {


     public Patient getRandomPatient() {
         String sql = "SELECT TOP 1 * FROM tbl_patient ORDER BY NEWID()";
         Patient patient = (Patient) template.queryForObject(sql, new          PatientRowMapper());
         return patient;
     }

 }
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.