WWDC2001 Session 604
Transcript
Kind: captions Language: en good afternoon my name is james Dempsey and it is now five o'clock on day two of that annual drink from the Apple firehose known as the Worldwide Developers Conference so as everybody's brain full yet good we'll try to fix that this afternoon so it's been very nice the past couple of days seeing former students who have gone through our Apple I services classes folks that I've been teaching web objects to for the past couple of years hearing about the stuff that they've been doing with web objects and it's been a lot of fun so again other former students who haven't said hi after the clatter after the class after the session feel free to say hey alright so today we're going to talk about the enterprise objects framework before we begin though I need to take a couple of polls and I want you to respond with loudest thunderous applause you can if the question applies to you so first how many folks were here yesterday for Steve Hammonds introduction to the web objects technology session so please and it's very obvious that it was a session that you're all very disappointed in from your response that I just cannot wait until that is out on DVD because I think it's going to just bump Austin Powers off of the list for me if if not that it's gonna do it too dude where's my car so I'm not sure which so we're here to talk about webobjects the second thing I wanted to pull you on is how many of you consider yourself either brand new or relatively uncertain or novice in the enterprise objects phrase work again with the round of applause which is a good size of the audience which is very good because that's what we're going to be talking about now let's begin the introduction this is an introduction of the enterprise objects framework which is more succinctly known as AOF and what we're going to be talking about today in in Steve Hammonds presale yesterday we saw that web objects in EOF can be a lot of fun he was wiring stuff up they got maps flying all over the place and the question you may ask yourself is is all this stuff really that easy and the answer is actually yes and no so yes it is if you are doing traditional database stuff inserting stuff fetching stuff out creating new objects the answer is no if you start having to do very complicated things like you come into a situation where they have a legacy database that's been there for the past ten years and their encoding all this information in the primary key and so you have to generate primary keys with EOF and then other situations where they need you to interact with some system that was designed before people had any common sense and so you have to you have to do all these contorted things to get things to work and in those cases you know what without even you know up in the picture it's just hard now the nice thing about EOF is that it allows you to solve those almost impossible problems is it easy no but are they incredibly hard problems yes and does AOF lets you do it with with with grace style panache and without writing too much code definitely so that's what we're gonna talk about now what are we going to learn in this session the first thing we're going to learn about is y EO f anyway what's the purpose what do I get where why am I in this session what's going on here the second thing we're going to talk about is just a conceptual model about yo f and how it works because we've seen things flying out of databases on the webpages today and yesterday and for the rest of the week but I always get a little suspicious when it seems a little too magicky so we're going to demystify a little bit of just what's going on there we're not gonna go into excruciating detail and then finally we're going to do practical code for basic database operations now yesterday Steve Heymann a proud Canadian he he said that Canadians they don't need wizards they don't need assistance he was going to use a display group to fetch things well it's a little known fact but a true fact that I am half Canadian my father immigrated to this country during the Great Molson beer Famine of 1958 and he took the arduous journey 20 minute journey in his car to Maine and never returned except to visit family and friends mainly because he liked the idea of molson being imported so so that said I have the Canadian blood of my father racing through my veins yet I'm also a rugged individualists American who doesn't need a display group and so therefore what we're gonna do in this is we're going to see the programmatic code that actually a display group is using behind the scenes and expose another level of the magic of the of' so that's what we're doing now where does this all fit into the big picture yo f is actually a slight mist AF the two that we're focusing on our AO access and AO control and these are frameworks they form the core of database access if you're doing HTML based web objects apps cocoa apps Java client apps direct to Java client apps direct to web apps anything that you see in any of these sessions that is hitting a database is using the frameworks we're going to talk about all right that said if you are a very good piano player imagine you have never played the piano before in your life and for those of you who are either not very good piano players like myself or never seen a piano before imagine being walked up to a piano and handed a piece of music that looks like this you'd probably say okay it looks very complicated it looks very daunting it looks like how am I ever going to sit down and do this but we know from experience we know that there are people in the world who can sit down at a piano and play this very piece of music we know walking up to a piano that it's in there somewhere I just don't know how to get it out it's just like EOF because we know from the many years the DOF has been in production in the largest companies around the world we know that e o F is able to solve some problems that would make your head literally explode with o I've heard stories but just like you don't want to hand this piece of sheet music to somebody the very first time they sit down at a piano you don't want to do this those extraordinary complicated things the very first time you deal with EOF we know anybody who's gone down the little trail of learning to play the piano knows that you start here okay and you say oh how disappointing but we know that when you're starting to play the piano somebody tells you take this thumb put it on this key called middle C and then just kind of walk up the scale those are the fundamentals and you practice that you do that over and over again because those are the things you do all the time when you're playing the piano similarly we're gonna talk today about those things that you do all the time when you're working with AOF and get started by playing with those things rather than trying to sit down at the piano for the first time and muddle through that that's easy I could do that okay enough with that now let's move on and let's talk about ye o F what's the whole point here anyway so from we can look at EOF kind of from two points of view one point being from the point of view of I'm an object-oriented programmer or individual who thinks that way and then the point of view of I'm a database kind of person and I'm not really sure about all this so stuff let's start talking from the object perspective just the brief review we have different types of things called classes each of those classes stores different pieces of information instance variables state however we want to put it in addition each one holds on to certain amounts of logic okay canonical description of an object but the big question being where do objects sleep at night what happens when I need to if it's a desktop application Coco application I need to the user logs out or shuts down the computer what happens if I need to recycle an app on my server what happens if the power goes out in California and suddenly I've lost all the states in my object so I need somewhere to put that and I could put it in a flat file write serialize it out archive it have it all written out as some big text file but once you get over a certain number of objects that gets to be ridiculous so you need some place to stick the data and boy a database seems like a pretty good idea that's what they made them for and so it actually turns out that in sticking information or object related information into a database it actually turns out to be a pretty good match so of course we have types of things in our object model maps to tables in the database you've heard this probably at least seven times in each session so far because actually this mapping is the key to EOF this is the first fundamental thing that you need to be thinking about and also of course we have columns in the database that hold different types of information it maps so well to instance variables and then each row in the database Maps amazingly well to an instance of an object of a particular class so that's good for everything except for types that are more complex than a string or a number or dates how do i hook up things that are complex objects and we know that in Java we have an object that is reffering sing another complicated object it's not a pointer mind you although we can get null pointer exceptions which boggles my mind um don't understand that at all it's just a point to a unique place in memory a reference if you will but not a pointer um what wouldn't do to have that in fact in the database it actually works out almost identically how it works each row has a unique primary key and then in another table a row has a place to store the value of the unique primary key called a join in the world of entity relationship modeling from mapping that object to relational model we call this a relationship groovy so the points of EOF is to go from a row to an object and back how hard could that be now what is an enterprise object anyway we hear this term bandied about all the time well we affectionately call them POS or just because we don't want to say enterprise object all the time all that it really is is it's a object that implements a certain interface the eeo enterprise object interface strangely enough although you would not want to go and implement that interface yourself that would be akin to you getting up tomorrow morning and saying you know I think I'm gonna invent this round thing today that people can use to roll on or something like that maybe I'll call it a wheel yeah that'll be a good idea don't reimplemented class II Oh generic record so it's all done for you all that that does essentially is it allows these objects to work with the enterprise object framework and persist in the database now why do I bring this up because if you're looking through the documentation or the class browser you will see a lot of the methods take arguments or return values of type II Oh enterprise object so that's from the object is perspective from the database perspective having taught folks over the years I can tell you that yo f kin freak a DBA outs completely they going because as was mentioned in previous sessions they you don't have to write any sequel when you get the objects into your application there's no primary key there's no foreign key so it's kind of like your entire world as a DBA is you've been abstracted from it and it that would freak me out too so as you start working seriously on web objects applications and you are working with DBAs don't get cheesed off at them because they are coming from a different place and be very patient with them because this is kind of like actually it's a lot like getting dropped in the middle of a foreign country where you don't speak the language and things are completely different everything you're used to is not quite there anymore and even worse yet it's all kind of right there and you could get to it if you wanted to but you're not supposed to so you stick data in a database you can also put logic in a database most database vendors have devised some procedural language you can store in the database call the stored procedure let's talk about EOF and how it can add value or what it does in relationship to a database so one is distributed processing if I have a big website a big I don't want to put all my logic in my one database because in addition to fetching and saving changes back to the database it's processing all this stuff so I can offload the processing to one or multiple web objects applications second thing I can do is write my logic in standard Java I don't have to learn Oracle's brand of some procedural thing dynamically generated sequel as has been kind of testified to by a couple of folks up here they didn't know sequel all that well and to tell you the truth I could not write a well-formed sequel statement right now if you paid me a large sum of money I have to check some documentation why because using web objects in EOF for the past few years I haven't needed to and it's always done the job for me one very very nice thing in POF is the ability to connect to multiple data sources and from the point of view of your code you don't even necessarily care where those objects came from where those rows came from you're very nicely abstracted from the idea of multiple data sources and finally you get a separate scratch pad for every user so if you can imagine an application where a lot of people are fetching information or looking at information and they want to maybe try a change okay I'm going to update this number and see how it affects related numbers well if you just have a database the only place you can store that change is in the database and then you have people writing and overriding over each other which is a bad thing so in gof you have a place where each user user can make edits without affecting anybody else it's like a little alternate universe where you fetch in information and you can literally make changes to that information a little context to do editing if you will um how's that name pop into my head that is another very useful thing about us in fact so useful let's talk about that editing context for a while the eeo editing context class is the class it's like your go-to guy if you want to do anything related to all the basics of database access you're going to be talking to the editing context if you want to fetch from the database you make up object that specifies what you want and you hand it to the editing context you say go get it if you want to insert objects you make a new one you hand it to the editing context say here I want to stick this into the database the next time we save our changes back if you want to well I've been watching The Sopranos a lot if you want to whack an object you're gonna take an object that you've already fetched in and you tell the editing context hey I don't want that I want this thing gone I want to delete it and it also when you're changing objects you don't even have to do anything the other thing context is just watching just sitting there saying okay you made a change I got you it's a very nice thing and then at the end of the day when you've done all your edits you have the choice either to chuck them revert the editing context or save all of those changes in one big transaction down to the database editing context very important now we're gonna see some code we're gonna walk through each of these and I'll show you how to programmatically do all of these items now I brought up the display group earlier the whoa display group which is an object that sits on top of an editing context and all of the magic that you've seen right with dragging things up things are being fetched automatically they're all happening they've all been happening because a display group has been talking to the real power behind the scenes the editing context and so all of the methods that you see here are essentially what the display group magically has been sending the editing context there really is when you start to look at it not really so much magic it just really looks that way because the whole system's put together so well let's get into it so fetching when you start doing some fetching in web objects you will find that there are many techniques for fetching we've seen a couple already one is using a display group to fetch in the prior presentation there was a method from geo utilities a convenience method for fetching we're going to see two ways to fetch in this presentation no matter which technique we use there's still a canonical thing that always happens and that's what we're going to go through the canonical longhand way it's kind of like I'm going to teach you long division and then after that I'm gonna give you a calculator so first you create a Phet spec a Phet specification we'll see in a moment just specifies what I want from the database I have to get hold of an editing context conveniently enough in a web objects application every user has a session and every session has access to or can lazily create a default editing context so it's very easy to get hold of one and then I tell the editing context hey here's a Phet specification go get me the objects that match this the editing context does the work of talking to its friends at the lower levels in the enterprise objects framework and you get back heõs and what you get back is an array of retrieved enterprise objects and you have a choice you can either then you have this array and you can manage that array yourself so if you're adding new objects to the editing context you might also want them to stick them in that array if you're deleting objects from the editing context you might want to remove them from the array so that when you display that array everything looks copacetic that is something actually that a display group handles for you all right so let's do a fetch specification what are we going to get from the database well the first thing we need to tell it is what kind of thing are we getting from the database the entity name it's just a string it's the name of the entity in the model what table are we fetching against basically the next thing is something called a qualifier which is just a description it's basically an oo description of the criteria of what we're looking for and then finally an array of sort orderings and sort orderings always travel in a pack they you ever find a lone one they're always together in an array and they determine what we're going to sort on if you are a DBA that's wonderful because I don't know any sequel and you optimized my database and that's great this is very analogous to the where clause in a sequel statement and the order by clause the qualifier and the sort orderings so qualifier is basically an object-oriented way of describing a bunch of criteria so the phrase I'm looking for employees whose salary is greater than 5,000 and their last name begins with a J well EEO qualifier is a superclass and it has all of these subclasses some of them are for concatenating things together like an end qualifier we also have or and not all the good ones yoky value qualifier is where we put things like salary is greater than 5,000 now it would be a real pain in the butt if I had to go and build all these objects and hook them up myself so even in the longhand canonical way there's a slightly easier way to do that it's a method called qualifier with qualifier formats and essentially what it takes it's a lot like a print F string in C where you give it a string with a couple of placeholders or formatting characters percentage at sign and the second argument is an array of arguments that are going to get it plugged in to the blanks it's like a programmatic Madlib and so essentially what happens in this code example is we make an array we make an object integer 5,000 add an object that's a string and then we call that method and create a new qualifier and what this code is going to create is this object graph groovy and then sort orderings these essentially take the name of a key or the property that you want to sort on and how you want to sort ascending or descending etc and so forth the order that you put them in the array determines the precedence of the sort how do we make them well we make an array usually a mutable one so we can add stuff to it and then we make new yo sort orderings the name of the property or key that we're sorting on and then there are static variables in AO sort ordering class that define the ways we can sort compare us sending compared descending and then we have case insensitive versions of those for when we're doing string compares then we build the fetch spec we assume in this case that we already have an array of orderings we already have the qualifier we use a three argument constructor to create a fetch spec and give it the pieces of info it needs the entity name the qualifier of what we want and the array of sort orderings if you want to get everything back from the table in an unsorted way you could build a special a special fetch a vacation a fetch specification that takes null for the last two arguments and then finally doing the fetch we get a hold of some editing context and again the session has one that we use as the default just any old editing context just happens to be stored in the session we can ask the session for its default editing context and we send the long but descriptive method objects with fetch specification we hand it to specification we get back an array of objects the hard part is not fetching the hard part is building the specification of what you want actually that's sometimes true in software development as well think about that when you go home okay there's an easier way the graphical fetch spec builder that's part of EO modeler this I think is when I saw this I just left for joy it was a very happy day because I didn't have to write all of this code to build a fet specification everything that I did in code I could now do in the model and so I can graphically create and we will see a demo of that in a little bit we can create the qualifier this way including building complex ands and ORS and nots and we can also build sort orderings this way so that we can not have to make that array ourselves we can just do it in a tool very nice now when you build a qualifier however usually you don't want to always get people whose salary is greater than 5000 whose first name starts with J you usually want the user to type in some input so you can do a fetch otherwise it's a really boring app so in this graphical fetch spec builder there are something a little sneaky actually it's very cool called qualifier bindings I can instead of typing out a literal thing that I'm qualifying against I can put in that graphical fetch spec something that reads something like last name like dollar sign last name and that dollar sign last name is a variable that's going to get replaced at runtime with whatever the user typed in now I take that ingredient which again is kind of like a Phet spec with some blanks in it and how am I gonna fill those items in well you kind of got the answer already because it's on the slide in NS dictionary that holds keys and values the key in the dictionary that matches that dollar sign variable I stick those two together and whatever the value is gets substituted in and voila I have my fully formed qualifier which is very very nifty now how do I do all this tomfoolery well I can use a graphical Phet spec using an EO utility in one line of code I heartily recommend this as one of the best ways to fetch programmatically so we have an editing context we've already gotten ahold of probably from the session we have this dictionary of values just calling it a query dictionary and this method objects with fet specific age and bindings that's a static method of the eyo utilities class we handed the editing context we're going to use the name of the entity we're fetching the name of the fete spec in the model and then finally the dictionary of stuff that's going to get filled into the blanks it's going to build the qualifier for you fill in the blanks build the fetch spec tell the editing context go get me those objects with that fetch specification get back the array and hand it back to you creating and inserting it's actually very very simple to do it's a two-step process that a utility lets you do in one step you need to create an object and insert an object as this slide kind of gives away you make a new object and you can make as many enterprise objects as you want and they will never end up in the database unless you insert them into an editing context and save the changes what this line of code does create an insert instance is you hand it in editing context the name of the entity you want to make a new one of and it will make a new one stick it in the editing context ready to be saved and then you will also get back a reference to that new object so you can do what other what other wonderful things you'd like to do with it and then editing editing is the easiest one of the wonderful things about gof is that you get to use your objects like objects if I want to set and retrieve values I can use accessor methods and as I'm using those accessor methods they are automatically being watched those changes by the editing context so that the next time I save changes the most recent data gets put back into the database I also bring up key value coding this has come up I think in every session as part of the fundamental magic of web objects in EOF I would say just as a pointer because we are not going to get into it here that understanding key value coding and dictionaries especially NS mutable dictionaries we can add and remove them are probably two very key things to the Zen of AOF and web objects so further research for you all the idea though is basically in key value coding it's just an interface that declares instead of always having to write two accessor methods for every property set name get name set salary get salary you know you have 37 properties you end up with what's that 674 74 accessor methods let's have two and we just pass in the name of the property we're trying to get and set as a parameter rather than hard coding it as a method name that is what key value coding is which also means that as I'm using objects that implement key value coding and all the good ones do I'm able to treat them and get inset values in them in a very generic way which is really very much at the core of why we can do all the cool fun drag-and-drop easy stuff that we saw yesterday and then finally deleting if you want to get rid of a neo it's very simple you call on your friend the editing context and you say delete this object and it'll put it on the hit list that thing is going to be gone the next time you Save Changes so we've seen what for fetching inserting updating and deleting we've seen about what five lines of code very difficult stuff now all of those changes are just hanging out in that little scratch pad in that editing context they're not in the database they're not bothering anybody else and in fact to start from the bottom of the slide if that user say hit a cancel button on your web page you could in that action method tell the editing context to revert revert throw out all those changes all those things you inserted and changed and we're ready to delete just chuck that all we're reverting um or to make things persist we tell that editing context to save changes which is going to take all of those pending edits those inserts updates and deletes it's going to send them all through EOF they're a proper sequel gets generated and what's the very nice thing though we now have persistent objects ready to get pulled back out with the next time and they get fetched all right that is the fundamental way that we deal with EOF using an editing context now I'd like to bring out Marc rest pass or up Marc rest pass demo got extraordinaire who is going to be walking us through a sample app that does all of these things Marc thank you my on everyone hear me all right it's really bright up here okay what we're going to do is start with the browser and we've written a small application so I'm gonna start in the opposite way that I've usually do demos and show the application first so as you've heard so much about crud that's what this data this application does we have a small database of songs it allows me to search on these songs I can add songs I can inspect the song I can delete it so we've got a couple of fields here song name and price of course but I leave those blank as James said when you want to fetch all of your objects you pass null for the qualifier and null for these sort orderings and you just get back all the objects I can of course do searches for a particular song and this one is set up to do greater than or equal to a price so pretty simple stuff I can add a song here some tune and I've got a few pop up buttons with some preset categories so maybe we can take Rock and Charles Mingus I could see Mingus doing some rock and dirt a little collaboration with Alice in Chains come back and our research and now we've got that same song I can hit the delete button because it turns out Mingus doesn't want to do that and I can inspect any song and make a change to it so you can see I actually have an mp3 of this file on my home computer but since this isn't my computer let's delete it so that doesn't work and we go back take a look at it of course I can hit cancel and that reverts the changes so if I were to make a lot of changes and clear out all these fields hit cancel that simply invokes revert on the editing context so how do we do that starting with search big font starting with the search method James described there's lots of ways that you can can do this you can write all the code you can create your fetch specification through by creating your and qualifier in this case we've got two fields I'd have to create - geo key value qualifiers to take an array of those and pass them to an and qualifier and make that let's create my sort orderings create my fetch specification that's all that to the end in context and ask it to return all the objects or I can just use the big font hold on I can just ask it to the ER utilities method to sort do the fetch for me objects with specification and bindings giving an editing context the name of an entity the name of my fetch back and the query dictionary so I'm going to talk a bit about the graphical fetch backs in eyo modeler because as James was going through all that you can see it can get pretty complicated creating all of these yo key value qualifiers for every field that you had you potentially would have a whole bunch of fields in a more complicated application you'd have to create all these key value qualifiers so yo modeler makes it really easy to create these graphically you can see here I've got song name case insensitive like song name and cost greater than or equal to cost what I'm gonna do is add a couple of fields in here to do more searches so I'd like to be able to search by artist oh wait let me double check yeah by artist I've conveniently written some code in here already so I add an end qualifier and I'm gonna click on to artist equals artist and then I'd also like to be able to do category so let me add category to category equals category what's going to be interesting about this is that for the artist I'm just finding the two artists relationship if you remember in the custome oh you can see that two artists is a method on song that returns an artist object or an EO Enterprise object referring to the artists table but I'm only asking it for this particular object here in the fetch pet for category I'm looking at the actual category field in the category table so I can put a string in there now in my web objects template I've got this query dictionary and I've got it bound up the song name and costs two fields in my song table I'm going to add a row for the category putting in a field and I'm gonna bind up my query dictionary using the variables I specified in my fetch back so query dictionary dictionary and then I'm going to add a row below that for the artist but because I conveniently already put in a couple of variables I've got this artist display group and you may remember in previous sessions where they discuss the display group you can configure it to for a particular table or a particular entity and this one is for the artist table I've got it set to fetch on load sorted by artist name so it's gonna fetch all of the artists I'm going to bind the displayed objects to the list I've got an artist object in here for the item I'd like to display the artist dot artist name and then I've got a selection in the selection I'm gonna by inquiry Dictionary dot artist because what's interesting about this is that the pop-up button doesn't give you back a string which is the name of the artist it gives you back an actual artist object I happen to be displaying in the display string the artist name but the object the thing that I'm getting back is an artist object so I can pass that particular artist into my fetch back and say give for the relationship to the artist find all the songs that match that relationship if I go back in here and recompile and to get the changes for my model I'll get these two new fields in here they'll let me search and I don't have to write any more code in order to get these and out of the thousand demos that I've done I always seem to forget one binding in this pop-up button which is the no selection strength so let's fetch again and refreshing this page now I can select so I can select signing that to Nanak get all artists and get all the songs by Allison chains all the songs that begin with C in this case nothing nothing is found so it's really easy to add this up and add these things into your fetch specification using yo modeler you don't have to write any new code it's all getting set up with my query dictionary let's take a look in a little more detail at how this is getting done I have a query dictionary which is a NS mutable dictionary which I initialize in the constructor and I bound up these keys query Dictionary dot cost which is a field in my song table in this one the selection is query dictionary two artists and those all match what's in the fetch specification Ennio modeler so and during it during the request response loop when we when web our just goes through this page it's going to go into each one of those forms and say I've got query dictionary song name so it's going to look set the song name key and take the value out of that field and put it in and remember in nsmutabledictionary for anyone who doesn't know the method is set object for key so it'll set that the value to song name for the key song name but if son name doesn't exist it will create a key song name and set that value in there in fact if these are null if I were to leave one out who will actually remove it as part of key value coding which is how I'm able to do a fetch I can say put in two here and find all of these out greater than or equal oh no match found so if we can make a change to that and I don't keep all of the fields that were in my query dictionary so I also have debugging on in this application oh and if we look at the query dictionary here you can see that this is actually an artist's that was selected and you get an artist object and I have debugging on where you can see that the SQL being generated is the artist ID and a oh F is able to say find me the artist that matches get its primary key out match that up with the foreign key that's in the song table and do the query that way so the SQL is being generated for me but I don't have to deal with that I can just deal with the objects so that was the search method a couple of other things I can add a song so we went through and I hit the add song button it brings up this other page what happens with that if I want to add a song I use the method that James mentioned create an insert instance passed at the end in context that I'm using the sessions default that in context in this case and the name of the entity I want to get an object back that's which is a song entity I have a method here edit page with song because I'm actually using the same component to edit new objects and create and edit existing objects so I have edit page with song which simply sets the song to the song that I've returned and sets the return page to this which is why when I come back after creating a song my page looks the same passing this to the next page I can return that whoa component and I get the page back in the same state it was in which for this number worked out well for me if I were to edit a song I simply pass it the song that I have and this is part of some of the magic of well repetition the world repetition allows me to select one of the songs in that array in the table and it will set the song variable automatically to the one that I selected I don't have to go through and figure out what it is song variable gets set to the one I saw if I delete the same sort of thing happens it automatically sets the song instance variable to the object that I selected in the row and then I as James was talking about if you were to manage this array yourself I removed the object from the array ask the editing context to delete the song which just marks it at for deletion and then when changes are saved the editing context saves the changes deletes those objects taking a look at the Edit Page the save song method on here is again very simple I ask the editing context to Save Changes and I return the pray page that I set now you might wonder where are these changes coming from where is it getting all these values I can take a song object you can see all the instance variables here and I combined them directly to fields on the form I can also bind them to the selection for Papa buttons so for each one of these pop ups I have the object that was selected in the pop-up set to these for the song binding so I've got song to album and I combine these up directly hitting save saves the changes hitting cancel invokes revert on the editing context so I just want to try a couple more forget about the clock we have plenty of time alright so there's more things that we can do I didn't specify any sort orderings yet so I can specify sort orderings that maybe I'd like to sort these by artist's name and we can specify ascending or descending case insensitive or case sensitive I believe that this is pretty much if you have Alice in Chains with the capital a or a lowercase a they show up in two different places we'd like them to all be grouped together so case-insensitive sort ascending I could sort by a song name and last maybe do the category and there are a number of other things that you can do in here you can set prefetching which you might find out about some of the advanced sessions you can do raw fetches you can actually get back raw rows rather than getting back Enterprise objects you can get you just get back a dictionary of raw rows you can set options like fetch distinct rows like I think it's the only SQL I know select distinct well you know that that sort of thing we select distinct and if all of this worked out into some SQL that could be figured out then SQL will be set here so we can see already that SQL is being generated but Yoel modeler isn't really able to figure out I've got an artist object how does that relate to ask you well and that's part of what yo f is doing for us so now we've got some sort orderings we've got qualifiers we're working across relationships because he owes know about relationships lots of database access frameworks don't somehow they forgot about relationships the relational part of the relational database but with a neo if I have a song a song knows about its album it knows about its artist it knows about its category but it only knows about it when we need to get it when we ask for the artist that's when it goes and gets it so now that we've got some sort orderings in there I'll recompile get my model back into my application in my application back and now when I fetch all these should be sorted I think the absolutely there we go so if we just sort by you fetch all the objects in here now they're sorted by artist song name and category so we've got all these different songs Dave Holland something james Dempsey Fitz I know what the fetch Beck song is and that's I think that's pretty much it we've got sort orderings we can use AOF to do all this REO model or to create our fetch spec graphically if we switch back to slides awesome so the first time I wrote a web objects app it was a little small app to exercise the of' actually very similar this with one addition it was something that kept track of how many times mac OS rumours was right and so I wrote a little code that went out and grabbed the HTML from their site parsed through their tags pulled out the heading of each story and the story itself stuck it in a database using EOF and I went through and picked a date of when I would check back to see if that rumor was true or not and every morning cuz I don't know just kind of an Apple watcher I guess I would go in and check that out and 20% was about the ratio but that was usually on things that we're gonna happen tomorrow or the next day you know but I highly recommends starting out with the of' writing a small app of this nature that exercises those basic functions right one or two the practice is good keep it very simple it's actually one of the best ways to learn now the magic still this eeo editing context it does all this stuff I just get back this array of objects somehow they're sequel being generated who's doing what what's going on here well we're going to take kind of the nickel tour the EOF stack of the EO access framework in the EO control framework to show how we go from a row to a neo and back now we'll start with yo access and yo access is something where you don't for starters at least do things programmatically you configure yo access using yo modeler yo axis actually I'm going to jump back to slide ho maybe there we go yo access is responsible for the connection to the database it's responsible for turning those raw rows into enterprise objects it's responsible for doing that object relational mapping and it does so with the help or the assistance of a model file we don't really mess around the neo access that much except that the EO utilities classed with all those utility methods is part of the EO access framework so when you're looking in yo control the documentation and can't for the life of you find out where this Co utilities is it's because it's a neo access now EO control as we've seen is where we control things we have in editing context we fetch insert update delete that's where we are in control that's what yo control is for so again we don't programmatically touch EO access that much we've seen what do modeler does has the connection information of what database we're hooking up to and has that object to relational mapping without a model file EOF is just gonna sit there there it's not going to connect to a darn thing so the EO access framework has actually two layers that we're going to talk about one is called the adapter layer and the adapter layer currently the JDBC adapter is going to is the part of the framework that is sending sequel to the database it's generating the sequel particular to that database it is also maintaining the connection through the database it is dealing entirely in raw raw data it has never heard of an enterprise object it's dealing entirely in just the rows that come back when it gets them back it hands them up to the database layer and the database layer has two very important jobs kind of two raison d'être it as one would say if one had a very poor French accent the two things that the database layer does is first of all its job is to turn that raw row into an EO it's kind of like Pinocchio becoming a real boy it was just a plain behavior 'less bunch of data now it's an enterprise object that represents the the logic of your business the second thing that it does is it takes a snapshot of the data that came in from the database and stores it and it holds on to it one so we can cache and so EOF might save itself a trip to the database later because it already has the information we already went to the database and it also holds on to it so that when we save those changes we're able to check hey did somebody change that row out from under us what were the values when we first fetched those items those are called snapshots and as you go more and more into eof you'll learn more and more about them I just wanted to point them out and let you know where they lived so once things are out of the access framework they're fully formed AOS the snapshots been taken then we move on to geo control oh one more thing I mentioned earlier that multiple data sources was something that a Oh F did very very well and in fact it's so arduous to set up a second data source what you do is you make a second model file you add that model file to your project and as you are fetching using entities in both models EOF will automatically come up with the objects to connect to both databases and both of those are going to be fetching raw rows turning them into eos and the like a note not all databases are orange I should have picked a different color too distinguished it's also important to note I did not get a chance to change this that really that whole row that whole line is the database layer what yo f is doing is making a couple of objects in each layer for each connection down to a data source but again the takeaway add another model that connects to another data source you're connecting the multiple data sources the rest is handled pretty automatically by EOF now you may come across this object to class called the EEO model group it lives it exists because we can have multiple models and so we have an object that manages those models that's what it's job is those are kind of the big-ticket items of what's going on in a oxs now let's go through so we've gotten these things up out of the database we have multiple data sources we might be connecting to and how are you going to control what sequel gets sent here what sequel gets sent their customers live over here something else lives over here well we have kind of a traffic cop in the EEO control framework called the object store coordinator you'll run across this as you're reading the documentation you don't talk to the object store coordinator programmatically all that often it's just nice to know that the OSC is they're just directing traffic for you and then on top of the objects their coordinator is the thing we're familiar with the editing context so I wanted to just show you how things get from the database and who are the players along the way so that you don't think it's just magic and I don't understand exactly what's going on this is pretty much the Grand Tour of EOF and of course we can have different editing contexts by default one per user session and they're all talking through the same object store coordinator they're all using that same model they're all sharing the snapshots stored at the database layer and they're all connecting through the adapter layer so that is the big ol walkthrough of EOF now um let's review so well actually I wrote a little song about it so let's uh let's do that for a moment oh cool I feel like the [Applause] all right so mm so how many persistence object persistence frameworks in the world are there that people enjoy using so much that they write a little song about them oh this is my first time playing guitar in public so so it might just suck to be you [Music] fit stick baby you can stimulate the objects you wanna fetch in beauty yo coz O's whenever you fetch you're gonna get some of those yo zero zeros their database Rose wrapped in low clothes well that respect it helps you specify the objects you wanna fetch as its name implies with a fetch spec you can stimulate those objects you wanna fetch and manipulate or iterate over each object in the array yeah yeah yeah over each object you wanna display yeah yeah well I see what kind of objects are they gonna be well you've got to specify which entity in the criteria of what you desire you're gonna wrap that up into a qualifier willing don't forget about those sword all the Rings determines the order of objects the fit spec will bring me [Music] who's gonna fetch for you don't be perplexed it's an object editing context well that editing context it is your pal you can think of it like in the old Corral you get back in an array of the ones that you choose you make a change the editing context it knows then spec it helps you specify those objects you wanna fit baby you can stimulate those objects you wanna fetch in a sing-along let's spin it helps you to specify the objects you wanna fetch as its name implies with a fetch split baby you can stipulate those objects you wanna fetch it this was a little song about you if I you get the gist it is a framework that helps your [Music] except for them there's the web objects lab so hold on hold on just a second before we move on I just have to ask you one question sure do you have an agent so first time on stage huh so if you guys ever want to repeat ooh this list let us know and in case you didn't notice James is also on stage inside the classroom on almost a weekly basis um a little less but yeah so if you want a little bit more information from him regarding UF and other pieces of our technology you can sign up for web objects class right thank you go to the web objects lab and build one of these apps like Mark it showed you I'll be very good and roadmap we didn't talk a lot about using yo modeler here because data modeling and connectivity is all about that which is groovy advanced enterprise objects framework is going to be an awesome session that's I'm going to be there because I love just always here and more and the feedback for him and with that who to contact looks familiar from every other session you