数据库系统原理作业#5 WEB访问数据库

数据库实验五

Author:心猿意马

实验要求

自学掌握在3层或4层架构中访问数据库,通过Web页面的操作插入、修改和查询数据,并将操作结果和数据以Web页面的形式展示出来的技术。自主学习内容范围包括:

Web服务器、应用服务器和数据库服务器的概念

Web服务器安装使用和Web服务器部署

Java(首选)、Python等数据库编程、前端网页脚本语言及编程

第八章中的过程化SQL、存储过程、游标等基本概念

多层架构中各层之间的接口编程技术

实验内容及提交要求:

结合自己所选的应用案例,至少完成一个简单案例,Web页面的操作应包括增、删、改、查,查询结果以表格或表单形式展现。

整个系统架构至少应包括前端、Web服务器、应用服务器、数据库服务器。Web服务器和应用服务器可以合在一起,也可以根据硬件资源情况分开。

要求提交系统代码、程序与实验报告,届时将逐个检查。

flask框架版

基础配置信息讲解

首先进入虚拟环境,这里我们使用的是anaconda prompt
anaconda
我们进入我们自己创造的虚拟环境 pytorch

conda activate pytorch

输入下面的代码,用来安装必要的库

pip install flask mysql-connector-python

可能会有点慢,接下来在下载的同时,我介绍一下创建项目的注意事项
编译器使用的是jetbrain公司的pycharm,如果你是学生可以免费使用(得向jetbran公司提交一些学信网的材料)
在pycharm左上角的新建项目里面选择flask项目,将所需的虚拟环境添加到解释器即可
然后在创建好的文件夹下的templates文件夹放入这些html文件(文件代码放在本章末尾)
mainpage.html
SignUp.html
Revice.html
Revoke.html
Inquiry.html
Dynamic_express.html
我的数据库补充说明:
我的数据库是放在学校的虚拟机上面的,登录校园网才能访问。
其次,本次实验操作的表是我的数据库"zhihu_db"中的usr表,该表的建库SQL语句如下

create table usr
(
    usr_id           int          not null
        primary key,
    ip_address       varchar(45)  not null,
    user_brief_intro varchar(140) null,
    user_name        varchar(10)  not null
)
    collate = utf8mb3_unicode_ci;

项目结构示意图

flask_db5/
├── app.py ->这只是个py文件示意,不是链接,不要点
├── templates/
│ ├── mainpage.html
│ ├── SignUp.html
│ ├── Revice.html
│ ├── Revoke.html
│ ├── Inquiry.html
│ └── Dynamic_express.html
└── static/
这里只要注意这五个html和app.py的相对位置就行了

如何验证已经连接并登录上了数据库?

验证用代码
from flask import Flask, render_template_string
import mysql.connector

app = Flask(__name__)

# 数据库连接信息
db_config = {
    'user': 'root',
    'password': '123456',
    'host': '172.24.65.160',
    'database': 'zhihu_db',
    'port': 3306
}


# 数据库连接
def get_db_connection():
    conn = mysql.connector.connect(**db_config)
    return conn


@app.route('/')
def index():
    try:
        conn = get_db_connection()
        cursor = conn.cursor(dictionary=True)
        cursor.execute('SELECT * FROM usr')
        users = cursor.fetchall()
        cursor.close()
        conn.close()

        # 渲染用户信息的简单HTML模板
        template = """
        <!doctype html>
        <title>User List</title>
        <h1>User List</h1>
        <table border="1">
            <tr>
                <th>usr_id</th>
                <th>ip_address</th>
                <th>user_brief_intro</th>
                <th>user_name</th>
            </tr>
            {% for user in users %}
            <tr>
                <td>{{ user.usr_id }}</td>
                <td>{{ user.ip_address }}</td>
                <td>{{ user.user_brief_intro }}</td>
                <td>{{ user.user_name }}</td>
            </tr>
            {% endfor %}
        </table>
        """

        return render_template_string(template, users=users)
    except Exception as e:
        return f"An error occurred: {e}"


