I’m creating an app in javascript/nodejs and using neo4j as database.
Let’s say I have an entity User
in my database. It has a bunch of properties, like boxes_collected
and places_visited
, which keep updating independently of one another throughout the course of running my app.
So far I have functions that talk to the database to update these properties directly. But it’s getting a bit messy and I’m thinking of making a single high level object/class that handles everything in a much cleaner, nicer, and eloquent way.
Here’s a tiny version of my “model” to better explain what I mean:
Suppose I have a function like this
function UpdateUserValue_plants(number) {// update database}
But then if were to create a User
object and incorporate the above into it,
var User = function User(plants, other...) {
this.plants= plants;
}
User.prototype.updateValue_plants = function(number) {
this.plants += number; // first update the model itself
}
Then when am I supposed to update the database? And wouldn’t I be doing the updatation twice that way: first the object’s property, then the database?
Is there an elegant solution to this?
0
One approach is to come up with some way of tracking your changes, then dumping them to the database in bulk. There are different approaches to this, but you will need to have something keep track of all the original values, then figure out what has changed, then batch that up into inserts, updates, and deletes.
Martin Fowler calls the object that keeps track of this a Unit of Work. This object handles CRUD for all the business objects. From the link, it should be clear that you use registerNew, registerDirty, registerClean, registerDeleted from within properties setters, and use rollback or commit when you are ready to save everything.
There is discussion of pros and cons of various implementation details in Patterns of Enterprise Application Architecture as well. Some things to think about are how often to hit the database, what to do if clients are engaged in a business transaction longer than your database transaction can feasibly be, and whether to talk to your Unit of Work via events or directly.
This functionality will be part of what an ORM does best, and if you can find one it will be better than writing one. But understanding the concepts would still be valuable.
There’s no easy way to tell you when your application should update the database. That’s what designing programs is about and only you can decide that.
For DB connection management though, one thing you’ll find is that most DB connections support pooling. When you get a connection only the first time will it take the expensive step of making the connection, after that when you release it, it will not be torn down immediately but will go into a pool where you can retrieve it later, very quickly.
This means you do not have to store a single DB connection in your code as a global or similar to use, you can ‘create’ a new connection as needed.
You might want to look into an ORM to give you more of an object view of your database which seems to be what you’re asking for.
You’re going to have to connect to the server once for each update anyway, so I wouldn’t worry to much about updating the property. It depends on your architecture but it’s probably not best to have your database communication code mixing with your BL code SOC and all. If you’re worried about making multiple database connections though you can paint the cached objects after they are updated and have a manager persist them to a database at some other time. However, it can get a bit mucky dealing with a cached object and the DB you need to make sure you know what is Synced and what isn’t.
I would recommend as @gbjbaanb suggested, looking into an ORM. An ORM is basically doing what your talking about right now, it updates an object in code then persists that data to the database on save.
Implement additional persist() method which will persist object into db and also save object into database in updateValue_plants(). You are trying to do a Domain-driven design https://en.wikipedia.org/wiki/Domain-driven_design. By creating a persist() method for saving object and saving also in updateValue_plants you are on a good way to do that.