<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>


    隨筆-35  評論-97  文章-0  trackbacks-0

    EasyDBO上對象關(guān)聯(lián)還是存在很大問題。

    其中一個,添加對象時,沒能將被關(guān)聯(lián)對象的主鍵(由數(shù)據(jù)庫生成)插入到關(guān)聯(lián)對象的外鍵上。

    注:

    (1) EasyDBO的一對一關(guān)聯(lián)中,外鍵在關(guān)聯(lián)對象方。

    Class A{

    .....

    B b ;

    }

     

    Class B{

    }

    對應(yīng)于實(shí)體A的數(shù)據(jù)庫表有外鍵,如 fk_b

     

    (2) EasyDBO的一對多關(guān)聯(lián)中,外鍵在被關(guān)聯(lián)對象方(多方)。

    Class A{

    .....

    List<B> bList ;

    }

     

    Class B{

    A a;

    }

    對應(yīng)于實(shí)體B的數(shù)據(jù)庫表有外鍵,如 fk_a

     

    在解決這個問題中,對源碼做一些的修改:

    1、首先解決如果是數(shù)據(jù)庫生成的主鍵(如auto_increment類型),在DatabaseDAO添加getGeneratedKey()方法。

        public Serializable getGeneratedKey()
        
    {
            
    if(prepared==null){
                
    return null;
            }

            Serializable ret 
    =null;
            ResultSet rs 
    = null;
            
    try
            
    {
                rs 
    = prepared.getGeneratedKeys();
                
    if(rs.next())
                
    {
                    ret 
    = (Serializable)rs.getObject(1);
                    logger.info(
    "get the GeneratedKey:" + ret);
                }

            }

            
    catch(SQLException e)
            
    {
                e.printStackTrace();
            }

            
    finally
            
    {
                
    if(rs != null)
                    
    try
                    
    {
                        rs.close();
                    }

                    
    catch(SQLException e)
                    
    {
                        e.printStackTrace();
                    }

            }

            
    return ret;
        }

    2、在EasyJDBEngine中添加generatedKey字段和getter方法。

        private Serializable generatedKey;
        
        
        
    public Serializable getGeneratedKey()
        
    {
            
    return generatedKey;
        }

       在EasyJDBEngine的public boolean add(DBObject obj)方法中try的括號末尾添加

    generatedKey  = dba.getGeneratedKey();

        public boolean add(DBObject obj) // 添加一個對象
            ...
            
    try {

                        ...... 
                generatedKey  = dba.getGeneratedKey();
            }
     catch (Exception e) {

    3、EasyJDB中添加以下方法:

        private Object setObjectGenIdValue(Object obj){
            BeanWrapper wrapper 
    = new BeanWrapper(obj);
            DBTable dbTable 
    = findTable(obj.getClass());
            String idFieldName 
    = dbTable.getPoperty(dbTable.getId());
            
    if(wrapper.getPropertyValue(idFieldName)==null && StringUtils.isNotEmpty(dbEngine.getGeneratedKey())){
                Object javaPropertyValue 
    = wrapper.convertIfNecessary(String.valueOf(dbEngine.getGeneratedKey()),
                                                                        dbTable.getType(idFieldName));
                wrapper.setPropertyValue(idFieldName, javaPropertyValue);
                System.out.println(
    "setting id.");
                
    return javaPropertyValue;
            }

            
    return null;
        }


        
    private Object getObjectIdValue(Object obj){
            BeanWrapper wrapper 
    = new BeanWrapper(obj);
            DBTable dbTable 
    = findTable(obj.getClass());
            String idFieldName 
    = dbTable.getPoperty(dbTable.getId());
            
    if(StringUtils.isNotEmpty(wrapper.getPropertyValue(idFieldName))){
                
    return wrapper.getPropertyValue(idFieldName);
            }

            
    return null;
        }


        
    private void setClassFieldValue(Object target,ClassField classField,Object value){
            BeanWrapper wi
    =new BeanWrapper(target);
            DBTable dbTable 
    = findTable(target.getClass());
            wi.setPropertyValue(dbTable.getPoperty(classField.getColumn()),value);
        }

    EasyJDB中的public boolean add(Object obj)方法改為:

        public boolean add(Object obj)
        
    {
            logger.debug(
    "把對象obj保存到數(shù)據(jù)庫中");
             
    boolean ret = dbEngine.add(obj2dbo(obj));
             setObjectGenIdValue(obj);
    ///如果是新添加的記錄,且主鍵為數(shù)據(jù)庫生成,那么將主鍵值返回賦給對象
             if(ret)ret = ret & addRelativeObject(obj);
            
    return ret;
        }

     

     EasyJDB中的private boolean addRelativeObject(Object obj)方法改為:

     

        private boolean addRelativeObject(Object obj)
        
    {
            
    boolean ret = true;
            DBTable table 
    = findTable(obj.getClass());
            
    if(table != null)
            
    {
                BeanWrapper wrapper 
    = new BeanWrapper(obj);
                java.util.Iterator it 
    = table.getClassField().entrySet().iterator();
                
    while(it.hasNext())
                
    {
                    
    // 嘗試處理其它字段
                    Map.Entry en = (Map.Entry)it.next();
                    String propertyName 
    = (String)en.getKey();
                    ClassField classField 
    = (ClassField)en.getValue();
                    
    // System.out.println(classField.getClass()+":"+propertyName);
                    if(classField instanceof ManyToManyField && wrapper.isReadableProperty(propertyName))
                    
    {
                        
    // 處理多對多
                        Object value = wrapper.getPropertyValue(propertyName);
                        
    // System.out.println("值內(nèi)容"+value.getClass());
                        if(value != null && value instanceof Collection)
                        
    {
                            java.util.Iterator es 
    = ((Collection)value).iterator();
                            
    while(es.hasNext())
                            
    {
                                Object element 
    = es.next();
                                ret 
    = ret & this.saveOrUpdate(element);
                                
    // 保存關(guān)聯(lián)的第三方表
                                ManyToManyField field = (ManyToManyField)classField;
                                
    /*
                                 * DBTable table2=findTable(element.getClass());
                                 * if(table2!=null) { ManyToManyField field2=null;
                                 * java.util.Iterator
                                 * inf2=table2.getClassField().values().iterator();
                                 * while(inf2.hasNext()) { ClassField
                                 * ff=(ClassField)inf2.next();
                                 * if(ff.getTableName().equals(field.getTableName()) &&
                                 * ff.getType()==obj.getClass()) {
                                 * field2=(ManyToManyField)ff; } }
                                 
    */

                                String sql 
    = "insert into " + field.getTableName() + "(" + classField.getColumn() + ","
                                                
    + field.getTagColumn() + ") values(?,?)";
                                java.util.Collection paras 
    = new java.util.ArrayList();
                                paras.add(wrapper.getPropertyValue(classField.getKey()));
                                BeanWrapper wrapper2 
    = new BeanWrapper(element);
                                paras.add(wrapper2.getPropertyValue(field.getTagKey()));
                                
    try
                                
    {
                                    
    this.execute(sql, paras);
                                }

                                
    catch(Exception e)
                                
    {
                                    logger.error(
    "插入多對多關(guān)系時出錯!");
                                    e.printStackTrace();
                                }

                                
    // }
                            }

                        }

                    }

                    
    else if((classField instanceof ManyToOneField) && wrapper.isReadableProperty(propertyName))
                    
    {
                        
    // 處理一對多
                        Object value = wrapper.getPropertyValue(propertyName);
                        
    if(value != null && value instanceof Collection)
                        
    {
                            java.util.Iterator es 
    = ((Collection)value).iterator();
                            
    while(es.hasNext())
                            
    {
                                Object item 
    = es.next();
                                setClassFieldValue(item,classField,obj);
    //設(shè)置關(guān)聯(lián)值
                                ret = ret & this.saveOrUpdate(item);
                            }

                        }

                    }

                    
    else if((classField instanceof OneToOneField) && wrapper.isReadableProperty(propertyName))
                    
    {
                        
    // 處理一對一
                        Object value = wrapper.getPropertyValue(propertyName);
                        
    if(value != null)
                        
    {
                            ret 
    = ret & this.saveOrUpdate(value);
                            
    if(StringUtils.isNotEmpty(getObjectIdValue(value)))
                            
    {
                                setClassFieldValue(obj, classField, value);
    //設(shè)置關(guān)聯(lián)值
                                update(obj);//更新一下數(shù)據(jù),將關(guān)聯(lián)的對象主鍵作為外鍵
                            }

                        }

                    }

                }

            }

            
    return ret;
        }

    EasyJDB中的public boolean update(Object obj)方法改為:

        public boolean update(Object obj)
        
    {
            logger.info(
    "更新持久層中的數(shù)據(jù)表對象");
            
    boolean ret = dbEngine.update(obj2dbo(obj));
    //        ret = ret & this.addRelativeObject(obj);//這句很容易會導(dǎo)致死循環(huán),先不要了
            return ret;
        }

    EasyJDB中的public boolean saveOrUpdate(Object obj)方法改為:

        public boolean saveOrUpdate(Object obj)
        
    {
            
    // logger.info("把對象持久化到數(shù)據(jù)庫中,先償試添加,若無法保存則執(zhí)行修改操作");
            boolean ret = false;
            
    try
            
    {
                Object id 
    = getObjectIdValue(obj);
                
                
    if(id == null)
                
    {
                    ret 
    = add(obj);
                }


                
    else
                
    {
                    
    if(get(obj.getClass(), id) != null)
                        ret 
    = update(obj);
                    
    else
                        ret 
    = add(obj);
                }

            }

            
    catch(Exception e)
            
    {
                
    //這里的也先不要的,很容易導(dǎo)致死循環(huán)
                
    // 出錯,進(jìn)一步嘗試使用原始的方法進(jìn)行更改
    //            if(add(obj))
    //            {
    //                return true;
    //            }
    //            return update(obj);
                e.printStackTrace();
            }

            
    return ret;
        }

     

    解釋一下:

    這里處理的不包括多對多的關(guān)系,很少用到,暫時不管。

    解決的思路是,如果是自增(數(shù)據(jù)庫生成的id),那么獲取這個id,并回賦給對象,對象有了主鍵值(每個這樣的對象都回賦主鍵值),關(guān)聯(lián)就有了導(dǎo)航。

    在一對一關(guān)系處理中,因?yàn)槭窍炔迦腙P(guān)聯(lián)對象數(shù)據(jù),然后在插入被關(guān)聯(lián)對象數(shù)據(jù)。但是關(guān)聯(lián)對象需要知道被關(guān)聯(lián)的主鍵值,而被關(guān)聯(lián)的主鍵值是在最后插入數(shù)據(jù)后回賦的,所以,采取從新將對象關(guān)聯(lián),并更新數(shù)據(jù)。

           setClassFieldValue(obj, classField, value);//設(shè)置關(guān)聯(lián)值
           update(obj);//更新一下數(shù)據(jù),將關(guān)聯(lián)的對象主鍵作為外鍵

    在處理一對多(也即多對一)關(guān)系中,如一開就提到的“EasyDBO的一對多關(guān)聯(lián)中,外鍵在被關(guān)聯(lián)對象方(多方)”,數(shù)據(jù)插入順序同一對一的一樣,先關(guān)聯(lián)對象,后被關(guān)聯(lián)對象,所以,在這里只需要在被關(guān)聯(lián)對象插入前更新關(guān)聯(lián)就可以了

    setClassFieldValue(item,classField,obj);//設(shè)置關(guān)聯(lián)值

    比較明顯,將一對多的關(guān)系轉(zhuǎn)換成了多個一對一了。或許這樣不是很好,但是,在原有的架構(gòu)上,比較難做更大修改。

     

    EasyDBO有一些主鍵生成器的,不知對對象關(guān)聯(lián)上主鍵的處理上有沒有獨(dú)特的解決方法,待探索...

    淺見,不當(dāng)?shù)牡胤綒g迎指正~~~~~~~~

    posted on 2007-07-02 18:15 三告習(xí)習(xí) 閱讀(1194) 評論(3)  編輯  收藏 所屬分類: easyJF-projects

    評論:
    # re: [EasyDBO] EasyDBO上對象關(guān)聯(lián)問題的一個簡單解決方法 2007-07-19 12:13 | hingwu
    我在前面的項目中也使用到了EasyJDB,也發(fā)現(xiàn)了不少bug,有些甚至是莫名其妙的錯誤,希望以后有得提升。  回復(fù)  更多評論
      
    # re: [EasyDBO] EasyDBO上對象關(guān)聯(lián)問題的一個簡單解決方法 2007-07-19 17:29 | John Ong
    這種shit framework 不用也罷!  回復(fù)  更多評論
      
    # re: [EasyDBO] EasyDBO上對象關(guān)聯(lián)問題的一個簡單解決方法 2007-07-19 21:44 | 三告習(xí)習(xí)
    @John Ong
    盡管不是很完善,從中還能學(xué)到多少東西的,至少能提醒自己寫的時候不要這樣冒險,在處理這些地方需要慎重些
      回復(fù)  更多評論
      
    主站蜘蛛池模板: 伊人久久免费视频| 一级黄色免费网站| **aaaaa毛片免费| 亚洲理论电影在线观看| 女人裸身j部免费视频无遮挡| 免费看美女让人桶尿口| 亚洲av色香蕉一区二区三区| 69式国产真人免费视频| 亚洲AV一二三区成人影片| AV免费网址在线观看| 亚洲中文字幕无码久久2020| 日韩免费毛片视频| 国产亚洲Av综合人人澡精品| 国产乱色精品成人免费视频| 日本永久免费a∨在线视频| 亚洲午夜爱爱香蕉片| 日本一区午夜艳熟免费| 亚洲视频.com| 中文字幕av无码无卡免费| 亚洲欧美第一成人网站7777 | 免费国产高清毛不卡片基地 | 亚洲欧洲AV无码专区| 国产精品免费综合一区视频| 黄色a级片免费看| 亚洲精品狼友在线播放| 中文免费观看视频网站| 亚洲高清毛片一区二区| 亚洲美女高清一区二区三区 | 国产亚洲蜜芽精品久久| 自拍偷自拍亚洲精品情侣| 97av免费视频| 亚洲.国产.欧美一区二区三区| 亚洲午夜爱爱香蕉片| 最近免费mv在线电影| 久久精品国产亚洲av天美18| 在线A亚洲老鸭窝天堂| 精品香蕉在线观看免费| 午夜在线免费视频 | 亚洲国产综合精品中文字幕| a级日本高清免费看| 亚洲最大福利视频|