根据Dropwizard的观察,使用DBI.onDemand创建的DBI dao实例可以打开&根据需要关闭连接。我观察过一种情况,如果你在Docker中运行Dropwizard&让它闲置一天左右,我的daos无法重新连接到rdbms。
我正在做的是在启动时使用onDemand获取DAO实例一次&然后坚持应用程序的生命周期。这是使用onDemand的正确方法,还是每次我想运行查询时都应该获得一个新的DAO实例?
答案 0 :(得分:0)
我只使用了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实例。创建一个注入器对象,并将这两个实例绑定到它们的类UserQuery.class和CommentQuery.class。从注入器对象创建单个实例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,但到目前为止我还没有遇到过所描述的问题。