45、数据库应用开发:从单机到 Web 的实现与优化

数据库应用开发:从单机到 Web 的实现与优化

1. 项目实现概述

在项目开发中,实现环节至关重要,它涉及到选择合适的编程语言和 API,进行面向对象设计并编写代码。对于本项目,我们需要快速开发出一个多功能的程序,并且要考虑到程序未来的扩展性。

1.1 语言和 API 选择

选择编程语言时需综合考虑多方面因素。由于要快速得到最终产品,且程序应具备扩展性,我们选择了 Perl。不过,Python、C++ 或 PHP 也是不错的选择。Perl 在 Linux 和数据库领域广受欢迎,它易于 shell 程序员快速掌握,结构也符合 C 程序员的习惯,同时还是一种支持继承(包括多重继承)和数据保护的面向对象语言。在最近的一项针对 Linux 用户的脚本语言调查中,Perl 在非 Web 编程的脚本语言中排名第一。

1.2 面向对象编程基础

面向对象编程是一种设计和实现代码的方式,它将方法(函数)和数据捆绑在一起,形成类,类是创建对象的框架,对象是类的实例。以下是面向对象编程中的一些常见术语及在 Perl 中的实现示例:
|术语|解释|Perl 示例|
| ---- | ---- | ---- |
|对象(Object)|也称为类的实例,数据和方法封装在一起| $table; # 具有表的数据属性和方法 |
|构造函数(Constructor)|初始化对象| $table=customer-> new(); # $table 现在具有与 customer 相关的数据属性 |
|属性(Attributes)|对象的数据(属性),不应直接访问| $table->{STATE_CD} # 对象的最终用户不需要看到这个 |
|方法(Method)|对象可以执行的任务,通常称为对象的行为| $query=$table->delete("customer_xyz"); # 编写删除客户 xyz 的查询 |
|封装(Encapsulation)|隐藏对象属性的存储方式和位置| - |
|继承(Inheritance)|使用另一个类的方法| $table-> action_menu(); # 使用菜单类的 action_menu 方法 |

1.3 客户类(Customer Class)

客户类是一个用 Perl 编写的类,它展示了一些实用的面向对象技术。该类以 Customer 表为模型,可执行给表属性赋值、插入数据、删除行和浏览表等操作。以下是客户类的代码:

#!/usr/bin/perl
package customer;
use menu;
# inherit methods from menu
@ISA = ("menu");

sub new {
    my $proto=shift;
    my $class=ref($proto) || $proto;
    my $self={};
    $self->{FIRST_NAME}=undef;
    $self->{MIDDLE_INITIAL}=undef;
    $self->{LAST_NAME}=undef;
    $self->{ADDRESS_LINE_1}=undef;
    $self->{ADDRESS_LINE_2}=undef;
    $self->{CITY}=undef;
    $self->{STATE}=undef;
    $self->{ZIP}=undef;
    $self->{CUSTOMER_ID}=undef;
    $self->{PHONE_NUMBER}=undef;
    bless($self,$class);
    return $self;
}

sub zip {
    my $self = shift;
    if (@_) { $self->{ZIP} = shift }
    return $self->{ZIP};
}

# 其他方法如 phone_number、customer_id 等类似,此处省略

sub primary_key {
    my $self = shift;
    if (@_) { $self->{CUSTOMER_ID} = shift }
    return $self->{CUSTOMER_ID};
}

sub insert {
    my $self = shift;
    # Connect to database
    my $dbname='order_entry_db';
    my $user='dba';
    my $password='dba2pass';
    my $dbd='mysql';
    my $dbh=DBI->connect($dbname, $user, $password, $dbd);
    if (!$dbh) {
        print "ERROR connecting to database; $DBI::errstr\n";
    }else {
        print "connecting to database\n";
    }
    # create local values to use
    my $cust_id=$self->customer_id;
    my $first_name=$self->first_name;
    my $middle_initial=$self->middle_initial;
    my $last_name=$self->last_name;
    my $address_line_1=$self->address_line_1;
    my $address_line_2=$self->address_line_2;
    my $city=$self->city;
    my $state=$self->state;
    my $zip=$self->zip;
    my $phone_number=$self->phone_number;
    # create query
    my $query="insert into customer values ( $cust_id','$first_name',
            $middle_initial','$last_name',
            $address_line_1','$address_line_2',
            $city','$state','$zip',
            $phone_number','N')";
    # execute query
    print "preparing and executing sql.\n";
    my $sth=$dbh->prepare("$query");
    my $error=$sth->execute;
    $sth->finish;
    $dbh->disconnect();
    return $error;
}

# browse 和 delete 方法类似,此处省略
1;

客户类虽然能处理表的各种操作,但存在一些可优化的地方,例如数据库连接信息硬编码多次,可将其作为构造函数的参数或类数据,以提高类的通用性。

1.4 菜单类(Menu Class)

菜单类是表类的超类,具有通用性,任何具有哈希数据类型的对象都可访问该类。部分菜单是动态构建的,如字段菜单;部分是静态构建的,如表格菜单。以下是菜单类的代码:

