背景:
设计系统初期、系统类对象的属性往往是提前设计好,并且是固定的。后期在运营中会多次对同一类对象增加新的属性,拿个人信息为例。
用户刚开始具有:“姓名、手机号、生日”等基本信息。当时的我们认为这是很全面的属性。并且不会改变。过了一点都不长的时间后,产品要求用户可以选填“电子邮箱”。这一个字段的修改,对于使用mybatis的我们来说,增加起来不算困难。于是很快加好了。
又过了一段时间,产品要求用户要填写“个人收入”和“教育程度”。开发心想:“又是两个字段,真难啊”。于是将mybatis 升级 为 mybatis-plus 。对于加字段方便了一些。
又过了一段时间,产品要求用户可以“动态添加”个人的额外参数信息,以便于快速上线(开发加字段又慢、还经常出bug)
笔记来了
怎么将参数设计成动态的呢?
首先、构想下如何设计、他需要具有以下几个方面
- 用一种方式存储具有额外参数信息
- 存储用户额外参数信息数据
- 这些参数信息可以动态新增。数据支持搜索、分页、修改和删除
- 增改参数信息时,不对已有数据产生影响。
针对上面的设计,已 “若依”系统为例。
可以将用户额外信息存储为字典类型。
设计额外信息项。至此动态新增初步完成了。
下一步将动态数据存储入库。
表设计,存储以下字段即可
- 用户id
- 参数名称
- 参数值
聪明的小伙伴已经发现,存储数据是很简单。但是存储格式已记录的方式存储数据,这种数据对于查询来说是很不方便的。
查询
上面的设计,数据存储简单,查询是一个很大问题,这就要求我们有较强的sql 编写能力。
从下面几个思路介绍
- 通过xml 循环查询项, 编写负责复杂sql
- 通过视图提前写好复杂查询sql ,便于操作
1、编写复杂sql
select count(rowId) from
(
SELECT rowId, count(id) AS cnt
FROM LEDGER
<!--查询-->
<include refid="whereSql"/>
GROUP BY rowId
<!--分页-->
<if test="params.size != 0">
having cnt = ${params.size}
</if>
) a
<sql id="whereSql">
where
<if test="params != null and params.size != 0">
<foreach item="param" collection="params" index = "index" open="(" close=")" separator="and">
( paramKey = #{param.name} and paramValue like CONCAT('%',#{param.value},'%') )
</foreach>
</if>
</sql>
2、视图方式