当前位置: 首页 > 知识库问答 >
问题:

jdbi,guice与dropwizard

阎智
2023-03-14

你好,我正在尝试使用dropwizard框架创建一个应用程序。我有DAO类impl,它需要一个连接管理器实例的句柄,然后用于获取数据库连接。我有一个多租户数据库应用程序。这个连接管理器将是一个自定义实现。

该应用程序使用hikari cp作为连接池和mysql数据库。我想使用dropwizard托管对象功能初始化数据源和连接池。一旦数据源被初始化,我想使用guice绑定在每个dao类中注入连接管理器实例,类似于

bind(ConnectionManager.class).toProvider(ConnectionManagerProvider.class);

然后在每个dao impl类中

@Inject
public class UserDAOIpl extends AbstractDAO {
    protected UserDAOImpl(ConnectionManager connectionManager) {
        super(connectionManager);
    }
}

我在网上到处都找过了,没有我的用例的特殊例子。dropwirzard.io也缺少留档。

这更像是一个架构设计问题,而不是代码问题。

数据源模块将是一个单独的模块,将用于许多服务。我正在使用maven作为构建工具。

我的问题是:

    < li >我该如何应对这种情况?一些类名和实现指南会非常有用。 < li >该应用程序每天将处理50万个请求。解决方案应该是可行的。

我期待社区提供任何指导,或者任何机构可以向我指出一些好的资源。

注意:我们不会在这个应用程序中使用hibernate,而是使用JDBI。

共有2个答案

司空鸿禧
2023-03-14

我不能发表评论,但想补充亚历克斯的回答:

对于存储库实现,我建议让jDBI处理存储库,而不是使用Guice。这是我所做的:

在 Guice 模块中,添加一个提供方法

@Provides
@Singleton
public void repository(Dbi dbi) {
    // dbi.onDemand(whateverYourClassIs.class)
}

在存储库类中,使用@CreateSqlObject使您的DAO可用:

public abstract class Repo {
    @CreateSqlObject
    abstract Dao dao(); // will return a jDBI managed DAO impl

    public void doWhatever() {
       /// logic
    }
}

这具有明显的优势,即您现在可以使用 jDBI 注释。(我还没有找到一种方法来直接使用它们)。这非常好,例如,如果您需要在事务中执行DAO代码。存储库仍然在Guice中处理,因此它可以在任何地方注入,但是jDBI处理DAO /存储库代码中的棘手位。

希望这有帮助:)

阿图尔

苏俊友
2023-03-14

我准备了一个与您描述的类似的设置,如下所示。它设置guice,初始化DBIFactory(您可能需要在您的场景中采用该部分)。然后,JDBI对象被移交给一个存储库实现,该存储库实现可以使用它来持久化Vessel类型的实体。

(1) 为项目添加指导

<dependency>
  <groupId>com.hubspot.dropwizard</groupId>
  <artifactId>dropwizard-guice</artifactId>
  <version>x.x.x</version>
</dependency>

(2)在novalize()中设置Guice:

guiceBundle = GuiceBundle.<YourConfiguration>newBuilder()
        .addModule(new GuiceModule())
        .enableAutoConfig("your.package.name.heres")
        .setConfigClass(YourConfiguration.class)
        .build();

(3)准备JDBI元素的Guice配置

public class GuiceModule extends AbstractModule {

    private DBI jdbi;

    @Provides
    public DBI prepareJdbi(Environment environment,
                           SightingConfiguration configuration) throws ClassNotFoundException {
        // setup DB access including DAOs
        // implementing a singleton pattern here but avoiding 
        // Guice to initialize DB connection too early
        if (jdbi == null) {
            final DBIFactory factory = new DBIFactory();
            jdbi = factory.build(environment, configuration.getDataSourceFactory(), "h2");
        }
        return jdbi;
    }

    @Provides
    public VesselJDBI prepareVesselJdbi(DBI jdbi) {
        return jdbi.onDemand(VesselJDBI.class);
    }

    @Override
    protected void configure() {
        bind(VesselRepository.class).to(VesselRepositoryImpl.class);
        /* ... */
    }
}

(4)开始在课堂上使用它

public class VesselRepositoryImpl implements VesselRepository {

    private VesselJDBI jdbi;    

    @Inject
    public VesselRepositoryImpl(VesselJDBI jdbi) {
        this.jdbi = jdbi;
    }

    public Vessel create(Vessel instance) {
        return jdbi.inTransaction((transactional, status) -> {
            /* do several things with jdbi in a transactional way */
        });
    }

}

(请注意:上一个代码示例用的是Java 8。要将JDBI与Java 8和Dropwizard 0.8.1一起使用,请使用JDBI 2.62版以避免https://github.com/jdbi/jdbi/issues/144错误)

请让我知道这是否对您有所帮助。

此致敬意

亚历山大

 类似资料:
  • 我一直想利用Guice 但是,我开始遇到 Governator 和 Dropwizard 之间的类路径问题。我不得不在我的pom.xml中排除以下模块: 注意:我正在使用管理程序版本 1.3.3 但是现在我遇到的问题是没有指定基本包,乍一看是NoSuchMethodError,我想这可能是另一个类路径问题: 但是,在我的应用程序中,我使用了他们在dropwizer-guice github页面上显

  • jDBI 提供一个 Java 简单操作接口, 它不是一个抽象层而是一个类库是的公共的操作更简单、还有能力去做一些更复杂的操作。 JDBI 是 Java 的 SQL 便捷操作库,尝试使用集合,beans 等等来暴露 Java 中的关系型数据库,可以维护相同级别的 JDBC。提供两个不同样式的 APIs:fluent 和 sql object。 Fluent API // using in-memor

  • 从(在文件中)开始,一直到模式,我几乎尝试了任何名称空间,但我看到的只是如下所示: 这年头有办法做到这一点吗?

  • 我可以使用注释将jdbi查询的结果映射到我感兴趣的bean,如下所示: 如果应用程序中使用的实例尚未注册到任何自定义映射器中,则此操作很好。 此映射器在应用程序开始时注册到实例,如下所示: 重写方法,并提供逻辑将任何类型的结果从数据库转换为相关的bean类型。正是这个uber转换器负责整个应用程序中所有DB到POJO的转换。 我的问题是:有没有一种方法可以告诉继续使用这个将结果从数据库转换为所有类

  • 是否对两个函数进行了净化/对SQL注入安全?例如,请考虑以下内容: 我目前的理解是,将字符串按原样直接插入到查询中,但进行净化处理。因此,如果我们控制和tableName,并且只有参数是用户输入,那么就可以了。

  • 我在这里做错了什么?