当前位置: 首页 > news >正文

jfinal 支持mysql的json字段类型解决方案

目前使用的jfinal版本是4.2,mysql 版本是5.7,jar驱动版本mysql-connector-java-5.1.38.jar。默认对json类型的处理是当做字符串处理。即映射到BaseModel中对应的字段类型是String。如果希望实现映射到BaseModel中对应字段类型是JSON,则需要自行处理。解决方案如下:

思路:

  1. 确定射到BaseModel中对应的字段类型。这里我用的是com.alibaba.fastjson.JSON,这个可以根据项目需要定义。确定后就统一使用该类型映射json字段。
  2. 自动生成的BaseModel类映射json字段改为工具com.alibaba.fastjson.JSON。默认json字段生成的映射的类型是String。需要调整代码生成工具。
  3. 解决查询结果封装到Model对象时,映射正确的类型。
  4. 解决查询结果封装到Record对象时,映射正确的类型。
  5. 解决请求参数中json字符串封装到Model对象时,映射正确的类型。
  6. 解决执行保存或者更新sql时,com.alibaba.fastjson.JSON格式数据进行处理,保证sql顺利执行。

具体修改方案:

  1. 确定射到BaseModel中对应的字段类型。
 com.alibaba.fastjson.JSON
  1. 调整代码生成工具。
    这个需要分析源码,这里指贴出关键点。cm.javaType获取到映射的java类名称。
