在業(yè)務(wù)開發(fā)中,有的時(shí)候會(huì)碰到這樣的需求,一個(gè)對(duì)象要生效,會(huì)有各種各樣的條件,而這些條件又只有
是與否之分,如果我們每個(gè)條件都用一個(gè)字段的話,那么數(shù)據(jù)庫保存的時(shí)候需要對(duì)應(yīng)給每個(gè)條件都加一個(gè)字段,這樣也不是不可以,一般這種也是比較常見的做法,但是如果比較多,但是又有拓展的可能,那么是否可以考慮另一種方式來存儲(chǔ),也值得考慮。
本文介紹一種基于二進(jìn)制的方式來存儲(chǔ)這些條件,通過簡單的java代碼實(shí)現(xiàn)主要的邏輯。
開始
假如業(yè)務(wù)是支持的支付方式,比如有微信、支付寶、美團(tuán)支付、抖音支付(聽說要出了)、招商銀行卡;
創(chuàng)建一個(gè)枚舉:
public enum PayWayEnum {
/**
* 微信
*/
TENCENT(0),
/**
* 支付寶
*/
ALIPAY(1),
/**
* 抖音
*/
BYTE_DANCE(2),
/**
* 美團(tuán)
*/
MEITUAN(3),
/**
* 招商銀行
*/
CMB(4),
;
/**
* 對(duì)應(yīng)數(shù)據(jù)庫存儲(chǔ)的二進(jìn)制位數(shù)
*/
private int bit;
PayWayEnum(int bit) {
this.bit = bit;
}
public int getBit() {
return bit;
}
}
從業(yè)務(wù)的角度來講,不外乎對(duì)這個(gè)字段的增改查
工具類
@UtilityClass
public class BinaryUtil {
/**
* 驗(yàn)證二進(jìn)制第bit位的結(jié)果
*
* @param binary 二進(jìn)制值
* @param bit index 從0開始
* @return true 為1 false 為0
*/
public static boolean match(Integer binary, int bit) {
int value = 1 << (bit);
int i = value & binary;
return i > 0;
}
/**
*
* 將二進(jìn)制result的第bit位設(shè)置為bool的值
* 一般用于修改
* @param binary 二進(jìn)制原始值
* @param bit index 從0開始
* @param bool 要設(shè)置的值
* @return 修改后的結(jié)果
*/
public static Integer set(Integer binary, int bit, boolean bool) {
if (bool) {
int value = 1 << bit;
return binary | value;
} else {
int value = ~(1 << bit);
return binary & value;
}
}
/**
* 指定幾位生產(chǎn)二進(jìn)制
* 用戶創(chuàng)建
* @param bits 設(shè)置某幾位為1
* @return 范圍生成的二進(jìn)制值
*/
public static Integer accept(int[] bits) {
int binary = 0;
for (int bit : bits) {
binary = set(binary, bit, true);
}
return binary;
}
/**
* 字符串二進(jìn)制1010101轉(zhuǎn)為整數(shù)值
*
* @param binaryString
* @return
*/
public static Integer valueOf(String binaryString) {
return Integer.valueOf(binaryString, 2);
}
/**
* 將數(shù)字轉(zhuǎn)為二進(jìn)制字符串
*
* @param integer
* @return
*/
public static String toBinaryString(Integer integer) {
return Integer.toBinaryString(integer);
}
}
測(cè)試
public static void main(String[] args) {
// 初始化
Integer accept = accept(new int[]{PayWayEnum.TENCENT.getBit(), PayWayEnum.ALIPAY.getBit()});
System.out.println(toBinaryString(accept));
// 驗(yàn)證是否支持微信支付
String value = toBinaryString(accept);
Integer integer = valueOf(value);
boolean match = match(integer, PayWayEnum.TENCENT.getBit());
System.out.println(match);
// 設(shè)置支持美團(tuán)支付
Integer result = set(integer, PayWayEnum.MEITUAN.getBit(), true);
System.out.println(result);
String s = Integer.toBinaryString(result);
System.out.println(s);
}
思考
使用二進(jìn)制的方式存儲(chǔ)類似的這種業(yè)務(wù)數(shù)據(jù),擴(kuò)展性比較強(qiáng),比如我需要再增加一個(gè)建行支付,直接增加一個(gè)枚舉即可(如果將枚舉改成字典那就更好了); 但是也有不好的地方,比如數(shù)據(jù)庫值可讀性不高,不方便使用sql批量更新數(shù)據(jù),因?yàn)槊總€(gè)的值都會(huì)有不同,比如我某天增加了一個(gè)支付方式,我希望所有的商品都支持這種支付方式,這個(gè)時(shí)候其實(shí)就需要精細(xì)化更新了。
總的來說這是一種思考的方向,具體還是要根據(jù)實(shí)際開發(fā)中的需要來使用不同的數(shù)據(jù)結(jié)構(gòu),沒有萬能藥。