2015-02-27 2 views
0

Я хочу, чтобы мой уровень Java говорил с моей БД, используя хранимые процедуры. Хранимые процедуры действуют как уровень совместимости, поэтому я могу запускать две разные версии приложения, ожидающие двух разных схем поверх одной базы данных.Orika mapping jdbc ResultSet Bean

Чтобы сделать это, я хотел использовать Orika для быстрой карты из набора результатов JDBC на мои бобы.

Я написал тестовый код до сих пор: @Test общественного недействительными testSelectAndMap() бросает исключение { Assert.assertNotNull (DataSource); попытка (кон Connection = dataSource.getConnection()) { попытка (Заявление 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 автоматически определяет имя свойства на бобе и дает его мне в выраж. Но это не говорит мне о типе. Это также не говорит мне, к чему я пытаюсь перейти. Мне просто нужно притвориться, что в этом случае целью является ResultSet.

  1. Как узнать тип выражения, в который я пытаюсь поместить данные? Если это String, я сделаю встроенный вызов привязки ResultSet.getString("expr") и скажу Orika, чтобы использовать java.lang.String. Если это Отметка я сделаю встроенное связывание вызова Resulset.getTimestamp("expr") и сказать Orika использовать Timestamp
  2. Как я знаю, что я пытаюсь карта от ResultSet к InternalTestPojo по сравнению, например, Map к InternalTestPojo?

ответ

1

Я думаю, что самый простой способ добиться того, что вам нужно сделать, - использовать построитель пользовательских классов, расширяющий значение по умолчанию, поэтому вы можете автоматически добавлять поля в свою карту классов, переопределяя методDefault.

Это простой пример использования аннотаций с Orika: https://gist.github.com/elaatifi/5212119

Вам не нужно использовать Reflection Вы можете использовать PropertyResolver искать все свойства InternalTestPojo, и для каждого из них строить счетчик часть porperty для ResultSet и добавьте его в карту классов.

Чтобы создать свойство counter counter, вы можете использовать Property.Builder. Метод геттера для свойства может быть заключен из типа.

Надеюсь, это поможет!

+1

У меня нет репутации, чтобы отметить ваш ответ как правильный. Мне удалось создать сопоставление с использованием пользовательской сборки карты классов и получить информацию о поле из PropertyResolver – dodtsair