The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

ORM Model question

Hello,

so I'm trying to do some ORM and things are feeling a little weird.

Here's an example for my question:

Table
 user_code, user_name, password

Class {
 int user_code;
 String user_name;
 String password;
}

So my question:

Since the Class user represents one user in the system, how should the system represent a "registering user"?

For example, the Class User could have a registerUser method

boolean registerUser ( $username, $password ) {
  // check if username is non existing in db
  // send insert sql to database
  // check insert result and return true or false
}

However this seams quite strange because the class would probably have other methods, like:

* updateUser
* deleteUser

It seams strange that the User object will be deleting it's correspondent item on the database. Not sure why but this seams weird.

So I'm guessing if there actually should be two classes:
1) User - just keeps the user information
2) UserDB - functions to insert, update, delete, get user list...

Thanks.
Secret
Thursday, August 02, 2007
 
 
I think what you are looking for is a separate layer that handles authentication and general user management. It is only natural that a user "deleting itself" or "registering itself" seems weird.

"Separation of concern" is your friend, so I would separate as follows:

1) user objects - represent a user and his properties
2) persistence layer/component - can "CRUD" an object (not just users)
3) authentication layer/component - can authenticate a user
Dotimus Send private email
Friday, August 03, 2007
 
 
Thanks.

"1) user objects - represent a user and his properties
2) persistence layer/component - can "CRUD" an object (not just users)"

With number 2 do you mean a layer where each class handles a table / object or a Layer that can take a X (i.e. User) object and map it to a SQL query?

For exaple:

Layer 1: User, Car
Layer 2: UserCRUD, CarCRUD?

Or

Layer 1: User, Car
Layer 2: CRUDMaster (can take a User or Car object and create proper SQL)

On other thing: what would be good names for those "CRUD" classes? UserHandler? CarTableManager?

Thanks.
Secret
Friday, August 03, 2007
 
 
Option 2) is what I mean. I know there are frameworks which also have one "database object" for every business object which can persist itself, but I think persistence is a thing of itself which shouldn't be mixed with business logic. Anyway, there are probably different opinions on this.

Good name? How about PersistenceManager?

Car car = new Car();
PersistenceManager.store(car);

Depending on what language you are using there might already be frameworks for this (e. g. Java Persistence API). You don't have to reinvent the wheel. This especially the case if your language supports runtime type information.
Dotimus Send private email
Friday, August 03, 2007
 
 
Hello and thanks again.

"Car car = new Car();
PersistenceManager.store(car);"

So basicly the PersistenceManager class would check the structure of the Object sent to "store" and create a query on the fly for that object, correct?

Something like...

boolean store ( Object x ) {
  Query = "INSERT INTO " + getClass ( x );
  // create the COLUMNS list part of the SQL
  // create the VALUES part of the SQL
  // execute query
}

Although I like this kind of solution, I think it would add some overhead due to the constant SQL creation.

Maybe it would be better to place somewhere the preconstructed partial queries (with column list) for each object, for each method, and then just create the values part?

Thanks.
Secret
Friday, August 03, 2007
 
 
> Maybe it would be better to place somewhere the preconstructed partial queries (with column list) for each object, for each method, and then just create the values part?

as in stored procedures?

Usually that's the task ORM frameworks are there to simplify. There are lots of examples for nHibernate and other frameworks. For instance, here is one way to implement insert with SP in BLToolkit:
--------
public abstract class CarAccessor : DataAccessor<Car>
{
  [SprocName("Car_Insert")]
  public abstract void MyInsert(Car car);
}

CarAccessor ca = DataAccessor.CreateInstance<CarAccessor>();
ca.MyInsert(myCar); // insert with Car_Insert sproc
ca.Insert(myCar); // insert with regular INSERT sql
--------

I'm just curious if you are thinking about building a custom ORM solution or evaluating some of the existing ones as well.
DK
Saturday, August 04, 2007
 
 
<quote>
as in stored procedures?
</quote>

No, I was thinking about something like your example, a class with specific SQL ready for that object type.

Something like

class CarManager {

  DBManager dbm;

  public boolean insert ( Car car ) {
      sql = "insert into car ( code, model, brand )";
      sql = " values (" + car.code + "," + car.model + "," + car.brand + ")";
     
      return dbm.insert ( sql );

  }

}

class DBManager {
    Connection c;
    public boolean insert ( sql ) {
          c.send_query ( sql );
    }

}

<quote>
I'm just curious if you are thinking about building a custom ORM solution or evaluating some of the existing ones as well.
</quote>

I'm building one, but it's a simple one as part of another project.  For the feature set I need and the type of project (non commercial / personal use), I figure I should just do it so I can learn with it instead of learning how to use an existing solution.
Secret
Sunday, August 05, 2007
 
 
> No, I was thinking about something like your example, a class with specific SQL ready for that object type.
...
> I'm building one, but it's a simple one as part of another project.  For the feature set I need and the type of project (non commercial / personal use)), I figure I should just do it so I can learn with it instead of learning how to use an existing solution.

Ok, fair enough.

It seems like (almost?) all mature ORMs support CRUD operations with generated sql queries. Performance bottleneck is not as much query creation, but reflection over class and object instance. A common solution is to generate IL and add required functionality at run-time, or generate some source code before or at the moment of the build. Once it's implemented, caching of CRUD queries is most likely taken care of as well.

Code or IL generation, DB-to-primitive types mapping, handling null and default values, value mapping for enumerators to name a few ORM tasks... What about validation, or change tracking, or handling parent-child relations? I wouldn't call any ORM a "simple" one. OTOH, most popular ORMs are open source or even public domain, so you can use it as a starting point or for design reference. Said that, it should be a lot of fun to create one of your own from ground zero ;)

As for the original question - yes, it's very common to have data access as a layer, while keeping business entities in a separate namespace and use them across application layers: DA, BL, UI. Either DA or business entity would handle object structure information, along with things like caching _parameterized_ CRUD queries.
DK
Sunday, August 05, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz