[JAVA] Mit Commons DbUtils können Sie ganz einfach JDBC-Anrufe tätigen

Eine Bibliothek namens Apache Commons DbUtils erleichtert das Schreiben von DB-Zugriffscode als das direkte Aufrufen der JDBC-API. Commons DbUtils ist eher eine kleine Bibliothek als ein großes Framework, daher hat es den Vorteil, dass es einfach bereitzustellen ist.

Hol Jar

Sie können Jar auch von der Download-Seite auf der offiziellen Website herunterladen. Wenn Sie jedoch Maven verwenden, können Sie Folgendes in POM sehen Es ist in Ordnung, wenn Sie wie schreiben (Es scheint, dass 1.7, die neueste Version zum ersten Mal seit 3 Jahren, gerade veröffentlicht wurde).

<dependency>
  <groupId>commons-dbutils</groupId>
  <artifactId>commons-dbutils</artifactId>
  <version>1.7</version>
</dependency>

Wie rufe ich an?

Ich werde die grundlegende Methode zum Aufrufen von Commons DbUtils vorstellen.

Erstellen Sie zunächst einen QueryRunner

Erstellen Sie zunächst eine Instanz einer Klasse namens QueryRunner. Einfach neu ohne Argumente, oder wenn Sie eine DataSource verwenden (für Verbindungspooling usw.), nehmen Sie sie einfach als Argument und neu.

QueryRunner queryRunner = new QueryRunner();

//Wenn Sie eine DataSource haben, klicken Sie hier.
DataSource dataSource = ... 
QueryRunner queryRunner = new QueryRunner(dataSource);

Führen Sie die Anweisungen INSERT, UPDATE und DELETE aus

Als nächstes werde ich ein einfaches und leicht verständliches Beispiel für die Methoden vorstellen, die SQL-Anweisungen ausführen. Dies ist ein Ersatz für den Teil, der PreparedStatement # executeUpdate () im direkten JDBC-Aufruf verwendet hat. Insbesondere ist dies alles.

//Ein Beispiel für UPDATE einer Zeile einer Tabelle namens Person
int rows = queryRunner.update(connection, "UPDATE Person SET Name = ? WHERE Id = ?", "Taro", 1);

Dies führt dazu, dass QueryRunner intern ein PreparedStatement erstellt, die Parameter festlegt, executeUpdate () aufruft und eine Reihe von Schließvorgängen ausführt.

Der Rückgabewert entspricht dem Rückgabewert von PreparedStatement # executeUpdate (), dh die Anzahl der geänderten Zeilen wird zurückgegeben.

Die erste Argumentverbindung kann weggelassen werden, wenn DataSource beim Erstellen von QueryRunner übergeben wird. Wenn nicht angegeben, wird getConnection () aufgerufen und intern für diese DataSource verwendet. Und es wird automatisch geschlossen.

SQL-Anweisungsparameter werden als Argumente variabler Länge empfangen, sodass Sie beispielsweise Folgendes tun können.

List<Object> params = new ArrayList<>();
params.add(...);
params.add(...);

queryRunner.update("...", params.toArray()); //Sie können es in Form eines Arrays übergeben.

Führen Sie die SELECT-Anweisung aus

Als nächstes werde ich die Ausführung der SELECT-Anweisung vorstellen. Dies ist ein Ersatz für den Teil, der PreparedStatement # executeQuery () im direkten JDBC-Aufruf verwendet hat. Im Gegensatz zu früher wird ein ResultSet zurückgegeben, wenn die SQL-Anweisung ausgeführt wird. Daher muss konvertiert werden, wie das Ergebnis aus diesem ResultSet in der gewünschten Form (Typ) abgerufen wird. Zu diesem Zweck bietet Common DbUtils eine Schnittstelle namens ResultSetHandler.

Wenn Sie als einfaches Beispiel den Zeichenfolgenwert (dh eine einzelne Zeichenfolge) für eine bestimmte Spalte, einen bestimmten Datensatz oder eine bestimmte Tabelle abrufen möchten:

//Implementieren Sie ResultSetHandler. In diesem Beispiel wurde es als anonyme Klasse implementiert.
//ResultSetHandler verfügt über einen Typparameter und gibt den Typ an, den Sie hier zurückgeben möchten. Diesmal String.
ResultSetHandler<String> personNameHandler = new ResultSetHandler<String>() {
    @Override
    public String handle(ResultSet rs) throws SQLException {
        if (rs.next()) {
            //Geben Sie einfach den Wert in der ersten Spalte (obwohl es nur einen gibt) als Zeichenfolge zurück.
            return rs.getString(1); 
        }
        return null;
    }
};

//Die Implementierungsklasse von ResultSetHandler ist ResultSetHandler<String>Da wurde es als implementiert
//Der Typ des Rückgabewertnamens ist String.
String name = queryRunner.query(connection, "SELECT Name FROM Person WHERE Id = ?", personNameHandler, 1);

Auf diese Weise wird der Konvertierungsprozess "Wie konvertiert man das ResultSet, sobald es erhalten wurde" als ResultSetHandler ausgedrückt, und die Methode QueryRunner # query () wird aufgerufen, indem es in das Argument aufgenommen wird. Dies führt dazu, dass QueryRunner PreparedStatement # executeQuery () intern aufruft, ResultSetHandler # handle () auf das zurückgegebene ResultSet anwendet und das Ergebnis zurückgibt. Andere Argumente als ResultSetHandler sind dieselben wie QueryRunner # update () (Verbindung wird weggelassen, Parameter werden als Argumente variabler Länge übergeben).

