|
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.