【问题标题】:Use custom creds while using DropWizard JDBI在使用 DropWizard JDBI 时使用自定义凭据
【发布时间】:2014-06-30 01:53:37
【问题描述】:

我正在使用 Dropwizard JDBI 框架开发一个网络服务。

现在,我不想在 yaml 文件中使用数据库配置,而是使用“用户指定的参数”,我的意思是,数据库配置将通过端点 url 提供。

  • 是否可以通过 dropwizard jdbi 获得自定义凭据?

如果是,在引用此代码时我应该考虑在代码中做哪些更改? ->

http://dropwizard.readthedocs.org/en/latest/manual/jdbi.html

我了解,在正常流程中,服务方法在运行方法中获取配置详细信息 -

-- 配置类

public class ExampleConfiguration extends Configuration {
    @Valid
    @NotNull
    @JsonProperty
    private DatabaseConfiguration database = new DatabaseConfiguration();

    public DatabaseConfiguration getDatabaseConfiguration() {
        return database;
    }
}

-- 服务类

@Override
        public void run(ExampleConfiguration config,
                        Environment environment) throws ClassNotFoundException {
            final DBIFactory factory = new DBIFactory();
            final DBI jdbi = factory.build(environment, config.getDatabaseConfiguration(), "postgresql");
            final UserDAO dao = jdbi.onDemand(UserDAO.class);
            environment.addResource(new UserResource(dao));
        }

-- 和 yaml

database:
  # the name of your JDBC driver
  driverClass: org.postgresql.Driver

  # the username
  user: pg-user

  # the password
  password: iAMs00perSecrEET

  # the JDBC URL
  url: jdbc:postgresql://db.example.com/db-prod

但在这种情况下,我可能会在资源级别获得配置详细信息...

类似的东西 -

@GET
@Path(value = "/getProduct/{Id}/{dbUrl}/{dbUname}/{dbPass}")
@Produces(MediaType.APPLICATION_JSON)
public Product getProductById(@PathParam(value = "Id") int Id,
        @PathParam(value = "dbUrl") String dbUrl,
        @PathParam(value = "dbUname") String dbUname,
        @PathParam(value = "dbPath") String dbPass) {

     //I have to connect to the DB here! using the params i have.         
     return new Product(); //should return the Product
}

如果有人能指出我的方向,我将不胜感激。

【问题讨论】:

    标签: java dropwizard jdbi


    【解决方案1】:

    为什么不直接使用 JDBI?

    @GET
    @Path(value = "/getProduct/{Id}/{dbUrl}/{dbUname}/{dbPass}")
    @Produces(MediaType.APPLICATION_JSON)
    public Product getProductById(@PathParam(value = "Id") int id,
        @PathParam(value = "dbUrl") String dbUrl,
        @PathParam(value = "dbUname") String dbUname,
        @PathParam(value = "dbPass") String dbPass) {
      DataSource ds = JdbcConnectionPool.create(dbUrl, dbUname, dbPass);
      DBI dbi = new DBI(ds);
      ProductDAO dao = dbi.open(ProductDao.class);
      Product product = dao.findById(id);
      dao.close();
      ds.dispose();
      return product;
    }
    
    @RegisterMapper(ProductMapper.class)
    static interface ProductDao {
      @SqlQuery("select id from product_table where id = :id") // Whatever SQL query you need to product the product
      Product findById(@Bind("id") int id);
    
      @SqlQuery("select * from product_table")
      Iterator<Product> findAllProducts();
    }
    
    static class ProductMapper implements ResultSetMapper<Product> {
      public Product map(int index, ResultSet r, StatementContext ctx) throws SQLException {
        return new Product(r.getInt("id")); // Whatever product constructor you need
      }
    }
    

    【讨论】:

    • 这工作得很好。很好的答案!我相信 registerMapper 类是将查询的输出转换为 Product 类?对吗?
    • @webExplorer 正是...您应该为您的实际 Product 类自定义它。
    • RegisterMapper 看起来很酷...我在哪里可以找到它的文档?我有 2 个 dao 方法,一个 selectAll(返回 List)和另一个 selectById(只返回 Product)。不确定这是否也可以处理?你有没有机会做这样的事情?
    • 我添加了一个findAllProducts 方法。我认为这应该有效。您可以添加必要的网络资源...
    【解决方案2】:

    Spring 世界中有一个使用数据库路由器的概念(参考:https://spring.io/blog/2007/01/23/dynamic-datasource-routing/)。

    您可能可以为传递给 DBI 的数据库连接工厂设置代理。然后,该代理将从本地线程(可能)获取凭据并返回真实连接,为您提供您所追求的内容,并且仍然允许您使用运行类型代理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      相关资源
      最近更新 更多