Collection 拆分

优质
小牛编辑
132浏览
2023-12-01

在某些情况下,某个collection可能会非常大,比如,存储1亿条数据。这时候操作这个collection会很慢。一种最简单直接的优化方法,是将其拆分。

bugu-mongo支持对集合的拆分,可以按年、月、日、自定义字符串对其拆分。

比如,你有很多的朋友,你希望按省份存放到不同的表中,上海的存放在friend-shanghai,浙江的存放在friend-zhejiang。

步骤一:设置@Entity的split属性

注解@Entity有个属性split,用户定义对表的拆分行为,其值是一个SplitType枚举:

  • SplitType.NONE —— 不拆分
  • SplitType.DAILY —— 按天拆分
  • SplitType.MONTHLY —— 按月拆分
  • SplitType.YEARLY —— 按年拆分
  • SplitType.STRING —— 按自定义的字符串拆分

如果不设置@Entity的split属性,则其默认值为NONE,表示不拆分。

例:

@Entity(split = SplitType.STRING)
public class Friend extends SimpleEntity {

    private String name;

    private String province;

}

步骤二:对DAO设置表后缀

如果对表进行了拆分,那么在使用DAO进行操作的时候,需要让DAO知道操作哪个表。方法是调用BuguDao的如下两个方法中的某一个:

public void setSplitSuffix(Date date)

public void setSplitSuffix(String s)

例如,插入数据:

//保存Friend数据到不同的表中
Friend f1 = new Friend();
f1.setName("Frank");
f1.setProvince("zhejiang");

dao.setSplitSuffix(f1.getProvince());
dao.save(f1);

Friend f2 = new Friend();
f2.setName("Tom");
f2.setProvince("shanghai");

dao.setSplitSuffix(f2.getProvince());
dao.save(f2);

查询数据:

//只查询friend-zhejiang表中的数据
FriendDao dao = new FriendDao();
dao.setSplitSuffix("zhejiang");

List<Friend> list = dao.findAll();
for(Friend f : list){
    System.out.println("name: " + f.getName());
    System.out.println("province: " + f.getProvince());
}

说明

分表的时候,BuguDao内部使用了ThreadLocal,以解决不同的线程操作不同的表的情况,因此,BuguDao是线程安全的。