#!/usr/bin/perl
package menu;
use DBI;
@ISA=("DBI");

sub new {
    my $proto=shift;
    my $class=ref($proto) || $proto;
    my $self={};
    bless($self,$class);
}

sub table_menu {
    print ("Welcome..
        Please select a table from the following list or quit [q]:
        1) Product
        2) Customer
        3) Order Header
        4) Order Detail
    Make your selection: ");
    my $selection=<STDIN>;
    if ($selection == 1) {
        return 1;
    }elsif( $selection == 2) {
        return 2;
    }elsif ( $selection == 3) {
        return 3;
    }elsif( $selection == 3) {
        return 4;
    } elsif ($selection =~ m/[qQ]/) {
        die "Exiting application at users request.\n";
    } else { action();}
}

# 其他方法如 action_menu、field 等类似,此处省略

这个流程图展示了菜单类中 table_menu 方法的执行流程:

graph TD;
    A[开始] --> B[显示菜单选项];
    B --> C[获取用户输入];
    C --> D{输入是否为 q/Q};
    D -- 是 --> E[退出应用];
    D -- 否 --> F{输入是否为 1};
    F -- 是 --> G[返回 1];
    F -- 否 --> H{输入是否为 2};
    H -- 是 --> I[返回 2];
    H -- 否 --> J{输入是否为 3};
    J -- 是 --> K[返回 3];
    J -- 否 --> L{输入是否为 4};
    L -- 是 --> M[返回 4];
    L -- 否 --> N[执行 action() 方法];

1.5 主程序

主程序使用上述类来实现菜单驱动的用户界面。代码如下:

#!/usr/bin/perl
use customer;
use product;
use order_detail;
use order_header;
use strict;
# Strict requires this definition
my $table=undef;

my $table_choice=menu->table_menu();
if($table_choice==1) {
    $table=product->new();
}elsif($table_choice==2) {
    $table=customer->new();
}else { die "ERROR Line 25\n"; }

my $action=$table->action_menu();
if($action==1) {
    my $continue=$table->field();
    if($continue) {
        print "inserting customer into table ..\n";
        my $query=$table->insert();
        my $sth=$dbh->prepare("$query");
        my $error=$sth->execute;
    }
}
elsif($action==2) {
    my $pkey=$table->delete_menu;
    if($pkey) {
        $table->primary_key($pkey);
        my $query=$table->delete();
        print "deleting row where primary key is $pkey. \n";
        my $sth=$dbh->prepare("$query\n");
        my $error=$sth->execute;
    }
}
elsif($action==3) {
    my $continue=$table->browse_menu;
    if ($continue) {
        my $query=$table->browse();
        my $sth=$dbh->prepare("$query\n");
        my $error=$sth->execute;
        my @fields=undef;
        while(@fields=$sth->fetchrow_array) {
            print "@fields\n";
        }
    }
}
$dbh->disconnect();

主程序通过调用菜单类和客户类等,实现了用户选择表、执行操作(插入、删除、浏览)的功能。但目前代码存在一些不足,如使用数字返回码不够灵活,菜单类可以返回表名,结合只需表名就能构造自身的表类,可使程序更具通用性。

2. 从单机应用到 Web 应用的转变

2.1 新的业务需求

之前开发的单机应用的商业客户提出了一些新的需求。由于经济环境的变化,客户希望开始通过互联网接受订单。具体要求如下:
1. 登录页面 :客户需要登录网站,因此需要一个登录页面。
2. 购买历史查询 :在订单数据库中查询客户的购买历史,所以客户使用的登录 ID 必须存在于订单录入数据库中,或者通过某种外键关系进行关联。
3. 订单页面 :需要一个用于下单的网页,并且要让客户清楚如何使用。
4. 折扣计算与显示 :自动计算折扣(如果有),并在订单表单上显示节省的金额。

2.2 技术选型

经过深思熟虑,我们决定使用 PHP 来实现网页和与订单录入数据库的接口。这种方法有以下优点:
- 服务器端执行 :PHP 可以在服务器端执行数据库访问,而不像 Java 需要在客户端运行安全的小程序。
- MySQL 支持 :我们仍然使用 MySQL 作为数据库,PHP4 已经包含了对 MySQL 的支持,而使用 PHP3 时,需要使用 -with - mysql = DIR 选项进行安装。

2.3 数据模型集成与示例代码

结合给定的数据模型,我们可以通过以下示例 PHP 代码来实现集成,通过扩展这些示例可以创建更复杂的应用。以下是一个简单的登录验证示例:

<?php
// 数据库连接信息
$servername = "localhost";
$username = "dba";
$password = "dba2pass";
$dbname = "order_entry_db";

// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);

// 检查连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}

// 获取用户输入
$loginID = $_POST['loginID'];
$password = $_POST['password'];

// 查询用户信息
$sql = "SELECT * FROM customers WHERE loginID = '$loginID' AND password = '$password'";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    // 用户验证成功
    session_start();
    $_SESSION['loginID'] = $loginID;
    header("Location: order_page.php");
} else {
    // 用户验证失败
    echo "用户名或密码错误";
}

