MybatisPlus拼接SQL,PostgreSQL 数组查询和写入

本文讲述了在MybatisPlus中如何处理PostgreSQL的数组查询,通过ListStrTypeHandler类型处理器,将查询结果转换为List并避免SQL拼接时的双引号问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MybatisPlus拼接SQL,PostgreSQL 数组查询

PostgreSQL 查询的时候,对数组元素进行匹配,这块调了一下午,有点坑,MybatisPlus对于拼接SQL默认前后加了双引号,我怀疑是这样的,凭经验来看,我没有进一步追查源码(懒得追),这样写比较好。

List<String> fieldSql = Lists.newArrayList();
List<String> valueSql = Lists.newArrayList();
for (int i = 0; i < planQueryRequest.getFeatureType().size(); i++) {
    fieldSql.add("{" + i + "}");
    valueSql.add(planQueryRequest.getFeatureType().get(i).toString());
}
queryWrapper.apply("feature_type_array @> ARRAY[" +
		//列表转string,用英文逗号","拼接
        StringSplitUtils.join(fieldSql, ",") +
        "]", valueSql.stream().toArray(String[]::new));

写入代码

Entity字段标明Array

@TableField(value = "feature_type_array",typeHandler = ListStrTypeHandler.class,jdbcType = JdbcType.ARRAY)
private List<String> featureTypeArray;

TypeHandler

public class ListStrTypeHandler extends BaseTypeHandler<List<String>> {

    private static final Logger LOGGER = LoggerFactory.getLogger(ListStrTypeHandler.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, List<String> 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());
//        }

        if (parameter != null && !parameter.isEmpty()) {

            // 这2行是关键的代码,创建array,然后ps.setarray(i, array)就可以了
            Array array = ps.getConnection().createArrayOf(TYPE_NAME_VARCHAR, parameter.stream().toArray(String[]::new));
            ps.setArray(i, array);
        }

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

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


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


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

    private List<String> converList(Array array){
        if (array == null) {
            return null;
        }

        try {
            if (array.getArray() == null) {
                return null;
            }
            Object[] array1 = (Object[]) array.getArray();
            List<Object> objects = Arrays.asList(array1);
            return objects.stream().filter(Objects::nonNull).map(Objects::toString).collect(Collectors.toList());
        } catch (SQLException e) {
            LOGGER.error("ArrayTypeHandler getArray SQLException",e);
        }
        return null;
    }
}

这种写法,查询返回的时候,可以直接用List接收返回。

你可以使用 Python 中的 `psycopg2` 库 `mysql-connector-python` 库来连接 PostgreSQL MySQL 数据库,然后通过查询 PostgreSQL 数据库并将查询结果写入到 MySQL 数据库中。 以下是一个示例代码: ```python import psycopg2 import mysql.connector import pandas as pd # 连接 PostgreSQL 数据库 pg_conn = psycopg2.connect( host="your_postgres_host", database="your_postgres_db", user="your_postgres_user", password="your_postgres_password" ) # 连接 MySQL 数据库 mysql_conn = mysql.connector.connect( host="your_mysql_host", database="your_mysql_db", user="your_mysql_user", password="your_mysql_password" ) # 查询 PostgreSQL 数据库 pg_cursor = pg_conn.cursor() pg_cursor.execute("SELECT * FROM your_postgres_table") pg_results = pg_cursor.fetchall() # 将查询结果转换为 pandas DataFrame pg_df = pd.DataFrame(pg_results, columns=[desc[0] for desc in pg_cursor.description]) # 将查询结果写入 MySQL 数据库 mysql_cursor = mysql_conn.cursor() mysql_cursor.execute("DROP TABLE IF EXISTS your_mysql_table") mysql_cursor.execute("CREATE TABLE your_mysql_table (column1 datatype1, column2 datatype2, ...)") for row in pg_df.itertuples(index=False): mysql_cursor.execute("INSERT INTO your_mysql_table VALUES ({})".format(",".join(["%s"] * len(row))), row) # 提交事务并关闭连接 mysql_conn.commit() mysql_conn.close() pg_cursor.close() pg_conn.close() ``` 在这个示例代码中,我们首先分别连接 PostgreSQL MySQL 数据库,然后通过 `psycopg2` 库查询 PostgreSQL 数据库中的数据,并将查询结果转换为 pandas DataFrame。最后,我们通过 `mysql-connector-python` 库连接 MySQL 数据库,创建一个新的表格,并将查询结果写入到该表格中。 需要注意的是,在将查询结果写入 MySQL 数据库时,我们使用了 `itertuples()` 函数来逐行遍历 DataFrame,并使用 `execute()` 函数执行插入操作。在插入操作中,我们使用了 `%s` 占位符来表示插入值的位置,并使用 `join()` 函数将插入值拼接成一个字符串。这种写入方式可以避免 SQL 注入等安全问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值