2 Stimmen

MySQL-Ansicht in eine CSV-Datei mit Java, Spring und Hibernate konvertieren

Ich wurde gebeten, eine CSV-Datei aus einer Ansicht in MySQL auszugeben. Die App, an der ich gerade arbeite, verwendet Spring und Hibernate, um die Datenbank zu erstellen, aber die Ansicht wird mir einfach gegeben.

Hibernate weiß nichts über diese Ansicht, aber ich möchte etwas wie folgt tun:

public List getCsvView() {
  return (List) getHibernateTemplate().find("from myView");
}

Meine Vermutung war, dass ich eine native Abfrage zuordnen könnte, damit Hibernate die Ansicht kennt. Dies wurde etwas knifflig, als ich die Dokumentation las:

  Sie können auch eine native Abfrage zuordnen, um dies zu erreichen, müssen Sie die SQL-Ergebnismenge-Struktur beschreiben, indem Sie @SqlResultSetMapping verwenden.

Ich bin wirklich nicht daran interessiert, die Struktur des Ergebnisses abzubilden. Es ist mir genug, wenn die Struktur einfach eine Menge von Objekten ist.

Außerdem könnten sie diese Ansicht jederzeit ändern. Ich bin wirklich nicht begeistert davon, dass meine App überhaupt von der Ansicht weiß.

Gibt es also einen einfachen Weg, dies in der Spring/Hibernate-Welt zu tun, oder gehe ich das Problem auf die harte Tour an?

1voto

Pascal Thivent Punkte 548176

Führen Sie einfach eine native Abfrage auf der Ansicht durch und Sie erhalten eine List von Object[] mit Skalarwerten für jede Spalte als Ergebnis. Aus der Dokumentation:

16.1.1. Skalare Abfragen

Die einfachste SQL-Abfrage ist, eine Liste von Skalaren (Werten) zu erhalten.

sess.createSQLQuery("SELECT * FROM CATS").list();
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();

Diese geben eine Liste von Objektarrays (Object[]) mit Skalarwerten für jede Spalte in der Tabelle CATS zurück. Hibernate verwendet ResultSetMetadata, um die tatsächliche Reihenfolge und Typen der zurückgegebenen Skalarwerte abzuleiten.

Um den Overhead der Verwendung von ResultSetMetadata zu vermeiden oder einfach genauer anzugeben, was zurückgegeben wird, kann man addScalar() verwenden:

sess.createSQLQuery("SELECT * FROM CATS")
 .addScalar("ID", Hibernate.LONG)
 .addScalar("NAME", Hibernate.STRING)
 .addScalar("BIRTHDATE", Hibernate.DATE)

Diese Abfrage spezifiziert:

  • den SQL-Abfragetext
  • die Spalten und Typen, die zurückgegeben werden

Diese geben jetzt Objektarrays zurück, verwenden jedoch nicht ResultSetMetadata, sondern greifen explizit auf die ID-, NAME- und BIRTHDATE-Spalten als Long, String bzw. Short aus dem zugrunde liegenden Resultset zu. Das bedeutet auch, dass nur diese drei Spalten zurückgegeben werden, obwohl die Abfrage * verwendet und mehr als die drei aufgelisteten Spalten zurückgeben könnte.

Es ist möglich, die Typinformationen für alle oder einige der Skalare auszulassen.

sess.createSQLQuery("SELECT * FROM CATS")
 .addScalar("ID", Hibernate.LONG)
 .addScalar("NAME")
 .addScalar("BIRTHDATE")

Dies ist im Wesentlichen die gleiche Abfrage wie zuvor, aber jetzt wird ResultSetMetaData verwendet, um den Typ von NAME und BIRTHDATE zu bestimmen, während der Typ von ID explizit angegeben ist.

Wie die von ResultSetMetaData zurückgegebenen java.sql.Types auf Hibernate-Typen abgebildet werden, wird vom Dialekt gesteuert. Wenn ein bestimmter Typ nicht zugeordnet ist oder nicht den erwarteten Typ ergibt, ist es möglich, dies über Aufrufe von registerHibernateType im Dialekt anzupassen.

Sieht perfekt aus, um eine CSV-Datei zu generieren, ohne etwas über die Ansicht zu wissen :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X