for (int i=1; i<=rsmd.getColumnCount(); i++) {ColumnMeta cm = new ColumnMeta();cm.name = rsmd.getColumnName(i);String typeStr = null;if("JSON".equals(rsmd.getColumnTypeName(i))) {typeStr = "com.alibaba.fastjson.JSON";}if (typeStr == null) {String colClassName = rsmd.getColumnClassName(i);typeStr = typeMapping.getType(colClassName);}if (typeStr == null) {int type = rsmd.getColumnType(i);if (type == Types.BINARY || type == Types.VARBINARY || type == Types.LONGVARBINARY || type == Types.BLOB) {typeStr = "byte[]";} else if (type == Types.CLOB || type == Types.NCLOB) {typeStr = "java.lang.String";} else {typeStr = "java.lang.String";}}cm.javaType = typeStr;
  1. 解决查询结果封装到Model对象时,映射正确的类型。
    修改com.jfinal.plugin.activerecord.ModelBuilder类。
    在这里插入图片描述在这里插入图片描述
public class ModelBuilder {private static final Logger logger = Logger.getLogger("");public static final ModelBuilder me = new ModelBuilder();public final static int JSON             =  2200;@SuppressWarnings({"rawtypes", "unchecked"})public <T> List<T> build(ResultSet rs, Class<? extends Model> modelClass) throws SQLException, ReflectiveOperationException, ParseException {List<T> result = new ArrayList<T>();ResultSetMetaData rsmd = rs.getMetaData();int columnCount = rsmd.getColumnCount();String[] labelNames = new String[columnCount + 1];int[] types = new int[columnCount + 1];buildLabelNamesAndTypes(rsmd, labelNames, types);while (rs.next()) {Model<?> ar = modelClass.newInstance();Map<String, Object> attrs = ar._getAttrs();for (int i=1; i<=columnCount; i++) {Object value;if (types[i] < Types.BLOB) {value = rs.getObject(i);} else {if (types[i] == Types.CLOB) {value = handleClob(rs.getClob(i));} else if (types[i] == Types.NCLOB) {value = handleClob(rs.getNClob(i));} else if (types[i] == Types.BLOB) {value = handleBlob(rs.getBlob(i));} else if (types[i] == JSON) {value = rs.getObject(i);if(value != null) {try {value = TypeConverter.me().convert(JSON.class, value.toString());} catch (ParseException e) {logger.error("转换失败!" + value, e);}}} else {value = rs.getObject(i);}}attrs.put(labelNames[i], value);}result.add((T)ar);}return result;}public void buildLabelNamesAndTypes(ResultSetMetaData rsmd, String[] labelNames, int[] types) throws SQLException {for (int i=1; i<labelNames.length; i++) {labelNames[i] = rsmd.getColumnLabel(i);types[i] = rsmd.getColumnType(i);//JSONString columnTypeName = rsmd.getColumnTypeName(i);if("JSON".equals(columnTypeName)) {types[i] = JSON;}}}
  1. 解决查询结果封装到Record对象时,映射正确的类型。
    参考ModelBuilder的修改。修改com.jfinal.plugin.activerecord.RecordBuilder类。
    在这里插入图片描述
  2. 解决请求参数中json字符串封装到Model对象时,映射正确的类型。
    分析controller中封装Model的源码,比如 getBean(User.class,“”),
    在这里插入图片描述
    所以只需在TypeConverter中注册转换器就可以了。
    新增JsonConverter
package com.jfinal.core.converter;import java.text.ParseException;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;/**** 启动时注册转换器。 可以在JfinalServerConfig中注册,RegisterConverter.regist()* TypeConverter.me().regist(JSON.class, new JsonConverter());* @author xpl**/
public class JsonConverter implements IConverter<JSON>{/*** 数组返回 JSONArray,对象返回JSONObject* */@Overridepublic JSON convert(String s) throws ParseException {//不用考虑空值,调用前校验
//		if(StrKit.isBlank(s)) {
//			return null;
//		}JSON json = (JSON) JSONObject.parse(s);return json;}}

然后再JfinalServerConfig中注册转换器:

TypeConverter.me().regist(JSON.class, new JsonConverter());
  1. 解决执行保存或者更新sql时,com.alibaba.fastjson.JSON格式数据进行处理,保证sql顺利执行。
    修改com.jfinal.plugin.activerecord.dialect.MysqlDialect类。
	/**** 对一些特殊值进行处理,否则会导致sql执行报错。比如JSON对象。2025-11-11* @param paras* @param val*/public void  addPara(List<Object> paras, Object val) {if(val != null && val instanceof com.alibaba.fastjson.JSON) {paras.add( ((com.alibaba.fastjson.JSON)val).toJSONString() );}else {paras.add(val);}}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过以上修改就可以实现了。
PS:前端查询结果改之前json字段返回的结果是字符串,修改后,返回的结果是json对象。这里需要注意一下。

http://www.dtcms.com/a/596372.html

相关文章:

  • Excel处理控件Aspose.Cells教程:如何使用C#在Excel中添加、编辑和更新切片器
  • Java 在 Excel 文件中添加或删除分节符
  • 电子电气架构 --- 车载OTA功能
  • Chrome HSTS(HTTP Strict Transport Security)
  • 【项目亮点】基于EasyExcel + 线程池解决POI文件导出时的内存溢出及超时问题
  • 【C++】链表算法习题
  • 搭建智能问答系统需要什么文档解析工具?
  • 【C++】(以及大多数编程语言)中常见的 六种基本位运算操作
  • (129页PPT)罗兰贝格银行风险预警管理体系规划(附下载方式)
  • 建设银行网站可以更改个人电话网址大全域名解析
  • 增删查改(其一) —— insert插入 与 select条件查询
  • JuiceSSH+cpolar解锁手机远程Linux新姿势,无需公网IP,固定地址稳定用
  • 传统生产制造企业手写单据数字化落地:旗讯 OCR 的技术实现与系统对接方案
  • 如何添加网站白名单广州建设网站的公司
  • nnUNet 训练与推理命令操作记录
  • 【C#】从一次异步锁逐渐展开浅谈服务器架构解决重复编码问题,我与AI的一次深度讨论得出的一些解决方案
  • PKHeX 宝可梦存档编辑工具 用户可自由修改宝可梦属性、技能、道具、图鉴完成度等信息
  • 深度解析:环形链表——手撕面试经典题
  • elasticsearch集群访问中的通信问题
  • 西安模板网站建设套餐佛山做网站费用
  • 什么是RKNN?
  • 《智元启示录》升级说明:从「AI 思考集」到「AI 决策内参」
  • Ansible 基础配置与负载均衡部署实践
  • 融合先验文本与解剖学知识的多模态回归网络用于舌鳞状细胞癌浸润深度的自动预测|文献速递-文献分享
  • 【负载均衡】LVS DR模式详解
  • 从零搭建 ASP.NET 单文件 Web 项目:一个能真用的 BookShop 管理页实战
  • 安徽专业网站建设长春能开发网站的公司
  • hadoop-3.4.1 单机伪部署
  • Nginx(4)--Nginx与tomcat反向代理和负载均衡
  • 37负载均衡介绍和nginx模块编译安装