在做一个功能,需要把Web端数据库里与当前用户相关的数据同步到移动设备端。移动设备端在联网的情况下定时同步数据,在不联网时可查询旧的数据。
解决方案是:
1.假设初始状态Web端数据库为空。用户在录数据过程中,将操作记录到一张日志表中。
2.移动设备端启动线程,定时访问日志表。获取和自己相关的最新改动记录。
3.将这些改动更新到本地的SQLite
使用到技术:
1.用Hibernate Listener记录用户所有的操作。将对关心表的操作记入日志表。日志表包含:操作类型(insert update delete)、操作表名、记录ID和操作人。
2.Hibernate Listener 中没有Servlet,无法获取当前操作人的信息。因此使用ThreadLocal
一些疑问:
1.原打算用aspectJ在Session类做切面,记录数据库操作日志。发现aspectJ在Session做切面的代码不执行。不知道原因,可能和hibernate动态生成代码有关系。
public class HibernateHistoryListener implements PostInsertEventListener,
PostUpdateEventListener, PostDeleteEventListener {
static final Class accessClass[] = { DmMenu.class, DmRMenuDish.class,
DmCategory.class, DmDish.class, DmDishImage.class, DmEvaluate.class };
public final static ThreadLocal userLocal = new ThreadLocal();
public void onPostInsert(PostInsertEvent arg) {
log("insert", arg.getEntity(), arg.getId().toString(), arg.getSession());
}
public void onPostUpdate(PostUpdateEvent arg) {
log("update", arg.getEntity(), arg.getId().toString(), arg.getSession());
}
public void onPostDelete(PostDeleteEvent arg) {
log("delete", arg.getEntity(), arg.getId().toString(), arg.getSession());
}
private void log(String method, Object obj, String id, Session session) {
boolean access = false;
for (int i = 0; i < accessClass.length; i++) {
Class array_element = accessClass[i];
if (obj.getClass().equals(array_element)) {
access = true;
break;
}
}
if (!access) {
return;
}
DmOperationLog log = new DmOperationLog();
log.setOperationName(method);
log.setOperationTime(new Date());
log.setRecordId(id);
log.setTargetName(obj.getClass().toString());
log.setDmUser((DmUser) userLocal.get());
Session temp = session.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = temp.beginTransaction();
temp.save(log);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
temp.close();
}
}
}