之前将GreenDao数据库替换成Room数据库后,虽然表的构建和数据库的升级比以往简单了许多,但是也出现了,一个问题,那就是数据不同步问题,因为GreenDao 是有缓存,而Room数据库是没有缓存的
1.比如我们同时调用数据查询方法,根据id 获取两个对像,然后,对其中一个bean 进行update操作,那GreenDao和room分别会走一下流程

因为GreenDao有缓存操作,所有其实两个Bean所对应的是同一块内存,所以当 其中一个bean更新的时候,另外一个bean也会同步更新。

而Room数据库,每次获取对象都会开辟一个新的内存,所以 两个对象对应的内存块,不一致,因此当数据修改时候,不会同步
。
于是就想参照GreenDao对Room最一个数据缓存。
首先我们来看看GreenDao的数据缓存机制
1.首先是一个缓存对象

IdentityScope持有一个锁和一个map对象,然后实现,一些列的增加和删除操作,之所以要实现一个带锁和不带锁的方法,是因为之后有一些比较复杂的操作,需要通过,一些列的复合操作的实现,所以我们可以先调用lock 然后在一系列复合操作完成之后去调用unlock释放锁。详细的操作可以参见IdentityScopeObject的实现。所以GreenDao是数据缓存结构其实很简单。
/*
* Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.greenrobot.greendao.identityscope;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* The context for entity identities. Provides the scope in which entities will be tracked and managed.
*
* @author Markus
* @param <K>
* @param <T>
*/
public class IdentityScopeObject<K, T> implements IdentityScope<K, T> {
private final HashMap<K, Reference<T>> map;
private final ReentrantLock lock;
public IdentityScopeObject() {
map = new HashMap<K, Reference<T>>();
lock = new ReentrantLock();
}
@Override
public T get(K key) {
Reference<T> ref;
lock.lock();
try {
ref = map.get(key);
} finally {
lock.unlock();
}
if (ref != null) {
return ref.get();
} else {
return null;
}
}
@Override
public T getNoLock(K key) {
Reference<T> ref = map.get(key);
if (ref != null) {
return ref.get();
} else {
return null;
}
}
@Override
public void put(K key, T entity) {
lock.lock();
try {
map.put(key, new WeakReference<T>(entity));
} finally {
lock.unlock();
}
}
@Override
public void putNoLock(K key, T entity) {
map.put(key, new WeakReference<T>(entity));
}
@Override
public boolean detach(K key, T entity) {
lock.lock();
try {
if (get(key) == entity && entity != null) {
remove(key);
return true;
} else {
return false;
}
} finally {
lock.unlock();
}
}
@Override
public void remove(K key) {
lock.lock();
try {
map.remove(key);
} finally {
lock.unlock();
}
}
@Override
public void remove(Iterable< K> keys) {
lock.lock();
try {
for (K key : keys) {
map.remove(key);
}
} finally {
lock.unlock();
}
}
@Override
public void clear() {
lock.lock();
try {
map.clear();
} finally {
lock.unlock();
}