if __name__ == '__main__':
    app.run(debug=True)

代码讲解

其他的都没有什么讲的,如果你需要使用,只需要更改下面的内容

# 数据库连接信息
db_config = {
    'user': 'root',
    'password': '123456',
    'host': '172.24.65.160',
    'database': 'zhihu_db',
    'port': 3306
}

host是你的数据库的地址,有的是localhost,有的则是登录ip地址
database是你的数据库的名字
port是端口,这个一般不变
user和password是你的这个数据库登录时候使用的用户和密码
这里的代码是简单地提取我的usr表中的内容,让我们尝试运行一下

运行与验证结果

在这里插入图片描述

这里的Runnig on http…………
告诉我们要到这个网址找,那么我们打开我们的浏览器输入相应的IP地址看看吧。
在这里插入图片描述

那么果不其然我们成功验证了能够链接上数据库,接下来我们直接开始吧

三重架构实现增删改查flask版

设计运行展示

先注册
在这里插入图片描述

我们在后台查看是否注册成功?
在这里插入图片描述

确实注册成功了,那么我们接下来进行查询、注销等一系列操作吧

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

架构设计讲解&代码讲解

在Flask应用中,三层架构通常由表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)组成。这种架构设计有助于分离关注点,使代码更加模块化、易于维护和扩展。

表示层(Presentation Layer)

功能: 负责与用户交互,处理用户输入并将输出结果展示给用户。表示层主要包含视图函数和模板。

在Flask中的实现:

  • 视图函数: 处理HTTP请求,调用业务逻辑,并返回HTTP响应。视图函数通常使用装饰器@app.route来定义。
  • 模板: 使用Jinja2模板引擎将数据渲染为HTML页面,以提供给用户。模板文件通常存放在templates文件夹中。
业务逻辑层(Business Logic Layer)

功能: 负责处理应用的业务逻辑。包括数据验证、数据处理以及与数据访问层的交互。业务逻辑层通常包含在视图函数中,但也可以抽象到单独的服务或模块中。

在Flask中的实现:

  • 视图函数中的业务逻辑: 处理用户输入数据,调用数据访问层,执行业务操作,并返回结果。
  • 独立模块或服务: 可以将复杂的业务逻辑提取到单独的模块或服务中,以便于复用和测试。
数据访问层(Data Access Layer)

功能: 负责与数据库或其他持久化存储进行交互,执行CRUD操作。数据访问层通常封装在单独的函数或类中,以便于复用和维护。

在Flask中的实现:

  • 数据库连接: 管理与数据库的连接,执行SQL查询,并返回结果。

  • 数据访问函数: 封装具体的数据库操作,如插入、查询、更新和删除等。

  • 表示层(Presentation Layer): 包含视图函数和模板,负责处理HTTP请求和响应,渲染HTML页面。

  • 业务逻辑层(Business Logic Layer): 包含应用的业务逻辑,处理用户输入和数据处理。

  • 数据访问层(Data Access Layer): 负责与数据库交互,执行CRUD操作。

代码展示
app.py
from flask import Flask, render_template, request, redirect, url_for
import mysql.connector

app = Flask(__name__)

# 数据库连接信息
db_config = {
    'user': 'root',
    'password': '123456',
    'host': '172.24.65.160',
    'database': 'zhihu_db',
    'port': 3306
}


# 数据库连接
def get_db_connection():
    conn = mysql.connector.connect(**db_config)
    return conn


# 首页 - 用户中心
@app.route('/')
def main_page():
    return render_template('mainpage.html')


# 用户注册
@app.route('/signup', methods=['GET', 'POST'])
def sign_up():
    if request.method == 'POST':
        usr_id = request.form['usr_id']
        ip_address = request.form['ip_address']
        user_brief_intro = request.form['user_brief_intro']
        user_name = request.form['user_name']

        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute(
            'INSERT INTO usr (usr_id, ip_address, user_brief_intro, user_name) VALUES (%s, %s, %s, %s)',
            (usr_id, ip_address, user_brief_intro, user_name)
        )
        conn.commit()
        cursor.close()
        conn.close()

        return redirect(url_for('main_page'))
    return render_template('SignUp.html')


