APM: Database wrapper classes
Steve Lane
sml at zfx.com
Tue Aug 13 09:59:15 CDT 2002
Wayne Walker wrote:
> But, more importantly, I want other peoples inputs on good ways to wrap
> database access in some kind of class or package.
>
> Let's say I have a project that uses three database tables and I need/want
> to hide/bury the SQL away from the application developers (who are new
> to perl, every piece I can hide from them is one less thing they need
> to learn right now).
>
> I could write some classes that just make the SQL disappear:
>
> Person
> add(%data)
> delete($id)
> get($id)
> Address
> add(%data)
> delete($id)
> get($id)
> Relations
> add(%data)
> delete($id)
> get($id)
>
> This alone makes life easier for everyone. At first...
>
> Then we run into performance issues, or cross table joins, or searches,
> ...
>
> At which point this is now fairly ugly. We end up having the SQL hidden
> away, except for complex steps and then we're doing SQL outside of any
> of the objects.
>
> So, any recommendations? Existing CPAN modules that handle this somehow.
> A particular class hierarchy that makes sense for this that you've used
> (a few class names and method names like I did).
i do this kind of thing like this:
use MyDBI;
my $DBI = MyDBI->new(
DB => 'MyDatabase',
TABLE => 'MyTable',
USERNAME = 'steve',
PASSWORD = 'evets',
);
my $o = $DBI->select_by_id(123); # does a SELECT * FROM MyTable WHERE id = 123
$o->name('Steve Lane');
$o->address('123 Elm St.');
$o->update; # does an UPDATE
my $o2 = $DBI->empty;
$o2->name('Steve Lane');
$o2->address('123 Elm St.');
$o2->update; # does an INSERT
my $o3 = $DBI->select(name => 'Steve Lane');
$o3->delete;
$DBI->delete_by_id(666);
$DBI->delete(name => 'Bob Jones');
my @os = $DBI->selectlike(name => 'S');
map { $_->updated(time); $_->update } @os;
my @os2 = $DBI->select_raw("WHERE name LIKE 'S%' ORDER BY income DESC");
map { $_->income($_->income + 5_000); $_->update } @os;
and so on. inherit from MyDBI if you want to restrict to
a particular database/table/username/password etc.
if the objects have properties other than their database data,
just put their class in the ->new() call:
use MyDBI;
my $DBI = MyDBI->new(
DB => 'MyDatabase',
TABLE => 'MyTable',
USERNAME = 'steve',
PASSWORD = 'evets',
CLASS => 'StripOfBacon',
);
my @os = $DBI->fetch(crispiness => 'thawed');
# ->fry is a StripOfBacon method, not a MyTable field.
# it may modify several object fields, add calories to
# the user's calorie-counter, etc.
map { $_->fry; $_->update } @os;
have the appropriate amount of fun, and let me know if
MyDBI is implemented :). comments welcome of course.
--
Steve Lane <sml at zfx.com>
More information about the Austin
mailing list