6 ms·
I tried to use ORMs in Java years ago, but realized that while it makes simple things simpler, sooner or later you will need to do something that the ORM can't
by bborud 5y ago
I tried to use ORMs in Java years ago, but realized that while it makes simple things simpler, sooner or later you will need to do something that the ORM can't do simply. Or you will bang your head against the fact that you are trying to marry object graphs to relational models and you'll burn a lot of CPU, IO and memory in the translation. I have to admit I've been against ORMs ever since. You end up having a weak grasp on what is happening under the bonnet.
You can make much better use of your database, and understand what is going on a lot better, if you let the database be the database.
My approach is to forget about the database, and focus on what the application needs from the persistence layer. Then design an interface for the persistence. Then I implement that interface for each kind of persistence backend I need (SQL, files, memory, etc) while maintaining a single set of unit tests and benchmarks that are written against the interface.
This isn't new. A lot of applications and libraries do this. And I think it is a good way to design things.
Usually the database I use to develop a SQL schema is Sqlite3, since it allows for really nice testing. Then I add PostgreSQL support (which requires more involved testing setup, but I have a library that makes this somewhat easier: https://github.com/borud/drydock https://github.com/borud/drydock). (SQLite being in C is a bit of a problem since it means I can't get a purely statically linked binary on all platforms - at least I haven't found a way to do that except on Linux. So if anyone has some opinions on alternatives in pure Go, I'm all ears)
In the Java days JDBC every single method implementing some operation would be a lot of boilerplate. JDBC wasn't a very good API. But in Go that is much less of a problem. In part because you have struct tags, and libraries like Sqlx. To that I also add some helper functions to deal with result/error combos. Turns out the majority of my interactions with SQL databases can be carried out in 1-3 lines of code - with a surprising number of cases just being a oneliner. (The performance hit from using Sqlx is in most cases so minimal it doesn't matter. If it matters to you: use Sqlx when modeling and evolving the persistence, and then optimize it out if you must. I think I've done that just once in about 100kLOC worth of code written over the last few years).
And best of all: I get to deal with the database as a database. I write SQL DDL statements to define the schema, and SQL to perform the transactions. I don't have to pretend it is a object model, so I can make full use of the SQL. (Well, actually, I try to make do as far as possible with trivial SQL, but that's a whole different discussion). The interface type takes care of exposing the persistence in a way that fits the application.
(Another thing I've started experimenting with a bit is to return channels or objects containing channels instead of arrays of things. But there is still some experimenting that needs to be done to find a pleasing design)
- 62951413 5y agoIn Java there's another popular alternative to ORM/Hibernate, JOOQ (https://www.jooq.org/ https://www.jooq.org/). Which is basically type-safe SQL. The idea is to * start from an existing relational schema * run a CLI tool to generate Java code that represents all the tables/fields, * write queries in the application code that look like ".select().from(AUTHOR).join(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)).fetch();" So you don't need to mess up with strings anymore or learn any DSLs. Your queries look exactly like regular SQL and so are very readable. This approach is well aligned with schema migrations represented as SQL scripts too. But not everyone is comfortable with using code generation.
- bborud 5y agoSQL is actually pretty okay for writing SQL. I was never in love with this rather roundabout way of doing things since it didn’t solve problems I was actually having.