【问题标题】:jdbi, guice with dropwizardjdbi,带有dropwizard的guice
【发布时间】:2015-03-23 05:18:12
【问题描述】:

您好,我正在尝试使用 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 作为构建工具。

我的问题是

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

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

注意:我们不会为此应用程序使用休眠,而是使用 JDBI。

【问题讨论】:

  • 这种方法是否解决了mysql的多租户问题?

标签: java mysql guice dropwizard


【解决方案1】:

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

(1) 给项目添加guice

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

(2)initialize()中的设置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。要使用带有 Dropwizard 0.8.1 的 JDBI 和 Java 8,请使用 jdbi 版本 2.62 以避免错误https://github.com/jdbi/jdbi/issues/144

如果这对您有帮助,请告诉我。

最好的问候,

亚历山大

【讨论】:

  • 有点晚了,我把我实现的贴出来,我的实现需要一些cmets。
  • 抱歉来晚了。我期待看到您的解决方案。如果您不想在此处发布,请查看我的个人资料以通过电子邮件与我联系。
  • 回复太晚了,我在忙上面的项目。我实现的是使用dropwizard托管对象功能初始化jdbi和hikari cp,初始化后我将它们保存在静态变量中并编写了一个guice提供程序,它将返回该初始化的静态变量。它是一个单独的 maven 工件,用于所有微服务
  • 这种方法是否支持mysql多租户?
  • dropwizard-guicey (xvik.github.io/dropwizard-guicey/4.2.2/extras/jdbi3/…) 有一个 @InTransaction 注释可能也有帮助。
【解决方案2】:

我无法发表评论,但想补充亚历克斯的答案:

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

在Guice模块中,添加一个provide方法:

@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 注释。 (我还没有找到直接将它们与 guice 一起使用的方法)。例如,如果您需要在事务中执行 DAO 代码,这非常好。 Repository 仍然在 Guice 中处理,因此可以在任何地方注入,但 jDBI 会处理 DAO/Repository 代码中的棘手部分。

希望这会有所帮助:)

阿图尔

【讨论】:

  • 您也可以尝试对 Alex 的回答提出修改建议。
猜你喜欢
  • 1970-01-01
  • 2014-07-26
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多