$conn->close();
?>

这个代码示例展示了一个基本的登录验证流程,流程图如下:

graph TD;
    A[开始] --> B[连接数据库];
    B --> C[获取用户输入的登录 ID 和密码];
    C --> D[查询数据库验证用户];
    D --> E{用户是否存在};
    E -- 是 --> F[创建会话并跳转至订单页面];
    E -- 否 --> G[显示错误信息];
    F --> H[结束];
    G --> H;

2.4 订单页面与折扣计算

以下是一个简单的订单页面示例,包含折扣计算功能:

<?php
session_start();
if (!isset($_SESSION['loginID'])) {
    header("Location: login.php");
}

// 数据库连接信息
$servername = "localhost";
$username = "dba";
$password = "dba2pass";
$dbname = "order_entry_db";

// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);

// 检查连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}

// 查询用户购买历史
$loginID = $_SESSION['loginID'];
$sql = "SELECT SUM(total_amount) as total_purchase FROM orders WHERE customer_id = (SELECT customer_id FROM customers WHERE loginID = '$loginID')";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
$total_purchase = $row['total_purchase'];

// 计算折扣
$discount = 0;
if ($total_purchase > 150) {
    $discount = 0.1; // 10% 折扣
}

// 显示订单页面
echo "<h1>订单页面</h1>";
echo "<p>您的总消费金额: $total_purchase</p>";
echo "<p>本次订单折扣: $discount%</p>";

// 模拟商品列表
$products = [
    ["id" => 1, "name" => "Product 1", "price" => 50],
    ["id" => 2, "name" => "Product 2", "price" => 100],
    ["id" => 3, "name" => "Product 3", "price" => 200]
];

echo "<form action='submit_order.php' method='post'>";
foreach ($products as $product) {
    echo "<p>{$product['name']}: $ {$product['price']} <input type='number' name='quantity[{$product['id']}]' value='0'></p>";
}
echo "<input type='submit' value='提交订单'>";
echo "</form>";

$conn->close();
?>

这个代码示例展示了订单页面的基本结构和折扣计算逻辑,其操作步骤可以总结为:
1. 检查用户是否已登录,若未登录则跳转至登录页面。
2. 连接数据库,查询用户的购买历史。
3. 根据购买历史计算折扣。
4. 显示订单页面,包括商品列表和折扣信息。
5. 提供表单供用户输入商品数量并提交订单。

2.5 总结与展望

通过上述内容,我们展示了从单机数据库应用到 Web 应用的转变过程。在单机应用中,我们使用 Perl 进行面向对象编程,实现了菜单驱动的用户界面,处理了表的插入、删除和浏览等操作。而在 Web 应用中,我们根据新的业务需求,选择了 PHP 和 MySQL 技术栈,实现了用户登录、购买历史查询、订单页面和折扣计算等功能。

虽然目前的实现满足了基本需求,但仍有许多可以优化和扩展的地方。例如,在单机应用中,我们可以进一步优化客户类和菜单类,提高代码的通用性和可维护性;在 Web 应用中,我们可以加强安全性,防止 SQL 注入等攻击,同时可以优化用户界面,提高用户体验。通过不断地改进和完善,我们可以开发出更加健壮、高效和灵活的数据库应用程序。

总的来说,无论是单机应用还是 Web 应用,都需要我们在开发过程中充分考虑到未来的扩展性和变化,以确保应用程序能够适应不断变化的业务需求。这种基于生命周期的开发思想是成功开发数据库应用的关键,也是选择 Linux 和 UNIX 等操作系统的重要原因,因为这些操作系统本身就是为了便于重新设计和开发而设计的。

【EI复现】基于主从博弈的新型城镇配电系统产消者竞价策略【IEEE33节点】(Matlab代码实现)内容概要:本文介绍了基于主从博弈理论的新型城镇配电系统中产消者竞价策略的研究,结合IEEE33节点系统,利用Matlab进行仿真代码实现。该研究聚焦于电力市场环境下产消者(既生产又消费电能的主体)之间的博弈行为建模,通过构建主从博弈模型优化竞价策略,提升配电系统运行效率经济性。文中详细阐述了模型构建思路、优化算法设计及Matlab代码实现过程,旨在复现高水平期刊(EI收录)研究成果,适用于电力系统优化、能源互联网及需求响应等领域。; 适合人群:具备电力系统基础知识和一定Matlab编程能力的研究生、科研人员及从事能源系统优化工作的工程技术人员;尤其适合致力于电力市场博弈、分布式能源调度等方向的研究者。; 使用场景及目标:① 掌握主从博弈在电力系统产消者竞价中的建模方法;② 学习Matlab在电力系统优化仿真中的实际应用技巧;③ 复现EI级别论文成果,支撑学术研究或项目开发;④ 深入理解配电系统中分布式能源参市场交易的决策机制。; 阅读建议:建议读者结合IEEE33节点标准系统数据,逐步调试Matlab代码,理解博弈模型的变量设置、目标函数构建求解流程;同时可扩展研究不同市场机制或引入不确定性因素以增强模型实用性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值