使用 Mybatis 的 TypeHandler 存取 Postgresql jsonb 类型
文章目录
- 使用 TypeHandler 存取 Postgresql jsonb 类型
- 常见错误
- column "" is of type jsonb but expression is of type character varying
使用 TypeHandler 存取 Postgresql jsonb 类型
首先在数据库表中定义 jsonb 类型:
create table tb_user_info
(
id varchar(36) not null,
user_info jsonb,
user_list jsonb,
user_ids varchar(36)[],
create_time timestamp not null default now(), -- 创建时间
constraint pk_tb_user_info primary key (id)
);
使用 @TableName
标识实体类对应的表:
具体内容参考 MybatisPlus注解 章节
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import org.apache.ibatis.type.ArrayTypeHandler;
import org.apache.ibatis.type.JdbcType;
@TableName(value = "tb_user_info", autoResultMap = true)
public class AlarmRuleEntity {
@TableField("id")
private String id;
@TableField("user_info")
private String userInfo ;
@TableField(value = "user_ids", jdbcType = JdbcType.ARRAY, typeHandler = ArrayTypeHandler.class)
private String userIds ;
@TableField(value = "user_list", typeHandler = JacksonTypeHandler.class)
private List<UserInfo> userList;
}
@TableName
中的 autoResultMap = true
必须开启, @TableField
中的 jdbcType = JdbcType.ARRAY
用于指定数组类型,而typeHandler = ArrayTypeHandler.class
中的类则是自定义类型处理器。
UserInfo 如下:
/**
* 用户类型
*/
public class UserInfo {
/**
* 用户id
*/
private String userId;
/**
* 用户名
*/
private String userName;
}
常见错误
column “” is of type jsonb but expression is of type character varying
解决办法:
在 JDBC URL参数中加入:stringtype=unspecified
,例如:
jdbc:postgresql://xxxxxxx:xxxx/db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&stringtype=unspecified
官方对 stringtype 参数的解释:
stringtype : String
Specify the type to use when binding PreparedStatement parameters set via setString(). If stringtype is set to VARCHAR (the default), such parameters will be sent to the server as varchar parameters. If stringtype is set to unspecified, parameters will be sent to the server as untyped values, and the server will attempt to infer an appropriate type. This is useful if you have an existing application that uses setString() to set parameters that are actually some other type, such as integers, and you are unable to change the application to use an appropriate method such as setInt().
当 stringtype=unspecified
时,statement.setString()
方法的参数将以未知的类型发送给Postgresql 数据库,由数据库根据表中字段的类型进行推定和自动转换。