m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

PerlでTengを使用したDB操作

準備

データベース作成
create database sample_db1; 
テーブルを作成
create table posts(
  id int auto_increment NOT NULL,
  title varchar(50),
  body varchar(256),
  created DATETIME,
  modified DATETIME,
  primary key(id)
);
適当にデータを突っ込んでおく
insert into posts(title, body) values('test1', 'body1');
insert into posts(title, body) values('test2', 'body2');
insert into posts(title, body) values('test3', 'body3');
cpanmでTengを入れる
cpanm Teng

モジュールを作成

lib/DB.pm
package DB;
use parent 'Teng';
1;

※Tengを継承したものを用意

lib/DB/Schema.pm
package DB::Schema;
use strict;
use warnings;
use Teng::Schema::Declare;

table{
    name 'posts';
    pk   'id';
    columns qw/id title body/;
};

1;

※テーブルスキーマ?の情報を定義したモジュールを用意。使用するテーブルの名前やキーなどの情報を定義するよう

モジュールを使用して実行

sample1.pl
#/usr/bin/env perl

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use DB;
use Data::Dumper;

my $obj;
$obj = DB->new(
    connect_info => ['dbi:mysql:sample_db1:localhost', 'root', undef ]
);

# 1件参照
my $data;
$data = $obj->single('posts', {});
print "single---->\n";
print $data->title . "," . $data->body . "\n";

# 3件参照
$data = $obj->search('posts', {});
print "search---->\n";
while(my $row = $data->next()){
    print $row->title . "," . $row->body . "\n";
}

# 追加
my $data2;
$data2 = $obj->insert('posts' => {
    'title' => 'sample1',
    'body' => "zzzzzzzz1111"
});
print "insert row---->\n";
print $data2->id . "," . $data2->title . "," . $data2->body . "\n";

# 更新
my $data3;
$data3 = $obj->update('posts' => {
    'body' => 'xxxxxxxxxxxxx'
}, {
    'title' => 'sample1'
});
print "update count---->\n";
print $data3 . "\n";

# 削除
$data3 = $obj->delete('posts' => {
    'title' => 'test1'
});
print "delete count---->\n";
print $data3 . "\n";

# SQL
my $sql = "select * from posts order by id desc ";
my $res;
$res = $obj->do($sql);

print Dumper($res);

※doを使用してもデータ自体は取得してくれないのかな???

結果
[vagrant@localhost teng1]$ perl sample1.pl 
single---->
test1,body1
search---->
test1,body1
test2,body2
test3,body3
insert row---->
4,sample1,zzzzzzzz1111
update count---->
1
delete count---->
1
$VAR1 = 3;
[vagrant@localhost teng1]$
table内
mysql> select * from posts;
+----+---------+---------------+---------+----------+
| id | title   | body          | created | modified |
+----+---------+---------------+---------+----------+
|  2 | test2   | body2         | NULL    | NULL     |
|  3 | test3   | body3         | NULL    | NULL     |
|  4 | sample1 | xxxxxxxxxxxxx | NULL    | NULL     |
+----+---------+---------------+---------+----------+
3 rows in set (0.00 sec)

mysql>

DB::Schema…

なんかこれがどこでuseされているかわからないけどおそらくDB.pmを使用する際に参照している感じかな?

sample1.plをモデル化する?

ある程度機能をまとめたモジュールとして用意して、いくことでモデル化して対応出来る感じかな?

トランザクション

sample2.pl
#/usr/bin/env perl

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use DB;
use Data::Dumper;

my $obj;
$obj = DB->new(
    connect_info => ['dbi:mysql:sample_db1:localhost', 'root', undef ]
);

# トランザクション
$obj->txn_begin();

# 1件参照
my $data;
$data = $obj->single('posts', {});
print "single---->\n";
print $data->title . "," . $data->body . "\n";

# 3件参照
$data = $obj->search('posts', {});
print "search---->\n";
while(my $row = $data->next()){
    print $row->title . "," . $row->body . "\n";
}

# 追加
my $data2;
$data2 = $obj->insert('posts' => {
    'title' => 'sample1',
    'body' => "zzzzzzzz1111"
});
print "insert row---->\n";
print $data2->id . "," . $data2->title . "," . $data2->body . "\n";

# ロールバック
$obj->txn_rollback();

[vagrant@localhost teng1]$ perl sample2.pl 
single---->
test2,body2
search---->
test2,body2
test3,body3
sample1,xxxxxxxxxxxxx
insert row---->
5,sample1,zzzzzzzz1111
[vagrant@localhost teng1]$
table
mysql> select * from posts;
+----+---------+---------------+---------+----------+
| id | title   | body          | created | modified |
+----+---------+---------------+---------+----------+
|  2 | test2   | body2         | NULL    | NULL     |
|  3 | test3   | body3         | NULL    | NULL     |
|  4 | sample1 | xxxxxxxxxxxxx | NULL    | NULL     |
+----+---------+---------------+---------+----------+
3 rows in set (0.00 sec)

mysql> 

※rollbackしたので戻っている

ディレクトリ構成

[vagrant@localhost teng1]$ tree
.
├── lib
│   ├── DB
│   │   └── Schema.pm
│   └── DB.pm
├── sample1.pl
├── sample2.pl
└── sql
    └── create.sql

まとめ

基本的なデータ抽出、追加、更新、削除とトランザクションは実施できるので問題はなさそう。あとはORマッパーの使用方法をうまく理解することが重要みたいな感じ。perlでのクラスの継承などをうまく理解していないのでその辺りをやり直してまとめてモデルを使用できるようにすることが必要みたいな感じ。