abel533 / Mapper

Mybatis Common Mapper - Easy to use
https://mybatis.io
MIT License
7.34k stars 1.63k forks source link

返回类型必须是 Java POJO 吗?有没有可能返回 List<Map<String, Object>>,想结合 Mapper 提供的 Example 类来实现完全的动态 SQL 查询 #718

Open yunyexiansheng opened 4 years ago

yunyexiansheng commented 4 years ago

个人感觉 Example 组装各种动态条件很便利,想使用通用 Mapper 实现动态查询。表目前可以实现动态指定,字段也可以,只是发现返回类型必须是 POJO,因为返回字段的不确定性,所以很难写出 POJO。

@Data
@EqualsAndHashCode(callSuper = false)
public class DynamicTable extends HashMap<String, Object> implements IDynamicTableName {

    @Transient
    private String tableName;

    private String id;

    @Override
    public String getDynamicTableName() {
        return tableName;
    }

}

public interface DynamicMapper extends Mapper<DynamicTable> {
}

@RunWith(SpringRunner.class)
@SpringBootTest
public class TkMapperTest {
    @Autowired
    private DynamicMapper dynamicMapper;

    @Test
    public void test() {
        Condition condition = new Condition(DynamicTable.class);
        condition.setTableName("t_165759b0-96fc-47bf-be8a-60c1a40362c2");
        condition.selectProperties("id, object_id");

        Object r = dynamicMapper.selectByExample(condition);
        System.out.println(r);
    }
}

会报错,内容如下:

tk.mybatis.mapper.MapperException: 类 DynamicTable 不包含属性 'id, object_id',或该属性被@Transient注释!
760374564 commented 4 years ago

这个很简单的,POJO都实现了,返回Map的更容易实现了,直接将返回类型 List改成List<Map<String, Object>>即可,Provider实现跟ExampleProvider里面的一样, 可参考如下代码:

1、Mapper接口:

@tk.mybatis.mapper.annotation.RegisterMapper
public interface SelectMapByExampleMapper {

    /**
     * 根据Example条件进行查询
     *
     * @param example
     * @return
     */
    @SelectProvider(type = ExampleProvider.class, method = "dynamicSQL")
    List<Map<String, Object>> selectMapByExample(Example example);

}

2、ExampleProvider中 selectMapByExample 方法对应实现:

public String selectMapByExample(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder("SELECT ");
        if (isCheckExampleEntityClass()) {
            sql.append(SqlHelper.exampleCheck(entityClass));
        }
        sql.append("<if test=\"distinct\">distinct</if>");
        sql.append(SqlHelper.exampleSelectColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
        sql.append(SqlHelper.exampleWhereClause());
        sql.append(SqlHelper.exampleOrderBy(entityClass));
        sql.append(SqlHelper.exampleForUpdate());
        return sql.toString();
    }