Я ранее реализовал кэширование в своем приложении, которое будет использоваться с тремя отдельными методами get.Эти методы получения: getAllProfiles()
, getProfilesByID()
и getProfileByFields()
.Из-за этого мой код выглядит следующим образом:
private LoadingCache<int[], List<Profile>> loadingCache = CacheBuilder.newBuilder()
.refreshAfterWrite(5, TimeUnit.MINUTES)
.expireAfterAccess(5, TimeUnit.MINUTES)
.maximumSize(100).build(
new CacheLoader<int[] ids, List<Profile>>() {
@Override
public List load(int[] ids) throws Exception {
return profileDAO.getProfilesById(ids);
}
}
);
private LoadingCache<Integer, List<Profile>> loadingCache2 = CacheBuilder.newBuilder()
.refreshAfterWrite(5, TimeUnit.MINUTES)
.expireAfterAccess(5, TimeUnit.MINUTES)
.maximumSize(100).build(
new CacheLoader<Integer, List<Profile>>() {
@Override
public List<Profile> load(Integer size) throws Exception {
return profileDAO.getAllProfiles(size);
}
}
);
private LoadingCache<Profile, List<Profile>> loadingCache3 = CacheBuilder.newBuilder()
.refreshAfterWrite(5, TimeUnit.MINUTES)
.expireAfterAccess(5, TimeUnit.MINUTES)
.maximumSize(100).build(
new CacheLoader<Profile, List<Profile>>() {
@Override
public List<Profile> load(Profile profile) throws Exception {
return profileDAO.getProfileByFields(profile);
}
}
);
public ProfileManagerImpl(ProfileDAO profileDAO) {
this.profileDAO = profileDAO;
}
public List<Profile> getAllProfiles(Integer size) throws Exception {
return loadingCache2.get(size);
}
public List<Profile> getProfilesById(int[] idArray) throws Exception {
return loadingCache.get(idArray);
}
public List<Profile> getProfileByFields(Profile profile) throws Exception {
return loadingCache3.get(profile);
}
Однако, чтобы упростить свою работу, мне нужно создать один кэш, который создается при запуске, используя getAllProfiles()
для всей таблицы.Все три метода затем будут использовать этот один кеш для работы.
Я думаю, что я могу просто повторно использовать код для loadCache2, чтобы сначала создать кеш:
private LoadingCache<Integer, List<Profile>> loadingCache2 = CacheBuilder.newBuilder()
.refreshAfterWrite(5, TimeUnit.MINUTES)
.expireAfterAccess(5, TimeUnit.MINUTES)
.maximumSize(100).build(
new CacheLoader<Integer, List<Profile>>() {
@Override
public List<Profile> load(Integer size) throws Exception {
return profileDAO.getAllProfiles(size);
}
}
);
и передатьnull для размера, поэтому оператор SQL в DAO будет «SELECT * FROM Profiles».Проблема придет от других методов;Я понятия не имею, как указать эти методы для этого кэша, учитывая различные входные требования.Кто-нибудь делал что-то подобное ранее?
Редактировать:
Как предложил Луи Вассерман, я делаю один объект Cache, который принимает Object в качестве универсального ключа.Оттуда сервис должен использовать оператор if, чтобы определить тип входного объекта, и использовать соответствующий метод для извлечения содержимого кэша, в зависимости от используемого метода.
На данный момент, однако, он терпит неудачуна getAllProfiles, за исключением нулевого указателя, поэтому мне нужно это выяснить.
Исходя из приведенного ниже кода, похоже, я на правильном пути?Я использую Cache, а не LoadingCache для этого объекта:
public Cache<Object, List<Profile>> cache =
CacheBuilder.newBuilder()
.refreshAfterWrite(5, TimeUnit.MINUTES)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build(new CacheLoader<Object, List<Profile>>() {
@Override
public List<Profile> load(Object k) throws Exception {
if (k instanceof Integer) {
return profileDAO.getAllProfiles((Integer) k);
}
else if (k instanceof int[]) {
return profileDAO.getMultipleProfiles((int[]) k);
}
else if (k instanceof Profile)
return profileDAO.getProfileByFields((Profile) k);
}
});
public List<Profile> getAllProfiles(Integer size) throws Exception {
return cache.getIfPresent(size);
}