2012年9月24日星期一

Coherence_008:Coherence入门指南之八:复合主键和Affinity


运行环境:JDeveloper 11.1.2.2.0 + Coherence3.7.1 + Oracle Database 10g Express Edition 10.2.0.1。

在前面的实验中,我们使用的都是单一属性作为Key,在本实验中我们将定义一个主键类作为Key,并且利用Affinity特性,把具有相同属性值的数据放到同一缓存分区中。

1. 代码
(1)PersonComposited.java 可序列化的Person对象,其中定义了一个内部主键类:Key
package com.oracle.coherence.handson;


import com.tangosol.io.ExternalizableLite;
import com.tangosol.net.cache.KeyAssociation;
import com.tangosol.util.ExternalizableHelper;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class PersonComposited implements ExternalizableLite {

    private int id;
    private String surname;
    private String firstname;
    private String address;
    private int age;
    private String gender;

    public static String MALE = "M";
    public static String FEMALE = "F";

    public PersonComposited() {
    }

    public PersonComposited(int id1, String surname1, String firstname1, String address1, int age1, String gender1) {
        super();
        this.id = id1;
        this.surname = surname1;
        this.firstname = firstname1;
        this.address = address1;
        this.age = age1;
        this.gender = gender1;
    }

    public Key getKey() {
        return new Key(this);
    }


    public void setId(int param) {
        this.id = param;
    }

    public int getId() {
        return id;
    }

    public void setSurname(String param) {
        this.surname = param;
    }

    public String getSurname() {
        return surname;
    }

    public void setFirstname(String param) {
        this.firstname = param;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setAddress(String param) {
        this.address = param;
    }

    public String getAddress() {
        return address;
    }

    public void setAge(int param) {
        this.age = param;
    }

    public int getAge() {
        return age;
    }

    public void setGender(String param) {
        this.gender = param;
    }

    public String getGender() {
        return gender;
    }

    public double getAgeDouble() {
        return (double)this.age;
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!(object instanceof PersonComposited)) {
            return false;
        }
        final PersonComposited other = (PersonComposited)object;
        if (id != other.id) {
            return false;
        }
        if (!(surname == null ? other.surname == null : surname.equals(other.surname))) {
            return false;
        }
        if (!(firstname == null ? other.firstname == null : firstname.equals(other.firstname))) {
            return false;
        }
        if (!(address == null ? other.address == null : address.equals(other.address))) {
            return false;
        }
        if (age != other.age) {
            return false;
        }
        if (!(gender == null ? other.gender == null : gender.equals(other.gender))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        final int PRIME = 37;
        int result = 1;
        result = PRIME * result + ((surname == null) ? 0 : surname.hashCode());
        result = PRIME * result + ((firstname == null) ? 0 : firstname.hashCode());
        result = PRIME * result + ((address == null) ? 0 : address.hashCode());
        result = PRIME * result + ((gender == null) ? 0 : gender.hashCode());
        return result;
    }

    public void readExternal(DataInput dataInput) throws IOException {
        this.id = ExternalizableHelper.readInt(dataInput);
        this.surname = ExternalizableHelper.readSafeUTF(dataInput);
        this.firstname = ExternalizableHelper.readSafeUTF(dataInput);
        this.address = ExternalizableHelper.readSafeUTF(dataInput);
        this.gender = ExternalizableHelper.readSafeUTF(dataInput);
        this.age = ExternalizableHelper.readInt(dataInput);
    }

    public void writeExternal(DataOutput dataOutput) throws IOException {
        ExternalizableHelper.writeInt(dataOutput, this.id);
        ExternalizableHelper.writeSafeUTF(dataOutput, this.surname);
        ExternalizableHelper.writeSafeUTF(dataOutput, this.firstname);
        ExternalizableHelper.writeSafeUTF(dataOutput, this.address);
        ExternalizableHelper.writeSafeUTF(dataOutput, this.gender);
        ExternalizableHelper.writeInt(dataOutput, this.age);
    }

    public static class Key implements ExternalizableLite, KeyAssociation {

        // lets define a key of id and version
        private int id;
        private int version;
        private String surname;

        public Key() {
            //for serializble
        }

        public Object getAssociatedKey() {
            return surname;
        }

        public Key(int id, int version) {
            this.id = id;
            this.version = version;
        }

        public Key(PersonComposited p) {
            this.id = p.getId();
            this.version = 1; // default
            this.surname = p.getSurname();  // 运行KeyTest时,这行要注释掉
        }

        public void writeExternal(DataOutput dataOutput) throws IOException {
            ExternalizableHelper.writeInt(dataOutput, this.id);
            ExternalizableHelper.writeInt(dataOutput, this.version);
            ExternalizableHelper.writeSafeUTF(dataOutput, this.surname);
        }

        public void readExternal(DataInput dataInput) throws IOException {
            this.id = ExternalizableHelper.readInt(dataInput);
            this.version = ExternalizableHelper.readInt(dataInput);
            this.surname = ExternalizableHelper.readSafeUTF(dataInput);
        }

        @Override
        public boolean equals(Object object) {
            if (this == object) {
                return true;
            }
            if (!(object instanceof PersonComposited.Key)) {
                return false;
            }
            final PersonComposited.Key other = (PersonComposited.Key)object;
            if (id != other.id) {
                return false;
            }
            if (version != other.version) {
                return false;
            }
            if (surname != other.surname) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            final int PRIME = 37;
            int result = 1;
            return result;
        }
    }
}

(2)KeyTester.java 用于测试复合主键类

package com.oracle.coherence.handson;


import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;

public class KeyTester {
    public KeyTester() {
    }

    public static void main(String[] args) {
     
        NamedCache person = CacheFactory.getCache("person");
     
        PersonComposited p = new PersonComposited(1,"Middleton","Tim","Address",29,Person.MALE);
     
        person.put(p.getKey(), p);
     
        //PersonComposited p2 = (PersonComposited)person.get(p.getKey());
        PersonComposited p2 = (PersonComposited)person.get(new PersonComposited.Key(1, 1));
     
        System.out.println("Person is " + p2.getSurname() + " " +  p2.getSurname());
                
    }
}

(3)KeyTester2.java 用于测试Affinity

package com.oracle.coherence.handson;


import com.tangosol.net.CacheFactory;
import com.tangosol.net.DistributedCacheService;
import com.tangosol.net.Member;
import com.tangosol.net.NamedCache;

import java.util.LinkedList;

public class KeyTester2 {
    public KeyTester2() {
    }

    public static void main(String[] args) {
     
        NamedCache person = CacheFactory.getCache("person");
        LinkedList peopleList = new LinkedList();
     
        // build the list
        peopleList.add( new PersonComposited(1,"Flinstone","Fred","Address",29,PersonComposited.MALE));
        peopleList.add( new PersonComposited(2,"Flinstone","Wilma","Address",29,PersonComposited.FEMALE));
        peopleList.add( new PersonComposited(3,"Rubble","Barney","Address",44,PersonComposited.MALE));
        peopleList.add( new PersonComposited(4,"Rubble","Betty","Address",44,PersonComposited.FEMALE));
        peopleList.add( new PersonComposited(5,"Rubble","Dino","Address",44,PersonComposited.FEMALE));
     
        for (java.util.Iterator iterator = peopleList.iterator(); iterator.hasNext();) {
             
                PersonComposited p = (PersonComposited)iterator.next();
                person.put(p.getKey(), p);
         
                Member m = ((DistributedCacheService)person.getCacheService()).getKeyOwner(p.getKey());
                System.out.println("Person " + p.getFirstname() + " " + p.getSurname() +
                                   " is owned by member " + m.getId());
        }
     

    }
}

(4)WhereAreYouProcessor.java 查看数据到底是保存在哪个Cache节点上
package com.oracle.coherence.handson;

import com.tangosol.util.InvocableMap.Entry;
import com.tangosol.util.processor.AbstractProcessor;

public class WhereAreYouProcessor extends AbstractProcessor {
    public WhereAreYouProcessor() {
    }
 
    public Object process(Entry entry ) {
        PersonComposited p = (PersonComposited)entry.getValue();
        System.out.println("\nHello from " + p.getFirstname() + " " + p.getSurname() + "\n");
        return null;
    }
}

(5)EntryProcessorExample.java 执行WhereAreYouProcessor
package com.oracle.coherence.handson;


import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.util.filter.AlwaysFilter;

import java.util.LinkedList;

public class EntryProcessorExample {
    public EntryProcessorExample() {
    }

    public static void main(String[] args) {
     
        NamedCache person = CacheFactory.getCache("person");
        LinkedList peopleList = new LinkedList();
     
        // build the list
        peopleList.add( new PersonComposited(1,"Flinstone","Fred","Address",29,Person.MALE));
        peopleList.add( new PersonComposited(2,"Flinstone","Wilma","Address",29,Person.FEMALE));
        peopleList.add( new PersonComposited(3,"Rubble","Barney","Address",44,Person.MALE));
        peopleList.add( new PersonComposited(4,"Rubble","Betty","Address",44,Person.FEMALE));
        peopleList.add( new PersonComposited(5,"Rubble","Dino","Address",44,Person.FEMALE));
     
        for (java.util.Iterator iterator = peopleList.iterator(); iterator.hasNext();) {
             
                PersonComposited p = (PersonComposited)iterator.next();
                person.put(p.getKey(), p);          
        }
     
        // now run the entry processor to display where they are!
        person.invokeAll(AlwaysFilter.INSTANCE, new WhereAreYouProcessor());
    }
}

2. 运行
(1)选择运行DefaultCacheServer Profile,作为存储数据的Cache。
(2)选择NoLocalStorage Profile,并运行KeyTester,根据复合主键获取对象。
(3)选择运行DefaultCacheServer Profile,再增加一个Cache节点。
(4)选择NoLocalStorage Profile,并运行KeyTester2,会发现surname相同的数据在同一个Cache节点上。
(5)选择NoLocalStorage Profile,并运行EntryProcessorExample,会发现surname相同的数据在同一个Cache Console中输出。

Project 下载:CoherenceApp(Lab8).7z

没有评论: