Skip to content
© Code by Kevin · Home
All projects

Case study · 03 / 033 min read

Sistema Hemocentro

Blood bank management with trigger-driven inventory

Role
DAO layer and MySQL triggers
Team
Team of 3
Year
2026
Status
Academic project
Stack
Java 17 · Spring Boot · JDBC · MySQL 8 · Maven · DAO

TL;DR

A blood bank system built by a team of 3 at university: inventory per blood type is kept by the database itself through a MySQL trigger, and the donation compatibility rules live in the Java model.

Context and problem

A project for the Object-Oriented Programming with JDBC course at UMC, in 2026. The challenge was to model a blood bank's daily work: registering donors, recording donations, tracking the stock of each blood type and serving patients, while keeping the stock numbers always correct.

The tricky part is consistency: every recorded donation changes the stock. If that math depends on every screen remembering to update the stock, someday one of them forgets, and the number on screen no longer matches the blood that actually exists.

My role

A team of 3. I was responsible for the DAO layer and the MySQL triggers that update the stock, across the Patient, Donor, Donation and Inventory modules.

Constraints

  • Plain JDBC, no ORM: the course was about understanding data access under the hood.
  • Object-oriented design as a grading criterion: models, responsibilities and clearly separated layers.
  • A course deadline and work split between three people.

Technical decisions and trade-offs

DecisionAlternativeWhy
Stock updated by a MySQL triggerUpdate the stock in Java after each donationThe rule lives in one place. Stock stays right even if another part of the system records a donation; EstoqueDAO only needs to read.
One DAO per entity plus a ConnectionFactorySQL scattered across screensSeparate layers: screens don't know SQL, and the connection is configured in one place.
PreparedStatement for every queryBuilding SQL by concatenating stringsTyped parameters and protection against SQL injection.
Compatibility as a rule in the model (switch expression)A compatibility table in the databaseDonation rules are fixed, fit in one readable method and are easy to test.

Architecture

Layers
  1. 01Web pagesdonors, donations, stock and compatibility
  2. 02ModelsDonor, Donation, Patient, Stock, Compatibility
  3. 03DAOs (JDBC)one per entity, PreparedStatement
  4. 04MySQL 8a trigger keeps stock per blood type

Implementation highlights

The database owns the stock

The evidence is in the code itself: EstoqueDAO has no method to insert or update, only to query. The ESTOQUE table is maintained by the trigger fired on every donation.

src/DAO/EstoqueDAO.java (trimmed)
public List<Estoque> consultarTodos() throws ClassNotFoundException, SQLException {
    Connection con = ConnectionFactory.getConnection();
    PreparedStatement comando = con.prepareStatement("select * from ESTOQUE");
    ResultSet rs = comando.executeQuery();
    // ...builds the list of Estoque (blood type and amount)
}

Readable blood compatibility

The rules for who can donate to whom became a single method using Java switch expressions. The code is in Portuguese, as the course required.

src/Model/Compatibilidade.java (trimmed)
return switch (tipoDoador) {
    case "O-"  -> true;                        // universal donor
    case "O+"  -> tipoPaciente.endsWith("+");  // every Rh+
    case "A+"  -> tipoPaciente.equals("A+")  || tipoPaciente.equals("AB+");
    case "B+"  -> tipoPaciente.equals("B+")  || tipoPaciente.equals("AB+");
    case "AB+" -> tipoPaciente.equals("AB+");
    // ...and the negative types
    default    -> false;
};

Results and impact

  • Delivered for the course, with the Patient, Donor, Donation and Inventory modules and the compatibility screen.
  • In practice, it's where I solidified JDBC, the DAO pattern and layered design, the foundation of what I'm now studying with Spring Data JPA.

What I'd do differently and next steps

Links