如何使用MyBatis获得ResultSetMetaData
。我无法使用INFORMATION_SCHEMA.columns
,因为我有一个包含多个表的复杂动态查询联接。例如,我需要记录数(我可以根据列表大小获得该记录),列列表和每列的数据类型。我浏览了很多,却没有正确的使用方法。
请提出使用TypeHandler
或其他一些带有小示例的选项来获取ResultSetMetaData的正确方法吗?
我有2种情况。
方案1:
我的查询使用Abinitio QueryIt服务读取文件(它考虑与表相似的文件,并且可以使用SQL查询来读取)。这些文件是从各种上游接收的,而不是固定的一组列。它可以是N列数和任何数据类型。一旦我的查询从文件中读取了数据,它将被发送到UI以显示在Grid中,并具有基于数据类型(整数,双精度,字符串,日期)的格式化输出,以供用户查看。要构建Grid模型,我还需要知道列数和数据类型(用于格式化)。在我知道列数和每列的数据类型之前,我无法构建网格模型。我的映射器的返回类型为List<Map<String, Object>>
。
方案2(针对不同的过程):与上述方法类似,查询从多个表中读取数据,而不是根据从UI中选择的条件从文件中读取数据。在此,基于从UI的选择,网格的列数也是动态的。因此,我需要列数和每列的数据类型。返回类型与上面的类型相同。
谢谢。
答案 0 :(得分:0)
对于复杂的查询,您可以添加自定义映射器。我通常在单独的目录中创建扩展的映射器,因此在再次生成它们时不会被替换。另外,这会将所有自定义SQL保留在一起。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.company.core.app.db.mapper.custom.SomethingExtendedMapper">
<resultMap id="SomethingMap" type="com.company.core.app.db.Something">
<result column="ID" jdbcType="INTEGER" property="somethingId" />
<result column="LAST_CHANGE_DATE" jdbcType="DATE" property="lastChangeDate"
...
</resultMap>
<select id="getSomething" resultMap="SomethingMap" parameterType="Integer">
select
*
from
something
join something else...
WHERE SOMETHING_ID = #{id}
</select>
</mapper>
然后这将是接口:
public interface SomethingExtendedMapper {
public List<Something> getSomething(@Param("id") Integer id);
}
答案 1 :(得分:0)
您可以编写扩展了TypeHanlder
的自定义BaseTypeHandler
,这将使您可以访问ResultSetMetaData
。我之前已经编写了这样的处理程序,可以将Date
转换为LocalDate
。这对您的答案有点hacker,因为映射器不会直接返回List<Map<String, Object>>
,但是这可能是您要返回的对象的属性。
@MappedTypes(LocalDate.class)
public class DbLocalDateTypeHandler extends BaseTypeHandler<LocalDate> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setDate(i, null);
} else {
ps.setDate(i, Date.valueOf(parameter));
}
}
@Override
public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException {
Date date = rs.getDate(columnName);
if (date != null) {
return date.toLocalDate();
}
return null;
}
@Override
public LocalDate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Date date = rs.getDate(columnIndex);
if (date != null) {
return date.toLocalDate();
}
return null;
}
@Override
public LocalDate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Date date = cs.getDate(columnIndex);
if (date != null) {
return date.toLocalDate();
}
return null;
}
}
然后在您的resultMap
中,您只需要引用该处理程序即可:
<result column="CREATE_DATE" jdbcType="DATE" property="createDate" typeHandler="com.company.core.framework.db.DbLocalDateTypeHandler"/>
最后,如果您不需要ResultSetMetaData
,可以考虑创建自定义ObjectFactory
。
例如 How to return an Optional from MyBatis query
有用的MyBatis文档:
http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers
http://www.mybatis.org/mybatis-3/configuration.html#objectFactory