В MyBatis, как указать тип результата для SelectProvider

Это мой первый пост с использованием моего плохого английского...

Я использую MyBatis3.0

В запросе я использовал SqlBuilder со следующим методом:

public class DataStatisticSqlBuilder extends SqlBuilder{ 

public String getDataQtyListSql(Map<String, Object> map){

и интерфейс картографа следующим образом:

public interface DataStatisticMapper {

@SelectProvider(type=DataStatisticSqlBuilder.class, method="getDataQtyListSql")

public List<Map<String, Object>> getDataQtyList(@Param("groups")
List<DataStatisticSqlBuilder.Group> groups, @Param("quatity") Integer quatity, @Param("struct") Struct struct); 
}

когда я позвонил

session.getMapper(DataStatisticMapper.class).getDataQtyList(...some parameters)

я получил следующий вывод результата в консоли:

<==    Columns: PROJECT, PRJ_COUNT, TAR_COUNT, SITE_COUNT, PARAM_COUNT
<==        Row: project A, 1, 1, 0, 0 
<==        Row: project B, 1, 1, 0, 0

Основываясь на приведенном выше выводе, ожидаемым результатом должен быть список [Map, Map, ...], но фактический результат — [null, null]. Кажется, результат не отображается в HashMap. Как установить для этого запроса тип результата HashMap?

Возможно, используйте какие-то аннотации, но я их не нашел.

Большое спасибо.


person Zys    schedule 20.08.2011    source источник


Ответы (1)


Я получил то же самое [null, null], пытаясь обработать некоторые динамически сгенерированные sql. В руководстве mybatis упоминается SqlBuilder, но не предлагается, как использовать sql. Я думаю, что вашу проблему можно решить, добавив аннотацию @Results и @Result. Это должно работать, если столбцы результатов всегда одинаковы, см., например, в конце пример @Results

При моем использовании я не буду знать, какие столбцы есть, поэтому вот что я в итоге сделал.

В моем XML-файле картографа:

  <update id="executeUpdate">
    ${stmt}
  </update>

  <select id="executeQuery" resultType="java.util.Map">
    ${stmt}
  </select>

${} вместо #{} вставит строку как есть и не будет рассматривать ее как jdbc? параметр. Это ключ к этому решению. В вашем случае это будет sql, возвращаемый @SelectProvider, и вы должны добавить @Param("stmt") для передачи фактического sql для запуска.

В интерфейсе mybatis, соответствующем файлу xml:

void executeUpdate(DynamicSqlDao.ParameterObject po);
List<Map<String,Object>> executeQuery(DynamicSqlDao.ParameterObject po);

ParameterObject — это простой bean-компонент:

@Data
public class ParameterObject
{
    String stmt;
    Map<String,Object> param;
}

(@Данные взяты из Project Lombok и генерируют геттеры/сеттеры)

Теперь я могу назвать свой интерфейс «дао» следующим образом:

Map<String,Object> pmap = new HashMap<String,Object>();
pmap.put("apa", "banan");
ParameterObject po = new ParameterObject();
po.stmt = stmt;
po.param = pmap;
List<Map<String,Object>> result = dao.executeQuery(po);

ParameterObject мог быть просто Map с зарезервированным именем для инструкции sql. Теперь, когда я опубликовал это, может кто-нибудь еще опубликовать более элегантное решение... :)

person Migrus    schedule 25.09.2011