A couple of years ago while building the Catch backend, I made a library for mapping GObject's to SQLite. It doesn't perform everything for you (like creating tables), but it does do a whole lot. Once you get into the realm of dynamically creating everything, managing migrations becomes untenable. So instead, Gom just manages all the plumbing. It helps you perform database upgrades. It helps you build search queries. Gom has lazy collections, and you can fetch things asynchronously. Yes, it has many-to-many tables too.
SQLite is actually managed from a single worker thread. Not necessarily the fastest multi-core way of solving things, but generally works well for applications. If this isn't fast enough for you, show me your use case and I'll go about fixing it.
This library is called Gom, and I finally moved it to git.gnome.org.
There are some examples in there. If you want something more complex, catch-glib was a library for accessing data in Catch that would transparently cache local data from the REST service. If you did not have access to internet, it would work locally and then sync when it was later connected. (Tangentally, I hope for a lot more partially connected services like this in the future. You'll find that a large part of our future users don't have reliable access or broadband.)
-- Christian Hergert 2014-04-12