0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Tengチート

Last updated at Posted at 2016-09-27

概要

tengのSQL書き方は、SQL::Maker::Conditionを踏襲しているようです。
https://metacpan.org/pod/SQL::Maker::Condition

※pluginのlookupだと、使えない条件指定が多い(特に{}を使う条件)ため、その場合はsingleを使ってください。

初期化

use Teng;
use Teng::Schema::Loader;

my $teng = Teng::Schema::Loader->load(
    connect_info => ['dbi:mysql:dbname=myapp', 'username', 'password'],
    namespace => 'MyApp::DB',
);

基本的なCRUD操作

Create (挿入)

my $row = $teng->insert('table_name', {
    column1 => 'value1',
    column2 => 'value2',
});

Read (検索)

単一行の取得:

my $row = $teng->single('table_name', { id => 1 });

複数行の取得:

my @rows = $teng->search('table_name', { status => 'active' });

Update (更新)

$teng->update('table_name', 
    { column1 => 'new_value' },  # 更新するカラムと値
    { id => 1 }                  # WHERE 条件
);

Delete (削除)

$teng->delete('table_name', { id => 1 });

高度なクエリ

IN句

my @rows = $teng->search('table_name', {
    status => { 'IN' => ['active', 'pending'] }
});

LIKE句

my @rows = $teng->search('table_name', {
    name => { 'LIKE' => '%John%' }
});

AND条件

# -and を使用する場合(明示的)
my @rows = $teng->search('table_name', {
    -and => [
        status => 'active',
        age => { '>' => 18 }
    ]
});

# -and を省略する場合(暗黙的)
my @rows = $teng->search('table_name', {
    status => 'active',
    age => { '>' => 18 }
});

注: Tengでは、-andキーワードは多くの場合省略可能です。複数の条件を単純にハッシュとして列挙すると、暗黙的にAND条件として扱われます。ただし、より複雑な条件やORとの組み合わせを使用する場合は、明示的に-andを使用すると可読性が向上することがあります。

OR条件

my @rows = $teng->search('table_name', {
    -or => [
        status => 'active',
        status => 'pending'
    ]
});

NOT EQUAL条件 (<>)

my @rows = $teng->search('table_name', {
    status => { '!=' => 'inactive' }
});

複合条件(AND, OR, NOT EQUALの組み合わせ)

# -and を使用する場合
my @rows = $teng->search('table_name', {
    -and => [
        status => { '!=' => 'deleted' },
        -or => [
            age => { '>' => 18 },
            has_parent_consent => 1
        ]
    ]
});

# トップレベルの-andを省略する場合
my @rows = $teng->search('table_name', {
    status => { '!=' => 'deleted' },
    -or => [
        age => { '>' => 18 },
        has_parent_consent => 1
    ]
});

この例では、statusが'deleted'ではなく、かつ(年齢が18歳より上、または親の同意がある)レコードを検索しています。トップレベルの-andは省略可能ですが、内部の-orは明示的に指定する必要があります。

ORDER BY

my @rows = $teng->search('table_name', 
    { status => 'active' },
    { order_by => 'created_at DESC' }
);

LIMIT と OFFSET

my @rows = $teng->search('table_name', 
    {},
    { limit => 10, offset => 20 }
);

トランザクション

$teng->txn_begin;
eval {
    $teng->insert('table1', { ... });
    $teng->update('table2', { ... }, { ... });
    $teng->txn_commit;
};
if ($@) {
    $teng->txn_rollback;
}

カスタムSQLの実行

my $itr = $teng->search_by_sql(q{
    SELECT * FROM table_name WHERE column1 = ? AND column2 = ?
}, ['value1', 'value2']);

スキーマ情報の取得

my $table_info = $teng->schema->get_table('table_name');

関連テーブルの取得

my $row = $teng->single('users', { id => 1 });
my $related_rows = $row->cascade_fetch('posts');  # users.id = posts.user_id の関係を想定

count

(例)

my $count = $teng->count('order_table', '*', +{import_user => $editor, is_deleted => 0, last_edit_at => undef});

between

(例)

my $iter = $teng->search(attendance_tbl => +{attendance_date => +{between => [$begin_date, $end_date]}});

bulk_insertについて

$teng->bulk_insert('webedi_tbl', \@csv_datas_for_insert);

bulk_insertは早いと思っていたけど、早くない。
ログを見ると、tengのbulk_insertはinsertしてからselect文を発行する仕様(SQLiteのみ??)らしく、select文のぶんだけ遅くなってしまった。。

iteratorで取得するか、配列で取得するか?(性能観点)

search()結果を取得するには、以下の2通りの方法がある。

1.iteratorで取得し、iterator->next()でループ処理
2.配列で取得し、ループ処理

1は取得は早いが、next()で回す回数が多いほど処理が遅くなる。
2は1に比べて取得は若干遅くなる(内部で配列に変換するため?)が、その後のループ処理は早い。

ゆえに、取得データが多ければ多いほど、2のほうが早くなると思われる。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?