美文网首页
数据库一个字段保存多标志位

数据库一个字段保存多标志位

作者: 十毛tenmao | 来源:发表于2019-10-11 23:09 被阅读0次

项目中有一些场景,需要设置多个标志位,比如发送提醒消息,3天后发送提醒消息,7天后发送提醒,如果每个标志位都占用一个数据库字段就显得太浪费了。所以考虑使用一个INT字段,使用其二进制位保存各个标志

原理

MySQL数据库支持二进制位操作,比如

SELECT * FROM person WHERE hobbies & 0b100

实现示例

使用二进制位保存人员的各种爱好(假设爱好的集合是优先的)

  • BitFlag
/**
 * 二进制表示各种标志.
 * @author timxia 
 */
@NoArgsConstructor
public class BitFlag {
    /**
     * 最长支持的标志个数.
     */
    private static final int MAX_FLAG = 32;

    /**
     * 实际的值.
     */
    private BitSet value = new BitSet();

    public BitFlag(int value) {
        this.value = Bits.convert(value);
    }

    public void setFlag(int flagIndex) {
        if (flagIndex >= MAX_FLAG) {
            throw new IndexOutOfBoundsException();
        }
        value.set(flagIndex);
    }

    public boolean hasFlag(int flagIndex) {
        return value.get(flagIndex);
    }

    public void clearFlag(int flagIndex) {
        if (flagIndex >= MAX_FLAG) {
            throw new IndexOutOfBoundsException();
        }
        value.clear(flagIndex);
    }

    public int convertToInt() {
        if (bits.length() > Integer.SIZE) {
            throw new IllegalArgumentException("BitSet is out range of int");
        }
        int value = 0;
        for (int i = 0; i < bits.length(); ++i) {
            value += bits.get(i) ? (1 << i) : 0;
        }
        return value;
    }
}
  • BitFlagHandler
    为BitFlag定义TypeHandler,实现BitFlag与数据库字段的转换
public class BitFlagHandler extends BaseTypeHandler<BitFlag> {
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, BitFlag bitFlag, JdbcType jdbcType) throws SQLException {
        preparedStatement.setInt(i, bitFlag.convertToInt());
    }

    @Override
    public BitFlag getNullableResult(ResultSet resultSet, String s) throws SQLException {
        int anInt = resultSet.getInt(s);
        return new BitFlag(anInt);
    }

    @Override
    public BitFlag getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int anInt = resultSet.getInt(i);
        return new BitFlag(anInt);
    }

    @Override
    public BitFlag getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int anInt = callableStatement.getInt(i);
        return new BitFlag(anInt);
    }
}

BitFlag的使用


  • 人员类定义(Person)
/**
 * 人员类定义,其中hobbies使用{@link BitFlag}表示爱好.
 * @author tenamo
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Person {
    private Integer id;
    private String firstName;
    private String lastName;
    private Integer age;
    private BitFlag hobbies;
    private Boolean gender;
}
  • SpringBootApplication
@SpringBootApplication
public class BootMybatisApplication implements ApplicationRunner {
    @Resource
    private PersonMapper personMapper;

    public static void main(String[] args) {
        SpringApplication.run(BootMybatisApplication.class, args);
    }

    @Override
    public void run(ApplicationArguments args) {
        Person tenmao = personMapper.selectById(9);

        BitFlag hobbiesInDb = tenmao.getHobbies();

        //设置Flag
        hobbiesInDb.setFlag(5);
        hobbiesInDb.clearFlag(1);

        //保存到数据库
        personMapper.updateHobbies(9, hobbiesInDb);
    }
}
  • MyBatis配置(application.yml)
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  type-handlers-package: com.tenmao.boot.mybatis.handler

参考

相关文章

  • 数据库一个字段保存多标志位

    项目中有一些场景,需要设置多个标志位,比如发送提醒消息,3天后发送提醒消息,7天后发送提醒,如果每个标志位都占用一...

  • 合并两个表

    标志字段:设置标志字段的名称,标志字段用于保存比较的结果,比较结果有下列几种。 “identical” – 旧数据...

  • mysql简单总结

    数据库三范式 1.保持每列字段的原子性 保存用户的地址不用一个字段address来保存,而是用几个字段组成,比如:...

  • hive日常总结

    spark sql 读取mysql 数据库和写入mysql数据库时, dataframe 字段比表字段多一个 直接...

  • SAP CRM WebClient UI端到端的字段扩展

    所谓端到端的字段扩展,就是在WebClient UI上增添新的字段,允许客户维护,并保存到数据库里。 根据Jerr...

  • 【测试用例】之增删改查

    新增功能 1.输入长度限制(长度,格式,数据类型)2.保存(当保存成功,检查数据表新增,在数据库中保存的字段是否与...

  • beego orm查询数据保存

    beego orm 查询数据库之后,数据需要保存到相应的struct 数组中。 struct 中每个字段需要添加 ...

  • 常用SQL命令

    一、SQL语句 1、修改表格的字段(ALTER TABLE) 2、把事务保存到数据库(COMMIT) 3、创建表格...

  • 【FMDB使用】问题:多个用户登陆同一个设备,账单数据相同

    解决办法: 因为账单用FMDB保存到了数据库,所以要在数据库的表中,添加一个字段:区分不同的用户——》那就是用户名...

  • 前台显示时间格式转换2018-07-11

    spring boot返回date类型给前端,显示的是毫秒的问题 数据库字段类型为datetime 实体保存的类型...

网友评论

      本文标题:数据库一个字段保存多标志位

      本文链接:https://www.haomeiwen.com/subject/lekfmctx.html