# 用户信息修改
@app.route('/revice', methods=['GET', 'POST'])
def revice():
    if request.method == 'POST':
        usr_id = request.form['usr_id']
        user_name = request.form['user_name']
        user_brief_intro = request.form['user_brief_intro']
        ip_address = request.form['ip_address']

        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute(
            'UPDATE usr SET user_name = %s, user_brief_intro = %s, ip_address = %s WHERE usr_id = %s',
            (user_name, user_brief_intro, ip_address, usr_id)
        )
        conn.commit()
        cursor.close()
        conn.close()

        return redirect(url_for('main_page'))
    return render_template('Revice.html')


# 用户注销
@app.route('/revoke', methods=['GET', 'POST'])
def revoke():
    if request.method == 'POST':
        usr_id = request.form['usr_id']

        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute('DELETE FROM usr WHERE usr_id = %s', (usr_id,))
        conn.commit()
        cursor.close()
        conn.close()

        return redirect(url_for('main_page'))
    return render_template('Revoke.html')


# 用户查询
@app.route('/inquiry', methods=['GET', 'POST'])
def inquiry():
    user_data = None
    if request.method == 'POST':
        usr_id = request.form['usr_id']

        conn = get_db_connection()
        cursor = conn.cursor(dictionary=True)
        cursor.execute('SELECT * FROM usr WHERE usr_id = %s', (usr_id,))
        user_data = cursor.fetchone()
        cursor.close()
        conn.close()
    return render_template('Inquiry.html', user_data=user_data)


# 用户列表
@app.route('/dynamic_express')
def dynamic_express():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute('SELECT * FROM usr')
    users = cursor.fetchall()
    cursor.close()
    conn.close()
    return render_template('Dynamic_express.html', users=users)


if __name__ == '__main__':
    app.run(debug=True)

主页mainpage.html
<!DOCTYPE html>
<html>
<head>
    <title>用户中心</title>
    <style>
        body {
            background-color: #e0f2f1; /* 温和的绿色背景 */
            font-family: '微软雅黑'; /* 统一字体设置为微软雅黑 */
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* 设置视口高度,使内容垂直居中 */
        }
        .container {
            width: 50%; /* 设置容器宽度 */
            background-color: #ffffff; /* 容器背景色 */
            padding: 20px;
            border-radius: 10px; /* 圆角边框 */
            box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 阴影效果 */
            text-align: center; /* 文字居中 */
        }
        button {
            font-family: '微软雅黑'; 
            width: 80%; /* 按钮宽度 */
            padding: 15px; /* 按钮内边距 */
            margin-top: 10px; /* 按钮顶部边距 */
            margin-bottom: 10px; /* 按钮底部边距 */
            cursor: pointer; /* 鼠标悬停显示指针 */
            border: none;
            background-color: #4CAF50; /* 按钮背景色 */
            color: white; /* 文字颜色 */
            border-radius: 5px; /* 按钮圆角 */
        }
        button:hover {
            background-color: #45a049; /* 按钮悬停时的背景色变化 */
        }
    </style>
</head>
<body>
    <div class="container">
        <p style="font-size: 40px;">用户中心</p>
        <button onclick="window.location.href='{{ url_for('sign_up') }}'">用户注册</button>
        <button onclick="window.location.href='{{ url_for('revice') }}'">用户信息修改</button>
        <button onclick="window.location.href='{{ url_for('revoke') }}'">用户注销</button>
        <button onclick="window.location.href='{{ url_for('inquiry') }}'">用户查询</button>
        <button onclick="window.location.href='{{ url_for('dynamic_express') }}'">用户列表</button>
    </div>
</body>
</html>

