In generale, si suppone che si verifichi un collo di bottiglia in cui sono contenute le operazioni CRUD effettive e si utilizza un'interfaccia per gestirla. Dato che questo è il genere di cose che tende a cambiare spesso poiché è necessario sviluppare più operazioni CRUD, si rischia di dover cambiare ogni chiamata a un metodo che è stato modificato o almeno, ripensare a come viene chiamato nel contesto di come lo hai cambiato.
Se stai parlando di un piccolo progetto, questo non è un grosso problema, tuttavia nei progetti più grandi, questo diventa molto noioso molto rapidamente e quindi una buona struttura diventa fondamentale. Quello che ti consiglio di fare è rendere un oggetto rappresentativo delle operazioni che stai eseguendo sul database. In altre parole, se ho delle operazioni CRUD per scrivere la tabella "Studente", creo Studente di classe che gestisce le chiamate CRUD effettive. A quel punto, per aggiornare le informazioni relative a Student, devi solo, ad esempio, implementare un metodo "Salva" che aggiorna il database utilizzando le informazioni che contiene attualmente.
A questo punto, non è più necessario preoccuparsi di fornire una connessione al database, una sessione, che si debba inserire o aggiornare. I chiamanti devono semplicemente chiamare "Salva" e la tua classe si preoccupa di quel tipo di logica. Scoprirai che non solo questo semplifica il tuo codice, ma ti consente di bloccare la logica relativa al database dal resto del tuo programma, mantenendolo in generale più pulito.