问题的提出:

在开发的过程中,我们会遇到这样的问题,在订单中订单的所属人,这个数据设计时有用户id,用户名称,联系信息等等。这样做的好处是不用关联到系统用户表做数据关联。

问题是如果用户表的基础信息发生了修改,那么这个时候,希望修改订单相应用户信息。

 

解决方案

方案1.

使用数据库触发器,这个修改相对简单,而且不用修改java代码。

缺点:

有时开发人员可能不能直接接触数据库,无法通过此方式实现。

方案2:

使用代码处理,如果直接在用户编辑时对业务表进行修改,这样肯定是不合理的,问题在于这样每次增加一个业务我们都需要这个用户代码进行修改。这样不满足封闭开放原则。

现在的解决方案是:

1.在用户编辑时,发布一个事件。

2.写监听器监视这个事件。

3.在信息修改时调用这个代码发布事件。

这样用户编辑类就不需要做任何更改,发布事件就是了,这个事件可以被系统监听,也可以不监听,这样代码就

 

实现了解耦。

 

具体代码如下:

1.定义事件对象:

public class DataModel {
    private String pk="";
    private String tableName="";
    private String action="";

}

2.定义事件

public class UpdDataEvent extends ApplicationEvent {
   
    /**
     *
     */
    private static final long serialVersionUID = -656796814656037536L;

    public UpdDataEvent(Object source) {
        super(source);
    }

}

3.定义事件监听器。

public class UpdateDataListener implements ApplicationListener<UpdDataEvent> {
   
    @Resource(name="jdbcTemplate")
    JdbcTemplate jdbcTemplate;
   
    private Map<String,List<String>> sqlMap=new HashMap<String, List<String>>();

    @Override
    public void onApplicationEvent(UpdDataEvent event) {
        DataModel dataModel=(DataModel) event.getSource();
        String id=dataModel.getPk();
        String tableName=dataModel.getTableName();
       
        List<String> sqlList=sqlMap.get(tableName);
       
        for(String sql:sqlList){
            jdbcTemplate.update(sql, id);
        }
    }
   
    public void setSqlMap(Map<String,List<String>> map){
        this.sqlMap=map;
    }

}

 

从外部注入sql map。

这个map键是表名,值为List,这个列表对应了sql语句。

oracle下这个sql语句的写法为:

UPDATE QINGJIA a  SET(username) =(SELECT b.fullname FROM sys_user b WHERE b.userid = a.userid) WHERE a.userid=?

必须为一个参数。

 

4.配置文件的写法:

<bean id="updateDataListener" class="com.hotent.core.datahandler.UpdateDataListener">
        <property name="sqlMap">
            <map>

<!--这个为表名,需要和发布事件时保持一直,请统一小写—> 
                <entry key="biaoming">
                    <list>

<!--待更新的sql语句,可以配置多条—>
                        <value type="java.lang.String">
                            UPDATE QINGJIA a  SET(username) =(SELECT b.fullname FROM sys_user b WHERE b.userid = a.userid) WHERE a.userid=?
                        </value>
                    </list>
                </entry>
            </map>
        </property>
    </bean>

 

 


5.发布事件

public class DataPublishUtil {
   
    /**
     * 发布事件。
     * @param model
     */
    public static void publishData(DataModel model){
        AppUtil.publishEvent(new UpdDataEvent(model));
    }
   
    /**
     * 发布事件。
     * @param tableName
     * @param pk
     */
    public static void publishData(String tableName ,String pk){
        DataModel model=new DataModel();
        model.setPk(pk);
        model.setTableName(tableName);
        AppUtil.publishEvent(new UpdDataEvent(model));
    }

}

 

在需要的地方比如用户编辑时,调用相关方法。

publishData(String tableName ,String pk)

参数说明:

tableName :表名这个需要约定和配置文件中的保持一致。

pk: 主键数据

posted on 2015-01-12 17:26  自由港  阅读(742)  评论(2编辑  收藏  举报