注册页SignUp.html
<!DOCTYPE html>
<html>
<head>
    <title>Sign Up</title>
    <style>
        body {
            background-color: #e0f2f1; /* 更温和的绿色背景 */
            font-family: '微软雅黑'; /* 统一字体设置为微软雅黑 */
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* 设置视口高度,使内容垂直居中 */
        }
        .container {
            width: 50%; /* 设置容器宽度 */
            background-color: #ffffff; /* 容器背景色 */
            padding: 20px;
            border-radius: 10px; /* 圆角边框 */
            box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 阴影效果 */
        }
        input, button {
            font-family: '微软雅黑'; 
            width: 95%; /* 输入框宽度 */
            padding: 10px; /* 输入框内边距 */
            margin-top: 5px; /* 顶部边距 */
            margin-bottom: 15px; /* 底部边距 */
        }
        form {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <p align="center" style="font-size: 40px;">Sign Up</p>
        <form method="post" action="{{ url_for('sign_up') }}">
            Enter usr_id(输入用户ID):<br>
            <input type="number" name="usr_id" placeholder="usr_id">
            <br>
            Enter ip_address(输入用户IP地址):<br>
            <input type="text" name="ip_address" placeholder="ip_address">
            <br>
            Enter user_brief_intro(输入个人简介):<br>
            <input type="text" name="user_brief_intro" placeholder="user_brief_intro">
            <br>
            Enter user_name(输入用户昵称):<br>
            <input type="text" name="user_name" placeholder="user_name">
            <br>
            <input type="submit" value="Submit">
        </form>
        <form method="post" action="{{ url_for('main_page') }}">
            <input type="submit" value="返回">
        </form>
    </div>
</body>
</html>

修改页Revice.html
<!DOCTYPE html>
<html>
<head>
    <title>修改用户信息</title>
    <style>
        body {
            background-color: #e0f2f1; /* 更温和的绿色背景 */
            font-family: '微软雅黑'; /* 统一字体设置为微软雅黑 */
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* 设置视口高度,使内容垂直居中 */
        }
        .container {
            width: 50%; /* 设置容器宽度 */
            background-color: #ffffff; /* 容器背景色 */
            padding: 20px;
            border-radius: 10px; /* 圆角边框 */
            box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 阴影效果 */
        }
        input, button {
            font-family: '微软雅黑'; 
            width: 95%; /* 输入框宽度 */
            padding: 10px; /* 输入框内边距 */
            margin-top: 5px; /* 顶部边距 */
            margin-bottom: 15px; /* 底部边距 */
        }
        form {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <p align="center" style="font-size: 40px;">修改用户信息</p>
        <form method="post" action="{{ url_for('revice') }}">
            Enter usr_id(输入用户ID):<br>
            <input type="number" name="usr_id" placeholder="usr_id">
            <br>
            Enter new user_name(输入新的用户昵称):<br>
            <input type="text" name="user_name" placeholder="user_name">
            <br>
            Enter new user_brief_intro(输入新的个人简介):<br>
            <input type="text" name="user_brief_intro" placeholder="user_brief_intro">
            <br>
            Enter new ip_address(输入新的IP地址):<br>
            <input type="text" name="ip_address" placeholder="ip_address">
            <br>
            <input type="submit" value="Submit">
        </form>
        <form method="post" action="{{ url_for('main_page') }}">
            <input type="submit" value="返回">
        </form>
    </div>
</body>
</html>

注销页revoke.html
<!DOCTYPE html>
<html>
<head>
    <title>注销用户</title>
    <style>
        body {
            background-color: #e0f2f1; /* 更温和的绿色背景 */
            font-family: '微软雅黑'; /* 统一字体设置为微软雅黑 */
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* 设置视口高度,使内容垂直居中 */
        }
        .container {
            width: 50%; /* 设置容器宽度 */
            background-color: #ffffff; /* 容器背景色 */
            padding: 20px;
            border-radius: 10px; /* 圆角边框 */
            box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 阴影效果 */
        }
        input, button {
            font-family: '微软雅黑'; 
            width: 95%; /* 输入框宽度 */
            padding: 10px; /* 输入框内边距 */
            margin-top: 5px; /* 顶部边距 */
            margin-bottom: 15px; /* 底部边距 */
        }
        form {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .warning {
            color: red;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <p align="center" style="font-size: 40px;">注销用户</p>
        <form method="post" action="{{ url_for('revoke') }}">
            Enter usr_id(输入用户ID):<br>
            <input type="number" name="usr_id" placeholder="usr_id">
            <br>
            <input type="submit" value="Submit">
        </form>
        <form method="post" action="{{ url_for('main_page') }}">
            <input type="submit" value="返回">
        </form>
        <p class="warning">注意:注销账户不可恢复!</p>
    </div>
</body>
</html>

查询页Inquiry.html
<!DOCTYPE html>
<html>
<head>
    <title>查询用户信息</title>
    <style>
        body {
            background-color: #e0f2f1; /* 更温和的绿色背景 */
            font-family: '微软雅黑'; /* 统一字体设置为微软雅黑 */
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* 设置视口高度,使内容垂直居中 */
        }
        .container {
            width: 50%; /* 设置容器宽度 */
            background-color: #ffffff; /* 容器背景色 */
            padding: 20px;
            border-radius: 10px; /* 圆角边框 */
            box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 阴影效果 */
        }
        input, button {
            font-family: '微软雅黑'; 
            width: 95%; /* 输入框宽度 */
            padding: 10px; /* 输入框内边距 */
            margin-top: 5px; /* 顶部边距 */
            margin-bottom: 15px; /* 底部边距 */
        }
        form {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .result {
            margin-top: 20px;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <p align="center" style="font-size: 40px;">查询用户信息</p>
        <form method="post" action="{{ url_for('inquiry') }}">
            Enter usr_id(输入用户ID):<br>
            <input type="number" name="usr_id" placeholder="usr_id">
            <br>
            <input type="submit" value="Submit">
        </form>
        <form method="post" action="{{ url_for('main_page') }}">
            <input type="submit" value="返回">
        </form>
        {% if user_data %}
        <div class="result">
            <p>用户ID: {{ user_data.usr_id }}</p>
            <p>IP地址: {{ user_data.ip_address }}</p>
            <p>个人简介: {{ user_data.user_brief_intro }}</p>
            <p>用户名: {{ user_data.user_name }}</p>
        </div>
        {% endif %}
    </div>
</body>
</html>

动态显示页Dynamic_express.html
<!DOCTYPE html>
<html>
<head>
    <title>用户列表</title>
    <style>
        body {
            background-color: #e0f2f1; /* 更温和的绿色背景 */
            font-family: '微软雅黑'; /* 统一字体设置为微软雅黑 */
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* 设置视口高度,使内容垂直居中 */
        }
        .container {
            width: 80%; /* 设置容器宽度 */
            background-color: #ffffff; /* 容器背景色 */
            padding: 20px;
            border-radius: 10px; /* 圆角边框 */
            box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 阴影效果 */
            text-align: center; /* 文字居中 */
        }
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            padding: 8px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }
        th {
            background-color: #f2f2f2;
        }
    </style>
</head>
<body>
    <div class="container">
        <p align="center" style="font-size: 40px;">用户列表</p>
        <table>
            <tr>
                <th>用户ID</th>
                <th>IP地址</th>
                <th>个人简介</th>
                <th>用户名</th>
            </tr>
            {% for user in users %}
            <tr>
                <td>{{ user.usr_id }}</td>
                <td>{{ user.ip_address }}</td>
                <td>{{ user.user_brief_intro }}</td>
                <td>{{ user.user_name }}</td>
            </tr>
            {% endfor %}
        </table>
        <form method="post" action="{{ url_for('main_page') }}">
            <input type="submit" value="返回">
        </form>
    </div>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值