在网站、管理软件的开发中,经常会碰到多选框。例如:用户可以设置自己愿意接收的邮件类型 1:从不接收 2:接收自己follow的博客的更新信息 3:接收新闻 4:接收私人信息。
这时我们可以选择传统的方式。定义一些字符串常量,例如:
public static final String EMAIL_OPTION_NEVER = "NEVER";
public static final String EMAIL_OPTION_FOLLOWED = "FOLLOWED";
public static final String EMAIL_OPTION_NEWS = "NEWS";
public static final String EMAIL_OPTION_PERSONAL = "PERSONAL";
对应的JSF页面如下:
<h:selectManyCheckbox id="optionsCheckbox" value="#{consumerAccountAction.emailOptionList}" layout="pageDirection" οnclick="clickOptionCheckbox();">
<f:selectItem itemLabel="#{messages['label_emailoption_never']}" itemValue="NEVER"/>
<f:selectItem itemLabel="#{messages['label_emailoption_news']}" itemValue="NEWS" />
<f:selectItem itemLabel="#{messages['label_emailoption_followed']}" itemValue="FOLLOWED" />
<f:selectItem itemLabel="#{messages['label_emailoption_personal']}" itemValue="PERSONAL" />
</h:selectManyCheckbox>
假设数据库中有一个表的字段名为email_options。这样当用户选择2,3的时候, email_options中存储的数据就可能是 “FOLLOWED,NEWS”。
而在实际要给用户发邮件的时候,就要判断这个字段中存在的值,例如:if(emailOption.indexOf(EMAIL_OPTION_NEVER)!=-1)
上述传统的解决方案没有问题,但是数据库中存储的数据还是占用空间过多。有一种办法可以极大的降低占用空间,业务逻辑上也不会复杂。
重新定义常量(常量按照2的次方递增):
public static final String EMAIL_OPTION_NEVER = "1";
public static final String EMAIL_OPTION_FOLLOWED = "2";
public static final String EMAIL_OPTION_NEWS = "4";
public static final String EMAIL_OPTION_PERSONAL = "8";
并让字段email_options中存储的值为FOLLOWED|NEWS, 而判断的时候可以用if((emailOption&EMAIL_OPTION_NEVER)!=0).
'|' 和'&' 是位运算符。具体大家可以去google. 这样数据库中存储的仅仅是一个数字,比一长串的字符串占得空间要少得多。