MySQL INSERT / UPDATE MySQL - perStoredProcedure oder direkt im Code

  • Themenstarter Themenstarter Gelöschtes Mitglied 46222
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 46222

Gast
Hallo zusammen!

Ich möchte ein Objekt "Ressource" in meine Datenbank speichern, einen Eintrag in der Datenbank ändern oder löschen. Dabei möchte ich auch Prüfungen vornehmen, bspw. ob schon ein Datensatz mit gleichem Namen oder gleicher ID vorhanden ist.
Java:
public class Ressource 
{
//ein Ausschnitt des Codes
// Setter / Getter vorhanden
	private int ressourceId;
	private String name;
	private String type;
	private String source;
}
Code:
CREATE TABLE `ressources` (
  `ressource_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `type` varchar(255) DEFAULT NULL,
  `source` varchar(255) DEFAULT NULL
  PRIMARY KEY (`ressource_id`),
  KEY `name_idx` (`name`)
)

Weg1:
Java:
// con sei ein benutzbares DB-Connection Objekt
// ressource sein ein Objekt der Klasse Ressource
CallableStatement cstmt = con.prepareCall(" INSERT INTO ressources SET name = ?, type = ?, source = ?");
cstmt.setString(1, ressource.getName());
cstmt.setString(2, ressource.getType());
cstmt.setString(3, ressource.getSource());
cstmt.execute;

Weg2:
Java:
cstmt = con.prepareCall("call sp_create_ressource(?,?,?,?)");
cstmt.setString(1, repRessource.getName());
cstmt.setString(2, repRessource.getType());
cstmt.setString(3, repRessource.getSource());
cstmt.registerOutParameter(4, Types.VARCHAR);
cstmt.execute();
sp_create_ressource ist eine auf dem MySQL-Server liegende StoredProcedure
Code:
CREATE DEFINER=`workbench`@`localhost` PROCEDURE `sp_create_ressource`(
	IN p_ressource_name VARCHAR(255),
	IN p_type VARCHAR(255),
	IN p_source VARCHAR(255),
	OUT p_result VARCHAR(255)
)
BEGIN
	DECLARE 
		v_ressource_id INT;
	
	SELECT ressource_id FROM ressources WHERE name = p_ressource_name INTO v_ressource_id;

	IF v_ressource_id IS NOT NULL
		THEN SELECT CONCAT("Ressource ", p_ressource_name, " existiert bereits") INTO p_result;
	ELSE 
		BEGIN
			INSERT INTO ressources 
				SET 
					name = p_ressource_name, 
					type = p_type, 
					source = p_source, 
			SELECT CONCAT("Ressource ", p_ressource_name, " wurde erfolgreich angelegt") INTO p_result;
		END;
	END IF;
END

Was sind eurer Meinung nach hier die Vorteile / Nachteil der beiden Wege bezüglich Performance, Sicherheit, Wartbarkeit, Design?

Als kurze Erklärung, ich habe die Datenbank vor dem Javacode entworden und habe die StoredProcedures verwendet um einfacher Testdaten hinzufügen zu können.
Als ich dann ans Coden ging habe ich einfach die bereits vorhandenen SP's genutzt, da in diesen auch diverse Prüfungen drin waren.

Eure Meinung?
 
Performance
  • Weg 1 ordentlich
  • Weg 2 excellent
Sicherheit
  • Weg 1 ordentlich
  • Weg 2 excellent
Wartbarkeit
  • Weg 1 excellent
  • Weg 2 ordentlich
Design
  • Weg 1 excellent
  • Weg 2 ordentlich

Wie du dir wahrscheinlich vorstellen kannst, betrachten Java Entwickler store-procedures mit gemischten Gefühlen. Denn auf der einen Seite write-once-run-everywhere während auf der anderen Seite proprietärer DB-Code steht. Daher würde ich Letzteres vermeiden wenn es möglich ist.

Dies gilt umso mehr bei deinem Beispiel wo "nur" ein Datensatz eingefügt wird und dies recht einfach mit einem PreparedStatement gemacht werden kann. Andererseits sind stored-procedures "angenehm", wenn sie mehr mit Business-Logik zu tun haben, beispielsweise Validierungen vornehmen bevor die DB geändert wird.
 
Zuletzt bearbeitet:
Das ist der Punkt @ Validierungen!

Ich wollte kein zu aufwendiges / langes Beispiel einfügen um die grundsätzliche Frage nicht zu kompliziert zu machen. In einem anderen Fall tue ich bspw folgendes: Statt einem direkt Update des Datensatzes ändere ich ein "most_recent" flag von 1 auf 0 und füge die geänderten Informationen als ganz neuen Datensatz ein. Darüber hinaus ist dann die "ID" auch nicht Auto-Increment sondern wird "manuell" vergeben.
Anderes Beispiel: Anstatt einen Datensatz komplett zu löschen, möchte ich nur ein Löschkennzeichen von 0 auf 1 setzen
usw usf
Man könnte hier zwar auch einen "ON UPDATE" Trigger verwenden, aber ich finde, das kommt aufs selbe hinaus - Funktionalität befindet sich in der DB und nicht im Code

Kann ich das so zusammenfassen:
Bei einfachem UPDATE / INSERT sollte die SQL-Anweisung im Javacode geschrieben werden, bei komplexeren Validierungen / Business Logik kann man sie (oder Teile davon) in die DB Auslagern?

Vielen Dank für die Antwort!
Stefan
 

Zurück
Oben