Emerging Technology
Fall Semester, 2004 Mapping Collections |
||
---|---|---|
© 2004, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 02-Dec-04 |
CS 683 Emerging Technologies Fall Semester, 2004 Doc 32 Mapping Collections
Copyright ©, All rights reserved. 2004 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA. OpenContent ( http://www.opencontent.org/opl.shtml) license defines the copyright on this document
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 2 |
Hibernate Reference 2.1.6
Online html version http://www.hibernate.org/hib_docs/reference/en/html/
Other versions (including Chinese) at: http://www.hibernate.org/5.html
Glorp Tutorial, Whitney
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 3 |
Types of Collections
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 4 |
Allows repeats of elements
Order is not important
Hibernate uses List to implement a bag
Order of elements added to the database is not preserved
Example is the Person-EmailAddresses of doc 31
id |
first_name |
last_name |
1 |
Roger |
Whitney |
2 |
Leland |
Beck |
id |
user_name |
host |
person_id |
1 |
beck |
cs.sdsu.edu |
2 |
2 |
whitney |
cs.sdsu.edu |
1 |
3 |
whitney |
rohan.sdsu.edu |
1 |
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 5 |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="cs683"> <class name="Person" table="people"> <id name="id" type="long" column="id"> <generator class="increment"/> </id> <bag name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES"> <key column="person_id"/> <one-to-many class="cs683.EmailAddress" /> </bag> <property name="lastName" column="last_name" type="string" not-null="false" length="50"/> <property name="firstName" column="first_name" type="string" not-null="false" length="50"/> </class> </hibernate-mapping>
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 6 |
package cs683; import java.util.*; public class Person { String firstName; String lastName; List addresses = new ArrayList();; long id; public Person () { super(); } public Person(String first, String last) { firstName = first; lastName = last; } public List getAddresses() { return addresses; } public void setAddresses(List addresses) { this.addresses = addresses; } public void addAddress(EmailAddress newAddress) { addresses.add( newAddress); newAddress.setOwner(this); } public String getLastName() { return lastName; } public String getFirstName() { return firstName; } public void setFirstName( String name) { firstName = name; } public void setLastName( String name) { lastName = name; } public long getId() { return id; } public void setId(long l) { id = l; } public String toString() { return firstName + " " + lastName + id; } }
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 7 |
ArrayList & Vector are lists
Order of elements in the list are preserved
id |
first_name |
last_name |
1 |
Roger |
Whitney |
2 |
Leland |
Beck |
3 |
Carl |
Eckberg |
id |
user_name |
host |
person_id |
Position |
1 |
beck |
cs.sdsu.edu |
2 |
0 |
2 |
whitney |
cs.sdsu.edu |
1 |
0 |
3 |
whitney |
rohan.sdsu.edu |
1 |
1 |
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 8 |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="cs683"> <class name="Person" table="people" > <id name="id" type="long" column="id" > <generator class="increment"/> </id> <list name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES"> <key column="person_id"/> <index column="position"> </index> <one-to-many class="cs683.EmailAddress" /> </list> properties same as last example </class> </hibernate-mapping>
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 9 |
package cs683; import java.util.*; public class Person { String firstName; String lastName; List addresses = new ArrayList(); long id; public Person () { super(); } public Person(String first, String last) { firstName = first; lastName = last; } public List getAddresses() { return addresses; } public void setAddresses(List addresses) { this.addresses = addresses; } public void addAddress(EmailAddress newAddress) { addresses.add( newAddress); newAddress.setOwner(this); }
rest same as last example
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 10 |
Java arrays are not Collection classes
id |
first_name |
last_name |
1 |
Roger |
Whitney |
2 |
Leland |
Beck |
id |
user_name |
host |
person_id |
Position |
1 |
beck |
cs.sdsu.edu |
2 |
0 |
2 |
whitney |
cs.sdsu.edu |
1 |
0 |
3 |
whitney |
rohan.sdsu.edu |
1 |
1 |
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 11 |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="cs683"> <class name="Person" table="people"> <id name="id" type="long" column="id" > <generator class="increment"/> </id> <array name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES"> <key column="person_id"/> <index column="position" /> <one-to-many class="cs683.EmailAddress" /> </array>
Rest is same as before
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 12 |
package cs683; public class Person { String firstName; String lastName; EmailAddress[] addresses = new EmailAddress[10]; int endOfList; long id; public Person () {super(); } public Person(String first, String last) { firstName = first; lastName = last; } public EmailAddress[] getAddresses() { return addresses; } public void setAddresses(EmailAddress[] addresses) { this.addresses = addresses; } public void addAddress(EmailAddress newAddress) { addresses[endOfList++]= newAddress; newAddress.setOwner(this); }
rest is as previous examples
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 13 |
TreeMap and TreeSet are examples of sorted collections in Java
Since the collection orders the elements one does not need extra columns in the database
id |
first_name |
last_name |
1 |
Roger |
Whitney |
2 |
Leland |
Beck |
id |
user_name |
host |
person_id |
1 |
beck |
cs.sdsu.edu |
2 |
2 |
whitney |
cs.sdsu.edu |
1 |
3 |
whitney |
rohan.sdsu.edu |
1 |
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 14 |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="cs683"> <class name="Person" table="people" > <id name="id" type="long" column="id" > <generator class="increment"/> </id> <set name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES" sort="natural"> <key column="person_id"/> <one-to-many class="cs683.EmailAddress" /> </set>
etc.
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 15 |
<set name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES" sort="natural">
Sort can be any of
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 16 |
package cs683; import java.util.TreeSet; public class Person { String firstName; String lastName; SortedSet addresses = new TreeSet(); long id; public Person () { super(); } public Person(String first, String last) { firstName = first; lastName = last; } public SortedSet getAddresses() { return addresses; } public void setAddresses(SortedSet addresses) { this.addresses = addresses; } public void addAddress(EmailAddress newAddress) { addresses.add( newAddress); newAddress.setOwner(this); }
etc
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 17 |
public class EmailAddress implements Comparable { String userName; String host; long id; Person owner; public Person getOwner() { return owner; } public int compareTo(Object anEmailAddress) { EmailAddress address = (EmailAddress)anEmailAddress; return (userName + host).compareTo(address.getUserName() + address.getHost()); }
Set/get methods not shown
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 18 |
Permits a sorted collection to
package cs683; import java.util.Comparator; public class EmailComparator implements Comparator { public int compare(Object a, Object b) { EmailAddress first = (EmailAddress)a; EmailAddress last = (EmailAddress)b; return (first.host + first.userName).compareTo(last.host + last.userName); } }
<set name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES" sort="cs683.EmailComparator"> <key column="person_id"/>
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 19 |
HashMap, Hashtable & TreeMap are instances of a map
id |
first_name |
last_name |
1 |
Roger |
Whitney |
2 |
Leland |
Beck |
3 |
Carl |
Eckberg |
id |
user_name |
host |
person_id |
Alias |
1 |
beck |
cs.sdsu.edu |
2 |
chair |
2 |
whitney |
cs.sdsu.edu |
1 |
main |
3 |
whitney |
rohan.sdsu.edu |
1 |
backup |
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 20 |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="cs683"> <class name="Person" table="people" > <id name="id" type="long" column="id" > <generator class="increment"/> </id> <map name="addresses" inverse="false" cascade="all" table="EMAIL_ADDRESSES"> <key column="person_id"/> <index column="alias" type="string" /> <one-to-many class="cs683.EmailAddress" /> </map>
etc.
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 21 |
package cs683; import java.util.HashMap; public class Person { String firstName; String lastName; Map addresses = new HashMap(); long id; public Person () { super(); } public Person(String first, String last) { firstName = first; lastName = last; } public Map getAddresses() { return addresses; } public void setAddresses(Map addresses) { this.addresses = addresses; } public void addAddress(String index, EmailAddress newAddress) { addresses.put(index, newAddress); newAddress.setOwner(this); }
etc
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 22 |
static void sampleWrite() throws MappingException, HibernateException, Exception { Session session = getHibernateSession(); Transaction save = null; try { save = session.beginTransaction(); Person newPerson = new Person("Roger", "Whitney"); EmailAddress a = new EmailAddress("whitney", "cs.sdsu.edu"); EmailAddress b = new EmailAddress("whitney", "rohan.sdsu.edu"); newPerson.addAddress("main", a); newPerson.addAddress("backup", b); session.save(a); session.save(b); session.save(newPerson); newPerson = new Person("Leland", "Beck"); a = new EmailAddress("beck", "cs.sdsu.edu"); newPerson.addAddress("chair", a); session.save(a); session.save(newPerson); newPerson = new Person("Carl", "Eckberg"); session.save(newPerson); save.commit(); } catch (Exception problem)
etc.
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 23 |
Address book contains dictionary of People
id |
first_name |
last_name |
1 |
Leland |
Beck |
2 |
Roger |
Whitney |
id |
title |
1 |
Work |
2 |
Dance |
person_id |
address_book_id |
person_key |
1 |
1 |
Chair |
2 |
1 |
OO |
1 |
1 |
Security |
2 |
2 |
Email Person |
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 24 |
Smalltalk defineClass: #AddressBook superclass: #{Core.Object} indexedType: #none private: false instanceVariableNames: 'id title entries ' classInstanceVariableNames: '' imports: '' category: 'GlorpExperiments'
title: aString ^super new setTitle: aString
at: aString ^entries at: aString at: aString put: aPerson entries at: aString put: aPerson title ^title setTitle: aString title := aString. entries := Dictionary new.
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 25 |
Smalltalk defineClass: #Person superclass: #{Core.Object} indexedType: #none private: false instanceVariableNames: 'firstName lastName id ' classInstanceVariableNames: '' imports: '' category: 'GlorpExperiments'
add needed accessor methods
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 26 |
Smalltalk defineClass: #GlorpTutorialDescriptor superclass: #{Glorp.DescriptorSystem} indexedType: #none private: false instanceVariableNames: '' classInstanceVariableNames: '' imports: 'Glorp.*' category: 'GlorpExperiments' allTableNames ^#( 'PEOPLE' 'ADDRESS_BOOK' 'ADDRESS_BOOK_LINKS' ) constructAllClasses ^(super constructAllClasses) add: Person; add: AddressBook; yourself classModelForAddressBook: aClassModel aClassModel newAttributeNamed: #id. aClassModel newAttributeNamed: #title. aClassModel newAttributeNamed: #entries collection: Dictionary of: Person. classModelForPerson: aClassModel aClassModel newAttributeNamed: #lastName. aClassModel newAttributeNamed: #firstName. aClassModel newAttributeNamed: #id.
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 27 |
descriptorForAddressBook: aDescriptor | table linkTable | table := self tableNamed: 'ADDRESS_BOOK'. linkTable := self tableNamed: 'ADDRESS_BOOK_LINKS'. aDescriptor table: table. aDescriptor addMapping: (DirectMapping from: #id to: (table fieldNamed: 'id')). aDescriptor addMapping: (DirectMapping from: #title to: (table fieldNamed: 'title')). aDescriptor addMapping: ((BasicDictionaryMapping new) attributeName: #entries; referenceClass: Person; keyField: (linkTable fieldNamed: 'person_key'); relevantLinkTableFields: (Array with: (linkTable fieldNamed: 'person_id'))) descriptorForPerson: aDescriptor | personTable | personTable := self tableNamed: 'PEOPLE'. aDescriptor table: personTable. (aDescriptor newMapping: DirectMapping) from: #id to: (personTable fieldNamed: 'id'). (aDescriptor newMapping: DirectMapping) from: #firstName to: (personTable fieldNamed: 'first_name'). (aDescriptor newMapping: DirectMapping) from: #lastName to: (personTable fieldNamed: 'last_name').
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 28 |
tableForADDRESS_BOOK: aTable (aTable createFieldNamed: 'title' type: (platform varChar: 50)). (aTable createFieldNamed: 'id' type: (platform sequence)) bePrimaryKey. tableForADDRESS_BOOK_LINKS: aTable | personId bookId | personId := aTable createFieldNamed: 'person_id' type: platform int4. aTable addForeignKeyFrom: personId to: ((self tableNamed: 'PEOPLE') fieldNamed: 'id'). bookId := aTable createFieldNamed: 'address_book_id' type: (platform varChar: 50). aTable addForeignKeyFrom: bookId to: ((self tableNamed: 'ADDRESS_BOOK') fieldNamed: 'id'). aTable createFieldNamed: 'person_key' type: (platform varChar: 30). tableForPEOPLE: aTable (aTable createFieldNamed: 'first_name' type: (platform varChar: 50)). (aTable createFieldNamed: 'last_name' type: (platform varChar: 50)). (aTable createFieldNamed: 'id' type: (platform sequence)) bePrimaryKey.
CS 683 Fall 04 | Doc 32, Mapping Collections Slide # 29 |
session inUnitOfWorkDo: [addresses := AddressBook title: 'work'. addresses at: 'musicMan' put: (Person first: 'Sam' last: 'Hinton'); at: 'author' put: (Person first: 'Martin' last: 'Fowler'); at: 'self' put: (Person first: 'Roger' last: 'Whitney'). session register: addresses].
Copyright ©, All rights reserved.
2004 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.