Orika 映射 jdbc 结果集 Bean

Orika mapping jdbc ResultSet Bean

我希望我的 Java 层使用存储过程与我的数据库对话。存储过程充当兼容层,因此我可以 运行 两个不同版本的应用程序,期望在同一数据库上有两个不同的模式。

为此,我想使用 Orika 快速将 JDBC 结果集映射到我的 Beans 上。

到目前为止我已经写了这个测试代码: @测试 public void testSelectAndMap() 抛出异常{ Assert.assertNotNull(数据源); 尝试(连接控制 = dataSource.getConnection()){ try(语句stmt = con.createStatement()) {

            try (ResultSet result = stmt.executeQuery("select 1 as internalTestPojoId, CURRENT_TIMESTAMP as now")) {
                result.next();
                MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
                mapperFactory.classMap(ResultSet.class, InternalTestPojo.class)
                        .byDefault()
                        .field("internalTestPojoId:{getInt('internalTestPojoId')|getInt('internalTestPojoId')|type=" + int.class.getName() + "}", "internalTestPojoId")
                        .field("now:{getTimestamp('now')|getTimestamp('now')|type=" + Timestamp.class.getName() + "}", "now")
                        .register();
                MapperFacade mapper = mapperFactory.getMapperFacade();
                InternalTestPojo pojo = mapper.map(result, InternalTestPojo.class);
                Assert.assertEquals(pojo.internalTestPojoId, 1);
                Assert.assertEquals(pojo.now, new Timestamp(new Date().getTime() / 1000 * 1000));

            }

这很好用,速度很快,但与我自己将 ResultSet 编写到 Bean 代码相比,我编写代码所花费的时间并没有减少那么多。但是,如果我可以自动生成映射,它会节省我很多时间。

我看了IntrospectorPropertyResolver。我写了这样的代码:

protected Property getProperty(java.lang.reflect.Type type, String expr,
                               boolean isNestedLookup, Property owner) throws MappingException {
    Property property = null;
    try {
        property = super.getProperty(type, expr, isNestedLookup, null);
    } catch (MappingException e) {
        try {
            property = super.resolveInlineProperty(type,
                    expr + ":{getInt('" + expr + "')|getInt('" + expr + "')|type=" + int.class);

        } catch (MappingException subE) {
            throw e; // throw the original exception
        }
    }
    return property;
}

这很好,Orika 自动确定 bean 上的 属性 名称并在 expr 中将其提供给我。但它没有告诉我类型。它也没有告诉我我试图映射到什么。我只需要假装在这种情况下目标是一个 ResultSet。

  1. 我如何知道我试图将数据放入的 expr 的类型?如果它是 String,我将进行内联绑定调用 ResultSet.getString("expr") 并告诉 Orika 使用 java.lang.String。如果它是时间戳,我将进行内联绑定调用 Resulset.getTimestamp("expr") 并告诉 Orika 使用 Timestamp
  2. 我怎么知道我正在尝试从 ResultSet 映射到 InternalTestPojo 而不是从 Map 映射到 InternalTestPojo

我认为实现您要做的事情的最简单方法是使用自定义 class 地图生成器扩展默认地图生成器,因此您可以通过覆盖 byDefault 自动将字段添加到您的 class 地图方法。

这是一个将注释与 Orika 一起使用的简单示例:https://gist.github.com/elaatifi/5212119

您无需使用反射,您可以使用 PropertyResolver 查找 InternalTestPojo 的所有属性,并为每个属性构建 ResultSet 的对应部分属性并将其添加到 class 映射。

要构建对应部分 属性,您可以使用 Property.Builder。 对于属性的getter方法可以从类型上推断出来。

希望对您有所帮助!