当前位置: 首页 > news >正文

java处理pgsql的text[]类型数据问题

背景

公司要求使用磐维数据库,于是去了解了这个是基于PostgreSQL构建的,在使用时有场景一条图片数据中可以投放到不同的页面,由于简化设计就放在数组中,于是使用了text[]类型存储;

表结构

#这是一个简化版表结构(id自增一般设置serial4=自增int4类型)
CREATE TABLE "public"."t_expand" (
  "id" int4 NOT NULL DEFAULT nextval('t_expand_id_seq'::regclass),
  "role_id" int4 DEFAULT NULL,
  "expand_role_ids" text[] COLLATE "pg_catalog"."default" DEFAULT NULL,
  "environment" varchar(64) COLLATE "pg_catalog"."default" DEFAULT NULL::character varying,
  "remark" varchar(255) COLLATE "pg_catalog"."default" DEFAULT NULL::character varying
);

实体类

@Data
public class TExpand implements Serializable {
    /**
     * 主键id
     */
    private Integer id;

    /**
     * 角色id
     */
    private Integer roleId;

    /**
     * 外部角色id绑定
     */
    private List<String> expandRoleIds;

    /**
     * 环境标识
     */
    private String environment;

    /**
     * 备注
     */
    private String remark;
    
    private static final long serialVersionUID = 1L;
}

mybatis 配置

注意:text[]不能直接对应java的List<String>类型,故需要自己转换:
public class TextListTypeHandler extends BaseTypeHandler<List<String>> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
        // 将 List<String> 转换为 PostgreSQL text[] 类型
        Array array = ps.getConnection().createArrayOf("text", parameter.toArray());
        ps.setArray(i, array);
    }

    @Override
    public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return toList(rs.getArray(columnName));
    }

    @Override
    public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return toList(rs.getArray(columnIndex));
    }

    @Override
    public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return toList(cs.getArray(columnIndex));
    }

    private List<String> toList(Array array) throws SQLException {
        if (array == null) {
            return null;
        }
        return Arrays.asList((String[]) array.getArray());
    }
}
    <resultMap id="BaseResultMap" type="com.domain.TExpand">
            <result property="id" column="id" jdbcType="INTEGER"/>
            <result property="roleId" column="role_id" jdbcType="INTEGER"/>
            <result property="expandRoleIds" column="expand_role_ids" jdbcType="ARRAY" javaType="java.util.List" typeHandler="com.TextListTypeHandler"/>
            <result property="environment" column="environment" jdbcType="VARCHAR"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
    </resultMap>

#在使用此参数查询时也要指定类型,否则无法匹配类型
    <select id="queryAllByExpandRoleIds" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from t_expand
        where expand_role_ids <![CDATA[&&]]> ARRAY[
        <foreach item="role" collection="roles" separator=",">
            #{role}::text
        </foreach>
            ]::text[]
    </select>
#插入修改也是要匹配
    <insert id="insertSelective">
        insert into t_expand
        <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="id != null">id,</if>
                <if test="roleId != null">role_id,</if>
                <if test="expandRoleIds != null">expand_role_ids,</if>
                <if test="environment != null">environment,</if>
                <if test="remark != null">remark,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
                <if test="id != null">#{id,jdbcType=INTEGER},</if>
                <if test="roleId != null">#{roleId,jdbcType=INTEGER},</if>
                <if test="expandRoleIds != null">#{expandRoleIds,jdbcType=ARRAY,typeHandler=com.TextListTypeHandler},</if>
                <if test="environment != null">#{environment,jdbcType=VARCHAR},</if>
                <if test="remark != null">#{remark,jdbcType=VARCHAR},</if>
        </trim>
    </insert>

常见问题

IllegalArgumentException: invalid comparison: java.util.ArrayList and java.lang.string] with root ca
<if test="touchCode != null and touchCode != ''" >
                and s.touch_code <![CDATA[&&]]> ARRAY[
                <foreach item="code" collection="touchCode" separator=",">
                    #{code}::text
                </foreach>
                ]::text[]
</if>
这里and touchCode != ''会影响传参应当去掉或者使用size函数
<if test="touchCode != null">
或者 
<if test="touchCode != null and touchCode.size>0"> 

相关文章:

  • window patch按块分割矩阵
  • 大脑网络与智力:基于图神经网络的静息态fMRI数据分析方法|文献速递-医学影像人工智能进展
  • HashMap详解+简单手写实现(哈希表)
  • 深度学习机器学习:常用激活函数(activation function)详解
  • Qt Creator 5.0.2 (Community)用久了突然变得很卡
  • Kafka分区管理大师指南:扩容、均衡、迁移与限流全解析
  • Flutter 实现 iOS 小组件与主 App 的通信
  • make命令学习
  • 知识拓展:设计模式之装饰器模式
  • 传输层协议TCP ( 下 )
  • springboot集成zookeeper的增删改查、节点监听、分布式读写锁、分布式计数器
  • UEFI PI PEI(3. PEI Foundation/PEI Dispatcher)
  • 蓝桥与力扣刷题(108 将有序数组转换成二叉搜索树)
  • 解锁豆瓣高清海报(三)从深度爬虫到URL构造,实现极速下载
  • 网站地址栏怎么变成HTTPS开头?
  • windows平台上 oracle简单操作手册
  • 【SQL server】存储过程模板
  • List对象进行排序
  • 如何提升谷歌SEO排名?
  • Springboot RabbitMQ 消费失败消息清洗与重试机制
  • 如何用域名访问网站/牛推网
  • 女生做网站后期维护工作好吗/品牌seo是什么意思
  • wordpress页面diy/抖音seo推广外包公司好做吗
  • wordpress制作的网站/湖南seo推广
  • 地方门户网站备案/网站seo入门基础教程书籍
  • 用html5做的静态网站网站/免费发广告帖子的网站