You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis是否支持PostgreSQL网络地址类型?求自定义类型处理器方案

处理MyBatis中PostgreSQL网络地址类型的自定义类型处理器

MyBatis默认确实没有提供PostgreSQL网络地址类型(如inet、cidr)的内置支持,不过自定义类型处理器来适配这些类型并不复杂,以下是具体的实现方案和建议:

1. 依赖准备

确保项目中引入了PostgreSQL JDBC驱动,比如Maven依赖:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>你的驱动版本</version>
</dependency>

2. 编写自定义类型处理器

以处理inet类型映射到Java的InetAddress为例,实现MyBatis的BaseTypeHandler:

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgresql.util.PGobject;

import java.net.InetAddress;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class InetAddressTypeHandler extends BaseTypeHandler<InetAddress> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, InetAddress parameter, JdbcType jdbcType) throws SQLException {
        PGobject pgInet = new PGobject();
        pgInet.setType("inet");
        pgInet.setValue(parameter.getHostAddress());
        ps.setObject(i, pgInet);
    }

    @Override
    public InetAddress getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return parseInet(rs.getString(columnName));
    }

    @Override
    public InetAddress getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return parseInet(rs.getString(columnIndex));
    }

    @Override
    public InetAddress getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return parseInet(cs.getString(columnIndex));
    }

    private InetAddress parseInet(String value) throws SQLException {
        if (value == null || value.isBlank()) {
            return null;
        }
        try {
            return InetAddress.getByName(value);
        } catch (Exception e) {
            throw new SQLException("解析inet地址失败: " + value, e);
        }
    }
}

如果需要处理cidr类型,只需将pgInet.setType("inet")改为pgInet.setType("cidr"),也可以使用PostgreSQL驱动提供的org.postgresql.net.PGCidr类来封装数据,简化解析逻辑。

3. 注册类型处理器

有两种方式注册自定义处理器:

  • 全局注册:在MyBatis核心配置文件中添加:
<typeHandlers>
    <typeHandler handler="com.yourpackage.InetAddressTypeHandler"/>
</typeHandlers>
  • 局部指定:在Mapper接口的注解中直接指定,比如:
@Result(property = "ip", column = "ip_address", typeHandler = InetAddressTypeHandler.class)

4. 使用示例

实体类中定义对应字段:

public class Device {
    private Long id;
    private InetAddress ip;
    // getter、setter方法
}

Mapper接口中的CRUD操作:

@Insert("INSERT INTO device(ip) VALUES (#{ip, typeHandler=com.yourpackage.InetAddressTypeHandler})")
int addDevice(Device device);

@Select("SELECT id, ip FROM device WHERE id = #{id}")
@Results({
    @Result(property = "id", column = "id"),
    @Result(property = "ip", column = "ip", typeHandler = InetAddressTypeHandler.class)
})
Device getDeviceById(Long id);

额外建议

  • 若需支持多种网络类型,可以编写一个通用的类型处理器,通过判断字段类型动态切换处理逻辑。
  • 测试时覆盖空值、IPv4、IPv6、带子网掩码的inet地址等场景,确保解析和写入正常。
  • 使用较新版本的PostgreSQL JDBC驱动,避免旧版本中存在的类型兼容问题。

内容的提问来源于stack exchange,提问作者lmk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 04:28:23