SQL开发知识:MySQL读取JSON转换的方式
你可以自己将数据转换成Json String后插入,也可以选择使用工具,
而mybatis-plus就为此提供了非常简便的方式,
只需要在字段上加上 @TableField(typeHandler = XxxTypeHandler.class),
mybatis-plus就会自动帮你做转换,通用一般就两个:
com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler
com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler
例如
@Data@TableName(autoResultMap = true)
public class Department implements Serializable {
private static final long serialVersionUID = 203788572415896870L;
@TableField(typeHandler = FastjsonTypeHandler.class)
private List Integer userIds;
存在什么问题? 如果使用通用处理器,那对于基础类型以及对象来说没有什么问题。
但如果存储的字段类型是对象集合,那么当你取出来时,会发现集合中的对象都是JSONObject类型。
最常见的情况就拿出来进行遍历操作时,会抛出强转异常:
java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to
因为处理器帮你转换时,并不会存储你集合的泛型,所以统统都按照Object类型来转换了:
@Override
protected Object parse(String json) {
return JSON.parseObject(json, type);
例如下面这种形式的类:
@Data@TableName(autoResultMap = true)
public class Department implements Serializable {
private static final long serialVersionUID = 203788572415896870L;
@TableId(value = id , type = IdType.AUTO)
private Integer id;
@TableField(typeHandler = FastjsonTypeHandler.class)
private List User users;
@Data
public static class USer implements Serializable {
//
}
}
方式一:自定义处理器,自己做类型转换,这也是当前最普遍的方式,但是对于存在List字段的对象,还需要在XxxMapper.xml中进行resultMap配置
@MappedTypes({Object.class})@MappedJdbcTypes(JdbcType.VARCHAR)
public class ListFastJsonTypeHandler extends FastjsonTypeHandler {
private final Class ? extends Object type;
public ListFastJsonTypeHandler(Class ? type) {
super(type);
this.type = type;
}
/**
* 自己将json转换成list
* @param json
* @return
*/
@Override
protected Object parse(String json) {
return JSON.parseArray(json, this.type);
}
配置完成后,ListFastJsonTypeHandler就会将json转换成javaType对应的对象集合了
方式二:配置一个Mybatis插件,拦截ResultSetHandler,将返回结果进行处理。 这样的好处就是不用写自定义的处理器和在XxxMapper.xml中做配置,减少了工作
@Component@Intercepts({
@Signature(type = ResultSetHandler.class, method = handleResultSets , args = {Statement.class})
})
public class ResultSetInterceptor implements Interceptor {
/**
* json序列化规则
*/
private final SerializerFeature[] serializerFeatures = {
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteNullStringAsEmpty
};
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object proceed = invocation.proceed();
if (containJSONObject(proceed)) {
if (proceed instanceof Collection) {
return JSON.parseArray(JSON.toJSONString(proceed, serializerFeatures), ((Collection ? ) proceed).toArray()[0].getClass());
}
return JSON.parseObject(JSON.toJSONString(proceed, serializerFeatures), proceed.getClass());
}
// if (proceed instanceof Collection) {
// for (Object obj : ((Collection ? ) proceed)) {
// parseJSON2Object(obj, obj.getClass());
// }
// } else {
// parseJSON2Object(proceed, proceed.getClass());
// }
return proceed;
}
* 将返回数据中心的JSONObject对象转换成正常的对象
*
* @param obj
* @param typeClass
* @throws IllegalAccessException
* @throws ClassNotFoundException
private void parseJSON2Object(Object obj, Class ? typeClass) throws IllegalAccessException, ClassNotFoundException {
for (Field declaredField : typeClass.getDeclaredFields()) {
declaredField.setAccessible(true);
Object value = declaredField.get(obj);
if (isNullValueField(value)) {
continue;
Type genericType = declaredField.getGenericType();
String fieldClassName = genericType.getTypeName();
if (genericType instanceof ParameterizedType) {
fieldClassName = ((ParameterizedType) genericType).getActualTypeArguments()[0].getTypeName();
if (containJSONObject(value)) {
if (value instanceof Collection) {
declaredField.set(obj, JSON.parseArray(JSON.toJSONString(value, serializerFeatures), Class.forName(fieldClassName)));
} else {
declaredField.set(obj, JSON.parseObject(JSON.toJSONString(value, serializerFeatures), Class.forName(fieldClassName)));
}
* 判断是否跳过字段
* @param value
* @return
private Boolean isNullValueField(Object value) {
return null == value || .equals(String.valueOf(value).trim())
|| (value instanceof Collection ((Collection ? ) value).size() == 0);
* 判断值是否包含JSONObject对象
private boolean containJSONObject(Object value) throws IllegalAccessException {
if (isNullValueField(value)) {
return false;
if (value instanceof Collection) {
for (Object obj : (Collection ? ) value) {
if (obj instanceof JSONObject) {
return true;
if (obj instanceof Collection containJSONObject(obj)) {
for (Field declaredField : obj.getClass().getDeclaredFields()) {
declaredField.setAccessible(true);
Object fieldValue = declaredField.get(obj);
if (isNullValueField(fieldValue)) {
continue;
}
if (fieldValue instanceof JSONObject) {
return true;
if (fieldValue instanceof Collection containJSONObject(fieldValue)) {
}
return value instanceof JSONObject;
}
到此这篇关于MySQL读取JSON转换的文章就介绍到这了,更多相关MySQL读取JSON转换内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
我想要获取技术服务或软件
服务范围:MySQL、ORACLE、SQLSERVER、MongoDB、PostgreSQL 、程序问题
服务方式:远程服务、电话支持、现场服务,沟通指定方式服务
技术标签:数据恢复、安装配置、数据迁移、集群容灾、异常处理、其它问题
本站部分文章参考或来源于网络,如有侵权请联系站长。
数据库远程运维 SQL开发知识:MySQL读取JSON转换的方式
相关文章
- MySQL 大小写转换:一次性解决难题(mysql大小写设置)
- Mysql 中使用自增 SQL 语句实现自动编号(mysql自增sql语句)
- 轻松【退出】MySQL命令行(命令行退出mysql)
- MySQL变量使用技巧分享(mysql变量的使用)
- MySQL 池库:实现无缝连接(mysql池库)
- MySQL管理二进制数据实现自动化运行(mysql二进制数据)
- MySQL数据导出至本地:简单易学的步骤教程(mysql导出到本地)
- MySQL实现分页查询的SQL语句(mysql的分页sql)
- MySQL备份表:记录每一步SQL语句(mysql备份表sql)
- 使用 MySQL 外键优化 SQL 数据库设计(mysql外键sql)
- 快速掌握 MySQL 数据库入门技巧(数据库mysql入门)
- Maximizing MySQL Performance with Expert Tuning Techniques(mysql性能调优)
- 从MSSQL转换至MySQL的挑战与应对(mssql跨mysql)
- MySQL安装包:一步一步轻松下载(mysql安装包下载)
- MySQL主主备份实现数据高可用性(mysql中主主备份)
- MySQL中的错误1065解析SQL语句时出现的问题(mysql中1065)
- 50道MySQL经典题,挑战你的SQL技能(50道mysql经典题)
- 如何在 MySQL 中查询包含指定数据的行(mysql 中包含)
- MySQL实现加减乘除学习SQL数学运算的基本用法(mysql中加减乘除)
- 使用MySQL将一行数据转换为多行文本的方法(mysql一行转为多行)
- MySQL大全深入探索SQL关键字,不包含用法详解(mysql 不包含用法)
- MySQL下载及安装教程快速掌握MySql下载及安装方法,更高效地使用MySql数据库(mysql下载了在哪)
- MySQL限制禁止重复索引设计(mysql不能重复索引)
- 为什么MySQL不推荐存储过程(mysql不推荐存储过程)