SDO,简单理解就是EMF的脱机版。类似于resultSet和DataSet。可用于smartclient等脱机数据加工场合。
主要特点:(个人理解)
可验证
强类型
可取出完整数据和差异。

生成SDO代码和EMF大同小异,主要是在my.genmodel的第一个节点的右键菜单中选择:Set SDO defaults.

体验:
1. 生成Editor后,执行生成的Editor Plugin
2. 新建Example EMF Model Creation Wizards->Data Graph Model
3. 在Changes节点上Start Loggin, 然后编辑数据即可看到自动生成的差异。

网上手工操作SDO的示例代码比较少,这里简单demo如下:
import java.util.Iterator;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.sdo.EDataGraph;
import org.eclipse.emf.ecore.sdo.SDOFactory;
import org.steeven.family.FamilyFactory;
import org.steeven.family.个人;
import org.steeven.family.家庭;

import commonj.sdo.ChangeSummary;
import commonj.sdo.DataGraph;
import commonj.sdo.DataObject;

public class Server {

    
public static void main(String[] args) {
        
// client side
        EDataGraph graph = loadGraph();
        graph.getChangeSummary().beginLogging(); // important!
        家庭 family 
= (家庭) graph.getRootObject();
        family.setTitle(
"my family");
        个人 baby 
= FamilyFactory.INSTANCE.create个人();
        baby.set姓名(
"sophie");
        family.get兔崽子().add(baby);
        graph.getChangeSummary().endLogging();
        saveGraph(graph);
        update(graph);
    }


    
//server side
    public static EDataGraph loadGraph() {
        家庭 family 
= FamilyFactory.INSTANCE.create家庭(); // or load from
        
// database
        EDataGraph graph = SDOFactory.eINSTANCE.createEDataGraph();
        graph.setERootObject((EObject) family);
        
return graph;
    }


    
//server side full save
    public static void saveGraph(EDataGraph graph) {
        System.out.println(graph.getRootObject());
    }


    
//server side update changed objects
    public static void update(DataGraph dataGraph) {
        ChangeSummary changeSummary 
= dataGraph.getChangeSummary();
        
for (Iterator it = changeSummary.getChangedDataObjects().iterator(); it
                .hasNext();) 
{
            DataObject changedObject 
= (DataObject) it.next();
            System.out.println(
"Update for " + changedObject);
            
for (Iterator settingIt = changeSummary.getOldValues(changedObject)
                    .iterator(); settingIt.hasNext();) 
{
                ChangeSummary.Setting changeSetting 
= (ChangeSummary.Setting) settingIt
                        .next();
                System.out.println(
" (changed "
                        
+ changeSetting.getProperty().getName() + " from \""
                        + changeSetting.getValue() + "\" to \""
                        
+ changedObject.get(changeSetting.getProperty())
                        
+ "\")");
            }

        }

    }

}

输出:
org.steeven.family.impl.家庭Impl@9664a1 (title: my family)
Update for org.steeven.family.impl.个人Impl@1729854 (姓名: sophie, 性别: 男)
Update for org.steeven.family.impl.家庭Impl@9664a1 (title: my family)
 (changed title from "null" to "my family")
 (changed 兔崽子 from "[]" to "[org.steeven.family.impl.个人Impl@1729854 (姓名: sophie, 性别: 男)]")

SDO生成的代码似乎更加纯净一点,没有很多的eXxxx()方法(有需要的也可以取到)。
据说log的开销比较大,不建议对大量数据使用。