简介
我为什么写这样一个简单的问题呢?首先介绍一下项目背景。最近需要做一个数据库同步的工作,也就是一个Web程序有两个数据库,一个是它自身的本地数据库,另外一个是远程的数据库。当我们对访问web项目,对其本地数据库进行增删改的时候,也要同时对远程数据库进行增删改。我们的思路是:我们首先在Spring的配置文件中,注入两个Dao对象,然后在service层进行增删改的时候,会在BaseDao中先调用本地数据库的dao,然后调用远程的dao。
1.系统之前已经开发完毕,没有数据库同步功能
2.系统使用ssh框架开发
3.系统的所有增删改都是有service层调用Dao层的Hibernate方法实现的
疑问:
1.同步的时候为什么不在每个service层修改?
对于一个相对庞大的系统,service层有很多类,如果一个service一个service修改,工作了太大,容易改错
2.为什么不在数据库中添加一个字段,标记该条数据是否同步?
系统有几十张数据库表,这样做的话,代码修改了过大
3.如何设计同步表,如何根据同步表的内容对,进行同步?
同步表的设计
create table synctbl(
id varchar2(26) primary key,
type varchar2(10) not null,
classname varchar2(128) not null,
syncstring varchar2(3000) not null,
createtime date
);
id;主键,UUID即可
type:操作类型(增、删、改,或者hql语句)
classname:数据库表对于的Hibernate实体类的类名
syncstring:进行增删改的对象的序列化字符串,或者hql语句
createtime:该条记录的生成时间
正文:
以上逻辑有点复杂,很难用简短的文字描述清楚。我就把如何使用JSONObject让Hibernate的实体类生成字符串,然后在恢复的时候又是如何根据这些字符串和实体类的名称恢复出该实体类。
使用JSONObject需要如下jar包。
1.commons-beanutils-1.7.0.jar
2.commons-collections-3.2.jar
3.commons-lang-2.3.jar
4.commons-logging-1.0.4.jar
5.ezmorph-1.0.6.jar
6.json-lib-2.1.jar
BeanModel.java
我为什么写这样一个简单的问题呢?首先介绍一下项目背景。最近需要做一个数据库同步的工作,也就是一个Web程序有两个数据库,一个是它自身的本地数据库,另外一个是远程的数据库。当我们对访问web项目,对其本地数据库进行增删改的时候,也要同时对远程数据库进行增删改。我们的思路是:我们首先在Spring的配置文件中,注入两个Dao对象,然后在service层进行增删改的时候,会在BaseDao中先调用本地数据库的dao,然后调用远程的dao。
关键问题:
当本地的数据库增删改成功,而远程数据库增删改失败的时候,我们就需要对其进行异常处理。我们需要将增删改的对象保存起来然后插入到本地的同步表当中,当远程数据库可访问的时候,然后再将本地同步表中的数据取出来,然后生成对应的Object对象,然后使用远程数据库的dao进行增删改,增删改之后再将本地数据库的同步表记录删除。
前提:1.系统之前已经开发完毕,没有数据库同步功能
2.系统使用ssh框架开发
3.系统的所有增删改都是有service层调用Dao层的Hibernate方法实现的
疑问:
1.同步的时候为什么不在每个service层修改?
对于一个相对庞大的系统,service层有很多类,如果一个service一个service修改,工作了太大,容易改错
2.为什么不在数据库中添加一个字段,标记该条数据是否同步?
系统有几十张数据库表,这样做的话,代码修改了过大
3.如何设计同步表,如何根据同步表的内容对,进行同步?
同步表的设计
create table synctbl(
id varchar2(26) primary key,
type varchar2(10) not null,
classname varchar2(128) not null,
syncstring varchar2(3000) not null,
createtime date
);
id;主键,UUID即可
type:操作类型(增、删、改,或者hql语句)
classname:数据库表对于的Hibernate实体类的类名
syncstring:进行增删改的对象的序列化字符串,或者hql语句
createtime:该条记录的生成时间
正文:
以上逻辑有点复杂,很难用简短的文字描述清楚。我就把如何使用JSONObject让Hibernate的实体类生成字符串,然后在恢复的时候又是如何根据这些字符串和实体类的名称恢复出该实体类。
使用JSONObject需要如下jar包。
1.commons-beanutils-1.7.0.jar
2.commons-collections-3.2.jar
3.commons-lang-2.3.jar
4.commons-logging-1.0.4.jar
5.ezmorph-1.0.6.jar
6.json-lib-2.1.jar
然后我们创建一个Java Project来演示:
项目源代码:https://github.com/nuptboyzhb/JavaJsonObjectBean
- /*
- * $filename: TestMain.java,v $
- * $Date: 2013-11-28 $
- * Copyright (C) ZhengHaibo, Inc. All rights reserved.
- * This software is Made by Zhenghaibo.
- */
- package edu.njupt.zhb;
- import java.util.ArrayList;
- import java.util.List;
- import net.sf.json.JSONObject;
- /*
- *@author: ZhengHaibo
- *web: http://blog.csdn.net/nuptboyzhb
- *mail: zhb931706659@126.com
- *2013-11-28 Nanjing,njupt,China
- */
- public class TestMain {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- BeanModel saveBeanModel = getInitBean();
- String clazzType = saveBeanModel.getClass().getName();
- String jsonString = JSONObject.fromObject(saveBeanModel).toString();
- printObject(saveBeanModel);//先打印一下看看
- ////////////////我们可以通过clazzType和jsonString,在程序中重新生成saveBeanModel对象
- JSONObject jsonObject = JSONObject.fromObject(jsonString);
- try {
- Object object = JSONObject.toBean(jsonObject, Class.forName(clazzType));
- /////////////////////此时的object就是我们由clazzType和jsonString两个属性恢复出的对象
- printObject(object);
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static BeanModel getInitBean(){
- List<BeanModel> list = new ArrayList<BeanModel>();
- for(int i = 0;i<10;i++){
- BeanModel beanModel = new BeanModel();
- beanModel.setDate(new java.util.Date());
- beanModel.setId(i);
- beanModel.setName("name"+i);
- }
- BeanModel saveBeanModel = new BeanModel();
- saveBeanModel.setId(11);
- saveBeanModel.setDate(new java.util.Date());
- saveBeanModel.setName("saveBean");
- saveBeanModel.setList(list);
- return saveBeanModel;
- }
- public static void printObject(Object object){
- String result = JSONObject.fromObject(object).toString();
- System.out.println("结果:"+result);
- }
- }
BeanModel.java
- /*
- * $filename: BeanModel.java,v $
- * $Date: 2013-11-28 $
- * Copyright (C) ZhengHaibo, Inc. All rights reserved.
- * This software is Made by Zhenghaibo.
- */
- package edu.njupt.zhb;
- import java.util.Date;
- import java.util.List;
- /*
- *@author: ZhengHaibo
- *web: http://blog.csdn.net/nuptboyzhb
- *mail: zhb931706659@126.com
- *2013-11-28 Nanjing,njupt,China
- */
- public class BeanModel {
- private Integer id;
- private Date date;
- private String name;
- private List<BeanModel> list;
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Date getDate() {
- return date;
- }
- public void setDate(Date date) {
- this.date = date;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public List<BeanModel> getList() {
- return list;
- }
- public void setList(List<BeanModel> list) {
- this.list = list;
- }
- }
注意:对于我们“恢复”的对象,我们可以使用Hibernate的getCurrentSession进行保存操作。但是,如果使用getCurrentSession来更新或删除这个对象,那么Hibernate就会报错。此时,我们需要使用Hibernate的sessionFactory.openSession方法,获得Session,然后再执行更新或者删除操作。
未经允许不得用于商业目的