json
大约 3 分钟languagejava
概述
mysql5.7 开始支持 json 类型的字段,一个字段可保存一个对象,下面介绍从前端到数据库的整个链路上的用法
数据库
下面表结构中的字段 phone_data 和 visit_data 是 json 类型的字段
create table visit_submit_log
(
id bigint auto_increment comment '自增主键'
primary key,
parent_id int default 0 null comment '生成访单成功后写入访单主键=visit.id',
union_id varchar(50) default '' null comment '用户微信unionId',
entry_time datetime null comment '微信用户进入制作访单页面的时间',
submit_time datetime null comment '制作访单后提交的时间',
phone_data json null comment '手机硬件信息',
visit_data json null comment '访单json数据',
state int default 1 null comment '状态,默认1有效,0停用',
is_delete int default 0 null comment '删除标识,默认0未删除,1表示删除。mybatis-flex默认使用该名称作为逻辑删除的标识',
remark varchar(200) default '' null comment '备注',
sys_remark varchar(100) default '' null comment '系统备注,系统在做自动化操作时用于说明业务逻辑',
seq float default 0 null comment '排序序号',
create_time datetime default CURRENT_TIMESTAMP null comment '创建时间,DB自动填充',
create_user varchar(100) default '' null comment '创建人',
update_time datetime null on update CURRENT_TIMESTAMP comment '最后一次修改时间',
update_user varchar(100) default '' null comment '修改人',
page_uuid varchar(100) default '' null comment '前端页面唯一标识,每次新打开制作访单页面都会创建一个新的UUID'
)
comment '访单提交记录表,不管是否成功,记录每一次的提交动作';
java
springboot 项目中使用了 mybatis-flex,只需要贴出实体类即可。一开始设置 phoneData 和 visitData 是 Map<String,Object>,前端发送请求后端报错由于没有 getter 和 setter 无法解析前端数据,后来设置这两个 json 字段数据类型为 String 也测试不同,最后更改为 Object 类型可行。
/**
* @author chanchaw
* @create 2025-09-26 12:12
*/
@Table("visit_submit_log")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VisitSubmitLog implements Serializable {
private static final long serialVersionUID = 1L;
@Id(keyType = KeyType.Auto)
private Long id;
private Integer parentId;
private String pageUuid;
private String unionId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime entryTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime submitTime;
@Column(typeHandler = JacksonTypeHandler.class)
private Object phoneData;
@Column(typeHandler = JacksonTypeHandler.class)
private Object visitData;
private Integer state;
private Integer isDelete;
private String remark;
private String sysRemark;
private Float seq;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
private LocalDateTime createUser;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
private LocalDateTime updateUser;
}
// 上面是实体类,下面是控制器代码
@PostMapping("/testJsonType")
public ResponseResult testJsonType(@RequestBody VisitSubmitLog record){
return new ResponseResult(visitSubmitLogMapper.insertSelective(record));
}
微信小程序
微信小程序中声明实体类的代码如下
interface IVisitSubmitLog {
id?:number,parentId?:number,pageUuid?:string,unionId?:string,entryTime?:Date,submitTime?:Date,phoneData?:string,visitData?:string,state?:number,isDelete?:number,remark?:string,sysRemark?:string,seq?:number,createTime?:Date,createUser?:string,updateTime?:Date,updateUser?:string
}
注意对应 mysql 两个 json 字段的数据类型是 string 类型,请求 API 时传递参数如下:
// 传递进来的参数 formData 是表单对象,visitSubmitLog 是实体类 IVisitSubmitLog 的实例
// 赋值 json 类型属性时不需要 JSON.stringify(),直接赋值对象即可
async insertVisitSubmitLog(formData:IVisit){
this.setData({
'visitSubmitLog.visitData': formData
})
const affectedRowCount = await http.insertVisitSubmitLogDev$(this.data.visitSubmitLog);
},
// 直接请求后端 API 的函数
// 传入的实体类对象参数 record 也不需要 JSON.stringify()
// 直接赋值给请求的 data 即可
const insertVisitSubmitLogDev$ = (record: IVisitSubmitLog):Promise<number> => {
console.log('请求参数1:',record);
return new Promise((resolve,reject) => {
wx.request({
header: { "Content-Type": "application/json; charset=UTF-8" }, method: 'POST',
url: `https://showawx.xdfznh.club/visitorbedev/test/testJsonType`,
data: record,
success: (res: any) => {
const { success,msg,data } = res.data;
if(!success) {
console.log('请求出现异常:', msg);
wx.showToast({title: msg, icon:'none', duration: 5000});
reject(data);
return
}
resolve(data);
},
fail: (err: any) => {
console.log('写入 visit_submit_log 时出现异常:',err)
},
complete: () => {}
})
})
}
小程序用string,Web前端用Object
注意上面的案例在微信小程序中测试通过,其通过下面代码更新对象数据到实体类的 string 属性
this.setData({
'visitSubmitLog.visitData': formData,
'visitSubmitLog.submitTime': new Date(),
})
前端的字符串类型属性 visitData 可以直接赋值表单的对象数据,java 后端采用 Object 类型接受数据。如果是 web 前端则属性 visitData 应该设置为 Object 类型
