如何使用MyBatis获取ResultSetMetaData
。我不能使用INFORMATION_SCHEMA.columns
,因为我有一个带有多个表的复杂动态查询联接。例如,我需要记录的数量(这个可以根据列表大小获得)、列列表和每列的数据类型。我浏览了很多,但没有正确的使用方法。
请用TypeHandler
或其他一些小示例选项来建议获取ResultSetMetaData的正确方法?
我有两个场景。
-
场景1:
My Query使用Abinitio QueryIt服务读取文件(它考虑类似于表的文件,可以使用SQL查询进行读取)。这些文件是从各种上行流接收的,而不是固定的列集。它可以是N个列和任何数据类型。一旦我的查询从文件中读取数据,它将被发送到UI,以在网格中显示,并根据用户视图的数据类型(Integer、Double、String、Date)进行格式化输出。为了构建网格模型,我需要知道列数和数据类型(用于格式化)。在我知道每列的列数和数据类型之前,我无法构建网格模型。我的映射器的返回类型将是
List<Map<String, Object>>
。 -
场景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