Perl 数据库连接
DBI 基础
连接数据库
perl
use DBI;
# 连接 MySQL
my $dbh = DBI->connect(
"DBI:mysql:database=test;host=localhost",
"username",
"password",
{
RaiseError => 1,
PrintError => 0,
AutoCommit => 1
}
) or die "Cannot connect: $DBI::errstr";
# 连接 PostgreSQL
my $dbh = DBI->connect(
"DBI:Pg:dbname=test;host=localhost",
"username",
"password"
);
# 连接 SQLite
my $dbh = DBI->connect(
"dbi:SQLite:dbname=test.db",
"",
""
);查询操作
执行简单查询
perl
use DBI;
my $dbh = DBI->connect("DBI:mysql:database=test", "user", "pass");
# 准备 SQL
my $sth = $dbh->prepare("SELECT * FROM users");
$sth->execute();
# 获取所有行
my @rows = @{ $sth->fetchall_arrayref({}) };
foreach my $row (@rows) {
print "$row->{name}, $row->{email}\n";
}
$sth->finish();
$dbh->disconnect();使用占位符
perl
use DBI;
my $dbh = DBI->connect("DBI:mysql:database=test", "user", "pass");
# 使用占位符防止 SQL 注入
my $sth = $dbh->prepare("SELECT * FROM users WHERE name = ?");
$sth->execute("Alice");
while (my $row = $sth->fetchrow_hashref) {
print "$row->{name}, $row->{email}\n";
}
$sth->finish();获取单行
perl
# 获取单行(数组形式)
my ($name, $email) = $dbh->selectrow_array(
"SELECT name, email FROM users WHERE id = ?",
undef,
1
);
# 获取单行(哈希形式)
my $row = $dbh->selectrow_hashref(
"SELECT * FROM users WHERE id = ?",
undef,
1
);插入操作
插入单条记录
perl
use DBI;
my $dbh = DBI->connect("DBI:mysql:database=test", "user", "pass");
# 插入数据
my $sth = $dbh->prepare(
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)"
);
$sth->execute("Alice", "alice@example.com", 25);
$sth->execute("Bob", "bob@example.com", 30);
$sth->finish();
# 获取最后插入的 ID
my $last_id = $dbh->{mysql_insertid};
print "Inserted ID: $last_id\n";批量插入
perl
my @users = (
["Charlie", "charlie@example.com", 35],
["David", "david@example.com", 28],
["Eve", "eve@example.com", 32]
);
my $sth = $dbh->prepare(
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)"
);
foreach my $user (@users) {
$sth->execute(@$user);
}
$sth->finish();更新操作
更新记录
perl
use DBI;
my $dbh = DBI->connect("DBI:mysql:database=test", "user", "pass");
# 更新单条记录
my $rows_affected = $dbh->do(
"UPDATE users SET age = ? WHERE name = ?",
undef,
26, # 新年龄
"Alice"
);
print "Updated $rows_affected rows\n";
# 批量更新
$dbh->do("UPDATE users SET age = age + 1");删除操作
删除记录
perl
use DBI;
my $dbh = DBI->connect("DBI:mysql:database=test", "user", "pass");
# 删除单条记录
my $rows_affected = $dbh->do(
"DELETE FROM users WHERE id = ?",
undef,
5
);
print "Deleted $rows_affected rows\n";
# 批量删除
$dbh->do("DELETE FROM users WHERE age < 18");事务处理
基本事务
perl
use DBI;
my $dbh = DBI->connect(
"DBI:mysql:database=test",
"user",
"pass",
{ AutoCommit => 0 } # 禁用自动提交
);
eval {
# 执行多个操作
$dbh->do("INSERT INTO accounts (user_id, amount) VALUES (1, 100)");
$dbh->do("UPDATE accounts SET amount = amount - 100 WHERE user_id = 2");
# 提交事务
$dbh->commit();
print "Transaction committed\n";
};
if ($@) {
# 回滚事务
$dbh->rollback();
print "Transaction rolled back: $@\n";
}
$dbh->disconnect();保存点
perl
$dbh->begin_work();
eval {
$dbh->do("INSERT INTO users (name) VALUES ('Alice')");
# 创建保存点
$dbh->savepoint("sp1");
$dbh->do("INSERT INTO users (name) VALUES ('Bob')");
# 回滚到保存点
$dbh->rollback_to("sp1");
$dbh->commit();
};高级查询
JOIN 查询
perl
my $sth = $dbh->prepare(qq{
SELECT u.name, o.order_date, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.id = ?
});
$sth->execute(1);
while (my $row = $sth->fetchrow_hashref) {
printf "%s: %s - \$%.2f\n",
$row->{name},
$row->{order_date},
$row->{total};
}
$sth->finish();分页查询
perl
my $page = 1;
my $per_page = 10;
my $offset = ($page - 1) * $per_page;
my $sth = $dbh->prepare(
"SELECT * FROM users LIMIT ? OFFSET ?"
);
$sth->execute($per_page, $offset);
my @users = @{ $sth->fetchall_arrayref({}) };
$sth->finish();聚合查询
perl
# 计数
my ($count) = $dbh->selectrow_array(
"SELECT COUNT(*) FROM users"
);
# 求和
my ($total) = $dbh->selectrow_array(
"SELECT SUM(amount) FROM orders"
);
# 分组
my $sth = $dbh->prepare(
"SELECT category, COUNT(*) as count FROM products GROUP BY category"
);
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
print "$row->{category}: $row->{count}\n";
}实践示例
示例 1:用户管理系统
perl
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
package UserManager;
use DBI;
sub new {
my ($class, $db_config) = @_;
my $self = {
dbh => DBI->connect(
"DBI:mysql:database=$db_config->{database}",
$db_config->{username},
$db_config->{password}
)
};
bless $self, $class;
return $self;
}
sub add_user {
my ($self, $name, $email, $age) = @_;
my $sth = $self->{dbh}->prepare(
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)"
);
$sth->execute($name, $email, $age);
$sth->finish();
}
sub get_user {
my ($self, $id) = @_;
return $self->{dbh}->selectrow_hashref(
"SELECT * FROM users WHERE id = ?",
undef,
$id
);
}
sub update_user {
my ($self, $id, %fields) = @_;
my @set_clauses = map { "$_ = ?" } keys %fields;
my $sql = "UPDATE users SET " . join(", ", @set_clauses) . " WHERE id = ?";
$self->{dbh}->do($sql, undef, values %fields, $id);
}
sub delete_user {
my ($self, $id) = @_;
$self->{dbh}->do("DELETE FROM users WHERE id = ?", undef, $id);
}
1;
package main;
use UserManager;
my $manager = UserManager->new({
database => "test",
username => "user",
password => "pass"
});
$manager->add_user("Alice", "alice@example.com", 25);
my $user = $manager->get_user(1);
print "User: $user->{name}\n";示例 2:订单处理系统
perl
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
package OrderProcessor;
use DBI;
sub new {
my ($class, $db_config) = @_;
my $self = {
dbh => DBI->connect(
"DBI:mysql:database=$db_config->{database}",
$db_config->{username},
$db_config->{password},
{ AutoCommit => 0 }
)
};
bless $self, $class;
return $self;
}
sub create_order {
my ($self, $user_id, @items) = @_;
eval {
# 创建订单
$self->{dbh}->do(
"INSERT INTO orders (user_id, total) VALUES (?, 0)",
undef,
$user_id
);
my $order_id = $self->{dbh}->{mysql_insertid};
my $total = 0;
# 添加订单项
my $sth = $self->{dbh}->prepare(
"INSERT INTO order_items (order_id, product_id, quantity, price) VALUES (?, ?, ?, ?)"
);
foreach my $item (@items) {
$sth->execute(
$order_id,
$item->{product_id},
$item->{quantity},
$item->{price}
);
$total += $item->{quantity} * $item->{price};
}
# 更新订单总价
$self->{dbh}->do(
"UPDATE orders SET total = ? WHERE id = ?",
undef,
$total,
$order_id
);
# 提交事务
$self->{dbh}->commit();
return $order_id;
};
if ($@) {
$self->{dbh}->rollback();
die "Order creation failed: $@";
}
}
1;
package main;
use OrderProcessor;
my $processor = OrderProcessor->new({
database => "test",
username => "user",
password => "pass"
});
my @items = (
{ product_id => 1, quantity => 2, price => 10.00 },
{ product_id => 2, quantity => 1, price => 20.00 }
);
my $order_id = $processor->create_order(1, @items);
print "Order created: $order_id\n";小结
本章节学习了 Perl 的数据库连接:
- ✅ DBI 基础
- ✅ 查询操作
- ✅ 插入操作
- ✅ 更新操作
- ✅ 删除操作
- ✅ 事务处理
- ✅ 高级查询
- ✅ 实践示例
接下来,我们将学习 Perl 包和模块。