ResultSetMetaData using MyBatis



如何使用MyBatis获取ResultSetMetaData。我不能使用INFORMATION_SCHEMA.columns,因为我有一个带有多个表的复杂动态查询联接。例如,我需要记录的数量(这个可以根据列表大小获得)、列列表和每列的数据类型。我浏览了很多,但没有正确的使用方法。

请用TypeHandler或其他一些小示例选项来建议获取ResultSetMetaData的正确方法?

我有两个场景。

  1. 场景1:

    My Query使用Abinitio QueryIt服务读取文件(它考虑类似于表的文件,可以使用SQL查询进行读取)。这些文件是从各种上行流接收的,而不是固定的列集。它可以是N个列和任何数据类型。一旦我的查询从文件中读取数据,它将被发送到UI,以在网格中显示,并根据用户视图的数据类型(Integer、Double、String、Date)进行格式化输出。为了构建网格模型,我需要知道列数和数据类型(用于格式化)。在我知道每列的列数和数据类型之前,我无法构建网格模型。我的映射器的返回类型将是List<Map<String, Object>>

  2. 场景2(针对不同的流程):与上述方法类似,查询从多个表中读取数据,而不是根据UI中的条件选择从文件中读取数据。这里的列数也是基于用户界面的选择而动态的。因此,我需要列的数量和每列的数据类型。返回类型与上述类型相同。

提前感谢。

对于复杂的查询,可以添加自定义映射器。我通常在单独的目录中创建扩展映射器,这样当您再次生成时它们就不会被替换。此外,这将所有自定义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);
}

您可以编写一个扩展BaseTypeHandler的自定义TypeHanlder,这样您就可以访问ResultSetMetaData。我以前写过这样一个处理程序,用于将Date转换为LocalDate。这有点像破解你的答案,因为映射器不会直接返回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

例如。如何从MyBatis查询返回可选

有用的MyBatis文档:

http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers

http://www.mybatis.org/mybatis-3/configuration.html#objectFactory

相关内容

  • 没有找到相关文章

最新更新