SpringMVC结合模板模式实现MyBatisPlus传递嵌套JSON数据
作者:图灵重生我名苏泽
引出
我们经常会遇到需要传递对象的场景。有时候,我们需要将一个对象的数据传递给另一个对象进行处理,但是又不希望直接暴露对象的内部结构和实现细节。这时,我们可以使用模板模式来实现优雅的对象传递。
为了实现这个场景,我们可以使用模板模式。
模板模式是一种行为设计模式,它定义了一个抽象类或接口作为模板,其中包含了一个或多个抽象方法,用于定义算法的骨架。具体的子类可以根据需要实现这些抽象方法,从而完成算法的定制化。
说说我这边的起因
大概是这样的 要做一个问卷系统 这个问卷里面包含各种各样的标签和因子 就使得 属性里面又包含属性 对象里面又嵌套数组 数组里面又有对象 遇到这种情况相信大家都会很头疼吧 那这种时候很多人就要开始写Mapper了 这里我提出一个大大节约时间的方法 类型构造器
设计模式的引入
我们知道 每一个属性需要引入一个新的类型构造器 那就要根据他的具体情况重写一个 那岂不是代码量指数级上涨?
还有很多...各种嵌套 于是我想 有没有一种办法能规定好所有的嵌套方法的逻辑 然后他们只需要说明自己是什么类型 就能套进去?
有,就是今天要说的模板方法
先定义一个通用的模板
public class JsonArrayHandler<T> extends BaseTypeHandler<List<T>> { private Class<T> type; public JsonArrayHandler() { // 添加无参构造函数 } public JsonArrayHandler(Class<T> type) { if (type == null) { throw new IllegalArgumentException("Type argument cannot be null"); } this.type = type; } @Override public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, JSONArray.toJSONString(parameter)); } @Override public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException { String json = rs.getString(columnName); return parseJsonArray(json); } @Override public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String json = rs.getString(columnIndex); return parseJsonArray(json); } @Override public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String json = cs.getString(columnIndex); return parseJsonArray(json); } private List<T> parseJsonArray(String json) { JSONArray jsonArray = JSONArray.parseArray(json); return jsonArray.toJavaList(type); } }
让我逐点解释其妙处:
泛型支持:
public class JsonArrayHandler<T> extends BaseTypeHandler<List<T>>
中的<T>
表示这是一个泛型类,可以适用于不同类型的 JSON 数组字段。通过使用泛型,可以在运行时指定具体的类型,使得处理不同类型的 JSON 数组变得更加灵活和通用。构造函数重载:
public JsonArrayHandler()
是一个无参构造函数,而public JsonArrayHandler(Class<T> type)
是一个有参构造函数。通过提供两个构造函数,可以灵活地创建JsonArrayHandler
的实例。无参构造函数用于在不知道具体类型时创建实例,而有参构造函数用于在已知类型时创建实例。参数设置:
setNonNullParameter
方法用于将 Java 对象转换为存储在数据库中的 JSON 字符串。在这里,使用了阿里巴巴的 FastJSON 库将 List<T> 对象转换为 JSON 字符串,并将其设置到 PreparedStatement 对象中。结果获取:
getNullableResult
方法用于从数据库中获取 JSON 字符串,并将其转换回 List<T> 对象。在这里,使用了 FastJSON 库将 JSON 字符串解析为 JSONArray,然后将其转换为 List<T> 对象。
有了这一个模板 那么剩下来的就是 直接使用他!
这里浅浅给出我业务中的6个例子
- 商品分类:数据库中的
category_ids
字段存储了商品所属的分类列表。使用自定义 TypeHandler,可以将 Java 对象的 List<Category> 直接映射到数据库的 JSON 字符串,并在读取时将 JSON 字符串转换回 List<Category>。
public class CategoryHandler extends JsonArrayHandler<Category> { public CategoryHandler() { super(Category.class); } }
- 用户角色:数据库中的
role_ids
字段存储了用户所拥有的角色列表。使用自定义 TypeHandler,可以将 Java 对象的 List<Role> 直接映射到数据库的 JSON 字符串,并在读取时将 JSON 字符串转换回 List<Role>。
public class RoleHandler extends JsonArrayHandler<Role> { public RoleHandler() { super(Role.class); } }
- 订单商品列表:数据库中的
order_items
字段存储了订单中的商品列表。使用自定义 TypeHandler,可以将 Java 对象的 List<OrderItem> 直接映射到数据库的 JSON 字符串,并在读取时将 JSON 字符串转换回 List<OrderItem>。
public class OrderItemHandler extends JsonArrayHandler<OrderItem> { public OrderItemHandler() { super(OrderItem.class); } }
- 图片列表:数据库中的
image_urls
字段存储了一组图片的 URL 列表。使用自定义 TypeHandler,可以将 Java 对象的 List<String> 直接映射到数据库的 JSON 字符串,并在读取时将 JSON 字符串转换回 List<String>。
public class ImageHandler extends JsonArrayHandler<String> { public ImageHandler() { super(String.class); } }
- 标签列表:数据库中的
tags
字段存储了一组标签。使用自定义 TypeHandler,可以将 Java 对象的 List<Tag> 直接映射到数据库的 JSON 字符串,并在读取时将 JSON 字符串转换回 List<Tag>。
public class TagHandler extends JsonArrayHandler<Tag> { public TagHandler() { super(Tag.class); } }
Answer
类是一个答案类,包含了答案内容answer
和分数score
两个字段。Questionnaire
类是一个问卷调查类,其中包含了一些字段,包括主键id
、问题编号qid
、答案answer
、问题名称qname
、问题描述question
、标签tab
、ans
。在ans
字段上,使用了@TableField
注解,并设置了typeHandler = AnswerHandler.class
,指定了使用AnswerHandler
这个自定义的 TypeHandler 来处理该字段。
public AnswerHandler(Class<Answer> type) { super(Answer.class); }
@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName("tb_questionnaire") public class Questionnaire { /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Long id; private int qid; private String answer; private String qname; private String question; private String tab; @TableField(exist = false,typeHandler = AnswerHandler.class) private List<Answer> ans; public void setAnswer() { this.answer = JSONUtil.toJsonStr(ans); } public void setAnswerList() { this.ans = JSONUtil.toList(answer,Answer.class); answer=null; } }
查询
这样就不用写复杂的Mapper 和sql语句 也能轻松查询嵌套的复杂的JSON数据啦
实现效果
这样就形成了复杂的嵌套的数据的自动构造
以上就是SpringMVC结合模板模式实现MyBatisPlus传递嵌套JSON数据的详细内容,更多关于SpringMVC传递嵌套JSON数据的资料请关注脚本之家其它相关文章!