Implementierungsklasse von ResultSetHandler im Voraus vorbereitet

Dieses Mal habe ich ResultSetHandler selbst implementiert, aber die in typischen Situationen wie diesem Beispiel verwendete ResultSetHandler-Implementierungsklasse ist bereits in Commons DbUtils enthalten. Sie müssen das offizielle Javadoc (http://commons.apache.org/proper/commons-dbutils/apidocs/index.html) lesen, um weitere Informationen zu erhalten. Hier sind jedoch einige.

ScalarHandler kann in Situationen verwendet werden, in denen Sie einen einzelnen Wert abrufen möchten, wie in diesem Beispiel.

//Im vorherigen Beispiel war dies tatsächlich in Ordnung.
String name = queryRunner.query("...", new ScalarHandler<>(), ...);

MapHandler konvertiert das Ergebnis der Auswahl einer Zeile in eine Karte. Der Spaltenname ist der Schlüssel zur Karte.

Map<String, Object> map = queryRunner.query("SELECT * FROM Person WHERE Id = ?", new MapHandler(), 1);

//Sie können eine Karte wie diese erhalten.
// map.get("Id") -> 1
// map.get("Name") -> "Taro"

BeanHandler konvertiert das Ergebnis von SELECTing einer Zeile in eine Java Bean.

//Angenommen, eine solche Klasse ist definiert ...
public class Person {
    private int id;
    private String name;
    //Unten Getter/Definition von Setter ...
}
//Auf diese Weise werden Java-Felder gemäß dem Ergebnis von SELECT festgelegt.
Person person = queryRunner.query("SELECT * FROM Person WHERE Id = ?", new BeanHandler<>(Person.class), 1);

Standardmäßig müssen in BeanHandler der DB-Spaltenname und der Java-Eigenschaftsname (Feldname) übereinstimmen. Sie können die Entsprechung zwischen Spaltennamen und Eigenschaftsnamen auch als Karte angeben, indem Sie die folgenden Schritte ausführen.

//Angenommen, eine solche Klasse ist definiert ...
public class Person2 {
    private int id;
    private String fullName; //Dies stimmt nicht mit dem DB-Spaltennamen überein.
    //Unten Getter/Definition von Setter ...
//Bereiten Sie eine Zuordnung mit dem DB-Spaltennamen als Schlüssel und dem Java-Eigenschaftsnamen als Wert vor.
Map<String, String> columnToPeroperty = new HashMap<>();
columnToPeroperty.put("Id", "id");
columnToPeroperty.put("Name", "fullName");

//Ein Objekt vom Typ RowProcessor kann im Konstruktorargument von BeanHandler angegeben werden.
//Darüber hinaus ist das Konstruktorargument von BasicRowProcessor, der Implementierungsklasse von RowProcessor,
//Sie können ein Objekt vom Typ BeanProcessor angeben.
//Darüber hinaus können Sie die Map als Konstruktorargument von BeanProcessor übergeben.

//Wenn Sie das oben von unten nach oben machen ...
BeanProcessor beanProcessor = new BeanProcessor(columnToPeroperty);
RowProcessor rowProcessor = new BasicRowProcessor(beanProcessor);
ResultSetHandler<Person2> beanHandler = new BeanHandler<>(Person2.class, rowProcessor);

Das ist alles für die ResultSetHandler-Implementierungsklasse, die Sie möglicherweise häufig verwenden. Um das Ergebnis der Auswahl mehrerer Zeilen zu interpretieren, gibt es außerdem eine Klasse, die eine Liste oder Zuordnung des Ergebnisses einer Zeile als Element zurückgibt.

Ruft den automatisch generierten Schlüssel ab, wenn die INSERT-Anweisung ausgeführt wird

Abhängig von der Tabelle gibt es häufig Spalten, die beim EINFÜGEN automatisch nummeriert werden. Insert () ist anstelle von QueryRunner # update () nützlich, wenn Sie die Werte dieser Spalten gleichzeitig mit dem Einfügen abrufen möchten.

Die Verwendung ähnelt der bei SELECTing verwendeten query (), und der ResultSetHandler wird als Argument angegeben. Anschließend ruft QueryRunner intern PreparedStatement # executeUpdate () auf, ruft dann PreparedStatement # getGeneratedKeys () auf, um das ResultSet abzurufen, wendet den ResultSetHandler darauf an und gibt das Ergebnis zurück. Werde dir geben.

Hier ist ein einfaches Beispiel.

//In der Personentabelle befindet sich eine Spalte mit dem Namen Id. Es wird davon ausgegangen, dass bei der Ausführung von INSERT Seriennummern zugewiesen werden.
//Hier habe ich ScalarHandler verwendet.
Integer taroId = queryRunner.insert("INSERT INTO Person(name) VALUES(?)", new ScalarHandler<>(), "Taro") ;

Recommended Posts

Mit Commons DbUtils können Sie ganz einfach JDBC-Anrufe tätigen
(Java) Einfache BDD mit Spektrum?
Einfacher Mikroservice mit Spark Framework!
Verwenden Sie Spring JDBC mit Spring Boot
Einfaches Web-Scraping mit Jsoup
Einfache Bibliothekseinführung mit Maven!
Verwenden Sie SpatiaLite mit Java / JDBC