Delphi and C++Builder are incredibly productive when it comes to building database applications. However, many people over the years have started to move away from the traditional data-aware control approach in an effort to make their code more maintainable and testable. So instead of having a bunch of code in their forms that interacts with, say, the customer table in their database, they’ll put all that inside a customer object, and keep it separate from the UI logic in their forms.
There’s a lot to like about this approach, however there’s also some downsides. Firstly, you have to come up with some way of connecting your UI to your business objects. Whereas before it was easy to just wire up a DBGrid to your Customer Query, now you have to somehow get the data in your list of Customer objects into your Grid, and back again when someone makes a change. Some people write this code themselves, some people use binding systems like LiveBindings, but there’s no question that for a developer used to the ease of DBGrid<->DataSource<->Query its a big change.
Another negative is on the other side, interacting with the database. You’re now responsible for loading the data in your Customer table into your Customer objects, keeping track of which ones change, and saving it back into the table once you’re done. This isn’t terribly interesting code to write, it’s involved and error prone and ultimately fairly unrewarding. I’ve hand-written more than enough data access code and SQL in my life, so would shed no tears if I never had to do it again.
Object Relational Mapping (ORM) systems have been developed to try and take away the need to write some of this boring, plumbing code, and I’ve worked with several over the years in various languages, from in-house, home grown systems to 3rd party systems. However, when I talk about ORMs with Delphi developers, many times I hear the same set of reasons as to why they can’t use them:
- “They are too complicated”
- “Performance sucks”
- “We need more control over how our objects are stored”
- “They’re fine for a new app, but we have an existing DB structure so can’t use them”
- “Takes too much time. We need to move faster than that”
In this series of posts, I want to introduce you to using an ORM in Delphi and C++Builder, and I hope to try and dispel each of these points along the way. The particular ORM I’ll be using is TMS Aurelius, but the concepts should be applicable in other ORMs.
We’ll start off simply, letting the ORM take control of a lot, but over the series gradually we’ll exercise more control over how things are being stored and loaded. We’ll also look at how you can do all this without giving up your DBGrids. Eventually I also want to get into using an ORM in a distributed application, on both the client and server side.