Jdbi: Docs / Beispiel: Geben Sie ein Beispiel (Repo) an, um zu zeigen, wie jdbi3 in Spring-Boot integriert wird

Erstellt am 20. Feb. 2018  ·  10Kommentare  ·  Quelle: jdbi/jdbi

Ich möchte jdbi3 in spring-boot integrieren. Aber es ist schwer, alle benötigten Teile im Internet zu finden, um sich ein vollständiges Bild zu machen.
Gibt es eine Möglichkeit, ein jdbi-examples-Repository auf github bereitzustellen, das nur zeigt, wie man eine Spring-Boot-Anwendung mit jdbi3 einrichtet?

Das würde ich sehr schätzen. Vielen Dank.
/Seb

doc help wanted improvement

Hilfreichster Kommentar

Ich habe die folgende Methode mit jdbi2.x ohne Probleme verwendet. Habe es mit jdbi3.x getestet und keine Probleme festgestellt. Dies scheint eine einfachere Möglichkeit zu sein, Spring dazu zu bringen, Transaktionen zu verwalten, während Sie jdbi verwenden.

Grundsätzlich wickeln Sie den Proxy mit einem TransactionAwareDataSourceProxy ein und verwenden diesen, um die Jdbi-Instanz zu erstellen. (Ich habe c/p'd aus der Antwort von @arteam , damit die Beispiele konsistent sind)

    <strong i="8">@Bean</strong>
    public DataSource dataSource() {
        // From Spring Boot's connection pool configuration;
    }

    <strong i="9">@Bean</strong>
    public TransactionAwareDataSourceProxy txDataSource(DataSource dataSource) {
        return new TransactionAwareDataSourceProxy(dataSource);
    }

    <strong i="10">@Bean</strong>
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        //not sure if this is needed
        return new DataSourceTransactionManager(dataSource);
    }

    <strong i="11">@Bean</strong>
    public Jdbi createJdbi(TransactionAwareDataSourceProxy dataSource) {
        //note that parameter is TransactionAwareDataSourceProxy instead of plain DataSource
        return Jdbi.create(dataSource);
    }

    <strong i="12">@Bean</strong>
    public UserDao userDao(Jdbi jdbi) {
        return jdbi.onDemand(UserDao.class);
    }

Alle 10 Kommentare

Wenn Sie in einem einfachen Fall keine Integration mit den Transaktionsfunktionen von Spring benötigen, können Sie einfach Jdbi und Ihre DAOs in einer Spring-Konfiguration initialisieren:

    <strong i="7">@Bean</strong>
    public DataSource dataSource() {
        // From Spring Boot's connection pool configuration;
    }

    <strong i="8">@Bean</strong>
    public Jdbi createJdbi(DataSource dataSource) {
        return Jdbi.create(dataSource);
    }

    <strong i="9">@Bean</strong>
    public UserDao userDao(Jdbi jdbi) {
        return jdbi.onDemand(UserDao.class);
    }

Hallo @bastman , @alwins0n trägt zu einer besseren Spring-Unterstützung in #989 bei - möchten Sie seine bisherige Arbeit überprüfen und kommentieren, ob es Ihre Spring-Integration klarer macht oder ob Sie nach etwas anderem fragen?

Die Integration von jdbi in Spring Boot ist trivial, Sie müssen nur eine annotierte Methode @Bean in Ihrer @Configuration Klasse einrichten, um eine Jdbi-Instanz zurückzugeben - wie von @arteam . gezeigt

Schwieriger ist es, wie in meiner Frühjahrs-PR, jdbi in das Frühjahrs-Transaktionsmanagement zu integrieren. Sie sollten es auf jeden Fall überprüfen, wenn es das ist, was Sie suchen.

Wenn dies genehmigt wird, überlege ich außerdem, eine Autokonfiguration / einen Spring-Boot-Starter für Spring Boot zu erstellen (2). wenn du das suchst. (Es ist eigentlich eine gute Übung, wenn Sie es selbst ausprobieren möchten: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html )

Ich habe die folgende Methode mit jdbi2.x ohne Probleme verwendet. Habe es mit jdbi3.x getestet und keine Probleme festgestellt. Dies scheint eine einfachere Möglichkeit zu sein, Spring dazu zu bringen, Transaktionen zu verwalten, während Sie jdbi verwenden.

Grundsätzlich wickeln Sie den Proxy mit einem TransactionAwareDataSourceProxy ein und verwenden diesen, um die Jdbi-Instanz zu erstellen. (Ich habe c/p'd aus der Antwort von @arteam , damit die Beispiele konsistent sind)

    <strong i="8">@Bean</strong>
    public DataSource dataSource() {
        // From Spring Boot's connection pool configuration;
    }

    <strong i="9">@Bean</strong>
    public TransactionAwareDataSourceProxy txDataSource(DataSource dataSource) {
        return new TransactionAwareDataSourceProxy(dataSource);
    }

    <strong i="10">@Bean</strong>
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        //not sure if this is needed
        return new DataSourceTransactionManager(dataSource);
    }

    <strong i="11">@Bean</strong>
    public Jdbi createJdbi(TransactionAwareDataSourceProxy dataSource) {
        //note that parameter is TransactionAwareDataSourceProxy instead of plain DataSource
        return Jdbi.create(dataSource);
    }

    <strong i="12">@Bean</strong>
    public UserDao userDao(Jdbi jdbi) {
        return jdbi.onDemand(UserDao.class);
    }

