MyBaitsPlus操作PgSQL数组字段

这篇博客介绍了如何在Java中使用MyBatisPlus操作PostgreSQL数据库的数组字段,包括创建带数组字段的表、编写SQL查询、处理自定义类型以及在实体类中配置。还展示了自定义ArrayTypeHandler的实现,用于设置和获取数组参数,并给出了Postman请求和数据库中的实际效果。

非商业用途,纯属个人记录,内容参考了多个大神的文章,侵权删!

本来以为PgSQL的数组字段跟MySQL一样,没想到这么复杂。

首先创建一个带数组字段的表格,navicat里面貌似没找到对应的创建方式,只能SQL语句创建。

create table data_catch_record(id serial primary key, netcage_list int4[]); 

netcage_list字段就是一个数组字段,但是navicat显示的是int8,不过下面纬度为1。

记录一个我需要的SQL查询语句,查询数组中是否有某个元素。

SELECT * FROM data_catch_record WHERE 2 = any(netcage_list)

我用的是IDEA,pom.xml 文件中mybaits-plus 版本用的是3.4.0  

之前用的3.1.0实体类无法自定义字段,找了半天错误。

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.0</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.0</version>
</dependency>

然后刷新一下引用,在实体类 @TableName注解中增加  autoResultMap = true 

在对应字段@TableField注解中增加自定义类型

package com.hywx.dao.entity;



import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.hywx.config.ArrayTypeHandler;
import com.hywx.util.TimeUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.ibatis.type.JdbcType;

import java.io.Serializable;
import java.util.Date;

@Data
@TableName(value = "data_catch_record",  autoResultMap = true )
@ApiModel(value="DataCatchRecord对象", description="捕捞记录表")
public class DataCatchRecord implements Serializable {

    private static final Long serialVersionUID = 1L;

    @ApiModelProperty(value = "数据id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id ;

    @ApiModelProperty(value = "捕捞网箱集合")
    @TableField(value = "netcage_list", jdbcType = JdbcType.ARRAY,typeHandler = ArrayTypeHandler.class)
    private Integer[] netcageList;

    @ApiModelProperty(value = "捕捞时间")
    @TableField("time")
    @JsonFormat(shape = JsonFormat.Shape.STRING,pattern = TimeUtil.FORMAT_STR_LONG,timezone = TimeUtil.TIMEZONE)
    private Date time;

    @ApiModelProperty(value = "捕捞种类")
    @TableField("name")
    private String name;

    @ApiModelProperty(value = "捕捞重量")
    @TableField("weight")
    private Double weight;

    @ApiModelProperty(value = "捕捞区域id")
    @TableField("ranch_area_id")
    private Integer ranchAreaId;

}

 创建一个自定义类型类ArrayTypeHandler

package com.hywx.config;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;

/**
 * @author: Admin
 * @date: 2021/12/24
 * @description:
 */
public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
    private static final Logger LOGGER = LoggerFactory.getLogger(ArrayTypeHandler.class);

    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());
        }

        // 这2行是关键的代码,创建array,然后ps.setarray(i, array)就可以了
        Array array = ps.getConnection().createArrayOf(typename, parameter);
        ps.setArray(i, array);
    }

    @Override
    public Object[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return getArray(rs.getArray(columnName));
    }


    @Override
    public Object[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return getArray(rs.getArray(columnIndex));
    }


    @Override
    public Object[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getArray(cs.getArray(columnIndex));
    }

    private Object[] getArray(Array array) {

        if (array == null) {
            return null;
        }

        try {
            return (Object[]) array.getArray();
        } catch (SQLException e) {
            LOGGER.error("ArrayTypeHandler getArray SQLException",e);
        }
        return null;

    }
}

然后就可以了。操作的时候用MyBatisPlus自带的方法就行。

 public Integer addCatchRecord(DataCatchRecord dataCatchRecord){
        return catchRecordMapper.insert(dataCatchRecord);
 }

postman传入的样子是这样的。

 插入后数据库里面的样子是这样的。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值