Java Mybatis 接收postgreSQL中array_agg的结果
Posted 洛阳泰山
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Mybatis 接收postgreSQL中array_agg的结果相关的知识,希望对你有一定的参考价值。
问题描述
因为项目中业务需求,postgreSQL使用了group by与array_agg将varchar或者bigint类型变为一个数组,这样多行结果就变为了一行结果,但是mybatis的jdbcType没有对应的数据类型。如果用string类型去接收,还得用java代码处理成数组,返回给前端有点麻烦。
array_agg介绍
array_agg函数 和string_agg 函数类似,最主要的区别为返回的类型为数组,数组数据类型同输入数据类型一致,array_agg函数支持两种语法。
解决
方式一:
通过设置mybatis xml配置和创建自定义数据类型处理类解决。
教程
maper类 以mybatis-plus常规分页写法示例
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.standardmodel.mineupdown.dto.AdvancedDetectionTunnelDTO;
import org.springblade.standardmodel.mineupdown.entity.AdvancedDetection;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface AdvancedDetectionMapper extends BaseMapper<AdvancedDetection>
List<AdvancedDetectionTunnelDTO> tunnelPage(IPage page, String tunnelName);
mapper.xml文件中设置typeHander
<resultMap id="BaseResultMap" type="org.springblade.standardmodel.mineupdown.dto.AdvancedDetectionTunnelDTO">
<result column="ids" jdbcType="ARRAY" property="ids" typeHandler="org.springblade.standardmodel.common.handler.ArrayTypeHandler"/>
</resultMap>
<select id="tunnelPage" resultMap="BaseResultMap">
SELECT
ids,
tunnel_id,
tunnel_name,
anomalous_region_num
FROM
(
SELECT
"array_agg" ( ID ) ids,
tunnel_id,
tunnel_name,
"sum" ( anomalous_region_num ) anomalous_region_num
FROM
(
SELECT
ad.ID,
ad.tunnel_id,
tb.hd_hdmc AS tunnel_name,
( SELECT COUNT ( 1 ) FROM gis_standard_abnormal_area aa WHERE aa.detection_id = ad.ID ) AS anomalous_region_num
FROM
gis_standard_advanced_detection ad
LEFT JOIN gis_standard_tunnel_base tb ON ad.tunnel_id = tb.ID
) T
GROUP BY
T.tunnel_id,
T.tunnel_name
) r
<where>
<if test="tunnelName!=null">
and r.tunnel_name like CONCAT('%',#tunnelName,'%')
</if>
</where>
</select>
自定义数组类型处理类 ArrayTypeHandler
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeException;
import java.sql.*;
public class ArrayTypeHandler extends BaseTypeHandler<Object[]>
private static final String TYPE_NAME_VARCHAR = "varchar";
private static final String TYPE_NAME_INTEGER = "integer";
private static final String TYPE_NAME_BOOLEAN = "boolean";
private static final String TYPE_NAME_NUMERIC = "numeric";
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType) throws SQLException
String typeName = null;
if (parameter instanceof Integer[])
typeName = TYPE_NAME_INTEGER;
else if (parameter instanceof String[])
typeName = TYPE_NAME_VARCHAR;
else if (parameter instanceof Boolean[])
typeName = TYPE_NAME_BOOLEAN;
else if (parameter instanceof Double[])
typeName = TYPE_NAME_NUMERIC;
if (typeName == null)
throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName());
Connection conn = ps.getConnection();
Array array = conn.createArrayOf(typeName, parameter);
ps.setArray(i, array);
@Override
public Object[] getNullableResult(ResultSet resultSet, String s) throws SQLException
return getArray(resultSet.getArray(s));
@Override
public Object[] getNullableResult(ResultSet resultSet, int i) throws SQLException
return getArray(resultSet.getArray(i));
@Override
public Object[] getNullableResult(CallableStatement callableStatement, int i) throws SQLException
return getArray(callableStatement.getArray(i));
private Object[] getArray(Array array)
if (array == null)
return null;
try
return (Object[]) array.getArray();
catch (Exception e)
return null;
实体类返回对象AdvancedDetectionTunnelDTO
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author TARZAN
*/
@Data
public class AdvancedDetectionTunnelDTO
@ApiModelProperty("巷道名称")
private String tunnelName;
@ApiModelProperty("异常区域数")
private Integer anomalousRegionNum;
@ApiModelProperty("超前探id集合")
private Long[] ids;
方式二:
通过 mybatis-plus @TableField(typeHandler = ArrayTypeHandler.class) 注解
实体类返回对象AdvancedDetectionTunnelDTO
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.ibatis.type.ArrayTypeHandler;
/**
* @author TARZAN
*/
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class AdvancedDetectionTunnelDTO
@ApiModelProperty("巷道名称")
private String tunnelName;
@ApiModelProperty("异常区域数")
private Integer anomalousRegionNum;
@ApiModelProperty("超前探id集合")
@TableField(typeHandler = ArrayTypeHandler.class)
private Long[] ids;
注意事项:
需要用到两个注解才能生效
@TableName(autoResultMap = true)
@TableField(typeHandler = ArrayTypeHandler.class)
以上是关于Java Mybatis 接收postgreSQL中array_agg的结果的主要内容,如果未能解决你的问题,请参考以下文章
Mybatis调用PostgreSQL存储过程实现数组入参传递
SpringBoot:Mybatis整合PostgreSQL