sieht gut aus, ich wusste nicht, dass es diese klasse gibt.

könntest du mal in der eingangs erwähnten PR nachschauen? es wurde bereits ein Vorschlag bezüglich einer "transaktionsbewussten" Verbindungsfabrik gemacht, die jdbi zugrunde liegt.

iirc bleibt das Problem, dass Verbindung und Handle nicht zustandsmäßig synchronisiert sind. also gibt dieser ds eine Verbindung (die an die Transaktion gebunden ist) zurück, die am Transaktionsende geschlossen wird. wohingegen das verwendete Handle nicht geschlossen wird und beim Versuch, es (wieder) zu verwenden, Ausnahmen auslöst.

aber vielleicht ist dies keine so große Sache und eher Eckfall-y und Ihre Lösung passt für 99% der Anwendungsfälle.

Kurzum: Bei Ihrem Ansatz ist die transaktionsgesteuerte Ressource die Verbindung. in meiner PR ist die verwaltete Ressource der Griff.

Es gibt Probleme im Zusammenhang mit der Verwendung von jdbi3 mit stringtemplate4 und Gruppenimporten. Siehe mein Problem https://github.com/jdbi/jdbi/issues/1052
Dieses Problem enthält auch einen Link zu einem voll funktionsfähigen Repo-Skelett für die Verwendung von jdbi3 in Spring Boot 2.0.0

Wenn ich die Lösung von @kaandok mit der erhalte ich die folgende Ausnahme aufgrund des Schließens von Handles, wenn offene Transaktionen vorhanden sind. Gibt es dafür eine empfehlenswerte/anwendbare Lösung?

"Unsachgemäße Transaktionsbehandlung erkannt: Ein Handle mit einer offenen Transaktion wurde geschlossen. Transaktionen müssen vor dem Schließen des Handles explizit festgeschrieben oder zurückgesetzt werden. Jdbi hat diese Transaktion automatisch zurückgesetzt."

@cengha können Sie bitte einen Code zur Verfügung stellen, der Ihr Problem demonstriert?

Unten ist die Konfigurationsklasse:

<strong i="6">@Bean</strong>
public HikariDataSource hikariDataSource() {
    HikariConfig dataSourceConfig = new HikariConfig();
    dataSourceConfig.setDriverClassName(driverClassName);
    dataSourceConfig.setJdbcUrl(jdbcUrl);
    dataSourceConfig.setUsername(username);
    dataSourceConfig.setPassword(password);
    dataSourceConfig.setAutoCommit(true);
    return new HikariDataSource(dataSourceConfig);
}

<strong i="7">@Bean</strong>
public TransactionAwareDataSourceProxy transactionAwareDataSourceProxy(HikariDataSource dataSource) {
    return new TransactionAwareDataSourceProxy(dataSource);
}

<strong i="8">@Bean</strong>
public PlatformTransactionManager platformTransactionManager(HikariDataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

<strong i="9">@Bean</strong>
public Jdbi jdbi(TransactionAwareDataSourceProxy transactionAwareDataSourceProxy) {
    Jdbi jdbi = Jdbi.create(transactionAwareDataSourceProxy);
    jdbi.installPlugin(new SqlObjectPlugin());
    return jdbi;
}

Hier ist die Serviceschicht

    <strong i="13">@Override</strong>
    <strong i="14">@Transactional</strong>
    public Long createX(X x) {
        Long aLong = XDao.insertX(x);
        if(true) throw new RuntimeException();
        return aLong;
    }

Wenn Auto-Commit auf false gesetzt ist, habe ich einen Transaktionsfehler erwähnt, aber wenn er auf true gesetzt ist, gibt es keinen Transaktionsfehler, aber dieses Mal funktioniert das Rollback nicht (nach einer Laufzeitausnahme) und so wird das X-Objekt in der Datenbank beibehalten. Ich verwende Spring 2.0.3, JDBI 3.0.0-beta2 .

Problem gelöst. Ich habe eine ältere Version von JDBI verwendet, nachdem ich bemerkt hatte, dass dieser Thread die Bibliothek aktualisiert und alles behoben wurde.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

electrum picture electrum  ·  3Kommentare

jimmyhmiller picture jimmyhmiller  ·  6Kommentare

keith-miller picture keith-miller  ·  3Kommentare

mcarabolante picture mcarabolante  ·  4Kommentare

buremba picture buremba  ·  5Kommentare