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
相关产品推荐
相关产品推荐

