根据Dropwizard文档,使用DBI.onDemand创建的DBI实例可以根据需要打开和关闭连接。我观察到一种情况,如果您在Docker中运行Dropwizard,并让它空闲一天左右,我的day将无法重新连接到rdbms。
我要做的是在启动时使用onDemand获取一次DAO实例,然后在应用程序的整个生命周期中一直保持下去。这是使用onDemand的正确方式吗?还是应该在每次运行查询时都获得一个新的DAO实例?
发布于 2016-12-20 07:50:27
我只将dropwizard与MariaDB一起使用,但我假设postgresql的行为是相似的。我在启动时创建一个dbi实例,并使用它为每个JDBI接口创建一个实例。这些JDBI实例在所有资源之间共享。
一个包含Guice的简单示例如下所示:
假设您有一个JDBI接口UserQuery:
@RegisterMapper(UserMapper.class)
public interface UserQuery {
@GetGeneratedKeys
@SqlUpdate("INSERT INTO userData (email, role) values (:email, role)")
long insertUser(@BindBean User user);
@SqlQuery("SELECT * FROM userData WHERE id = :id")
User getUserById(@Bind("id") long id);假设您还有另一个JDBI接口CommentQuery。
在启动时,为UserQuery和CommentQuery创建一个dbi onDemand实例。创建一个injector对象,并将两个实例绑定到它们的类UserQuery.class和CommentQuery.class。从injector对象创建一个UserResource实例,并将其注册到jersey。因此,您最终会得到一个UserQuery实例、一个CommentQuery实例和一个UserResource实例。
@Override
public void run(MyConfiguration conf, Environment env) {
Injector injector = Guice.createInjector(Stage.DEVELOPMENT, new AbstractModule() {
@Override
protected void configure() {
DBIFactory factory = new DBIFactory();
DBI dbi = factory.build(env, conf.getDatabase(), "mydb");
UserQuery userQuery = dbi.onDemand(UserQuery.class);
bind(UserQuery.class).toInstance(userQuery);
CommentQuery commentQuery = dbi.onDemand(CommentQuery.class);
bind(CommentQuery.class).toInstance(commentQuery);
}
});
UserResource userResource = injector.getInstance(UserResource.class);
env.jersey().register(userResource);
}UserResource可能如下所示:
@Path("/user")
public class UserResource {
private final UserQuery userQuery;
private final CommentQuery commentQuery;
@Inject
public UserResource(UserQuery userQuery, CommentQuery commentQuery) {
this.userQuery = userQuery;
this.commentQuery = commentQuery;
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
long userId = userQuery.insertUser(user);
Comment comment = new Comment();
comment.setCreatorId(userId);
comment.setTitle("Hello everyone!");
commentQuery.insert(comment);
return Response.ok().build();
}
}或者,如果您不喜欢使用guice (删除UserResource中的@Inject注释)
@Override
public void run(MyConfiguration conf, Environment env) {
DBIFactory factory = new DBIFactory();
DBI dbi = factory.build(env, conf.getDatabase(), "mydb");
UserQuery userQuery = dbi.onDemand(UserQuery.class);
CommentQuery commentQuery = dbi.onDemand(CommentQuery.class);
UserResource userResource = new UserResource(userQuery, commentQuery);
env.jersey().register(userResource);
}这看起来与您所描述的非常相似。我也同时使用docker和dropwizard,但到目前为止我还没有遇到所描述的问题。
https://stackoverflow.com/questions/41045039
复制相似问题