I am way too orientated with xPDO nowadays that it is hard to remember how it was before to be honest. Even I still do fall back to PDO queries with xPDO when I need big datasets and do not need the objects with them,
But what gives the kicks out of xPDO for me:
Database agnostic approach for (pretty much) everything (was mentioned in the blog post), but gonna point out few specific things
But what it did not mention was the actual benefactors that many people miss. For example, Oracle (not official) and Sql Server do not have LIMIT like MySQL and SQLite has. With xPDOQuery the limiting is done in behalf of you, no need to add subqueries or funky stuff just to achieve something that sounds really simple, especially if coming from MySQL World.
To same topic goes the schema value generated="native" which adds auto_increment (MySQL term) to your tables. No need to hassle with correct syntax for each platform separately. Hopefully will get Oracle support fully compatible soon as there is good example for this: as oracle has no auto increment, this needs to be done with triggers and sequences.
The xPDOManager takes care of your schema, as long you got right database data types set and if you use standard ANSI SQL datatypes, you are 90% of the time safe and can use the same schema for multiple platforms or just clone it and tweak the changes. Just use createObjectContainer() and you are free to breath.
Database agnostic field escaping, a pop thing. Commonly without using any abstraction model, most of us would write SQL queries similar to
SELECT this_column, that_column FROM the_table WHERE this_column = 2
With xPDO the query gets standardized with proper escaping just for field and table names. (The true one having table aliases etc.. also in the strings, escaped obviously.)
Extending objects and "extending" tables with single inherit model
MySQL: SELECT `this_column`, `that_column` FROM `the_table` WHERE `this_column` = 2
Oracle: SELECT "this_column", "that_column" FROM "the_table" WHERE "this_column" = 2
Something you gotta love is the fact that multiple objects can share the same table without any hassle with the objects themselves. Especially in the case of single inheritance when the child objects are quite powerful all together.
What else? Oh yes, if you need to run complex queries and still want to have the objects loaded, you can do it. Just simply use xPDOCriteria($xpdo, "SELECT your_raw FROM sql_query .... and lots of complex stuff"); to create the criteria instead of xPDOQuery. This is not database agnostic approach, but with proper escaping with $xpdo->escape() and manipulating the string before hand per driver type, it is pretty easy.
The criteria element for aggregate and composite joins
I guess most would expect me to write something to this direction I wrote, there is lot of brilliant features there. Not just database agnostic querying, but also cache engines are are used with xPDO methods so you can switch between APC, Memcached and filecache when ever you want.
Info/Debug/Error logging, quite efficient when you get used to it.
..... Could possibly have endless list of stuff here, but I've only written about 20% of the features that xPDO has with all my articles where most are really directed to queries. So do not even know all nifty features is might have. Even do know most of them, but have not studied them entirely.
Sorry for bolds, had to highlight "headings" somehow