数据库课设
背景概述
背景
数据库可谓计算机专业必修的一门课程,为了达到实践效果,推出这么一门实践设计的课程项目,涉及到前端、后端、数据库,以及它们之间的交互技术难题。
这些大多都需要项目成员自行调研,因此本项目是有一定工程量和难度的。值得庆幸的是,我的队友们都非常负责认真,也有很多大佬进行各种技术难题的突破,项目开展至今,是较为顺利的。
如今开发的第一大阶段即将过去,我试图整理一下本项目从开始到现在的各种技术成果,仅供参考。
由于本人进行后端开发,因此后端的技术问题覆盖可能更广一些。
技术分析
首先得有一台服务器,腾讯云或阿里云都可以,我们组采用腾讯云的一个2核2G的linux云服务器,使用新人优惠购买一年有效期可以将价格控制在100以内。
需要注意的是,linux的操作系统也存在不同的发行版,如Centos、Ubuntu、AliCloud等等。不同的类别会内置一些不同的安装工具包,如yum、apt、wget等等。
由于腾和阿里打折优惠的力度可能不同或时间上错开,可以博观而约取,选个最便宜的。
数据库部署
数据库版本采用Oracle12c,使用Docker部署
首先在服务器上安装好docker,oracle的环境配置极为复杂
(本人在自己电脑上配了12c后卸载再装19c,可能注册表误删,导致整个系统重装了),使用docker容器是绝对的省力~,安装好了可以使用docker -v
查看版本。使用docker拉取oracle镜像
- 搜索oracle镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27docker search oracle
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
oraclelinux Official Docker builds of Oracle Linux. 903 [OK]
oracleinanutshell/oracle-xe-11g 226
wnameless/oracle-xe-11g-r2 Oracle Express Edition 11g Release 2 on Ubun… 84
gvenzl/oracle-xe Oracle Database XE (21c, 18c, 11g) for every… 80
truevoly/oracle-12c Copy of sath89/oracle-12c image (https://git… 45
quillbuilduser/oracle-18-xe Oracle 18c XE Image for Quill Testing Purpos… 27
oracledb19c/oracle.19.3.0-ee 13
iamseth/oracledb_exporter A Prometheus exporter for Oracle modeled aft… 5
oraclecoherence/coherence-ce Coherence Community Edition 4
18fgsa/oracle-client Hosted version of the Oracle Container Image… 2
kasmweb/oracle-8-desktop Oracle Linux 8 desktop for Kasm Workspaces 1
dokken/oraclelinux-8 0
bitnami/oraclelinux-extras Oracle Linux base images 0 [OK]
dokken/oraclelinux-6 Oracle Linux 6 image for kitchen-dokken 0
oracledemo1/hello-world Test docker build from github 0 [OK]
kasmweb/oracle-7-desktop Oracle Linux 7 desktop for Kasm Workspaces 0
oraclejmx/docker_jmx 0
dokken/oraclelinux-7 Oracle Linux 7 image for kitchen-dokken 0
kasmweb/core-oracle-7 Oracle Linux 7 base image for Kasm Workspace… 0
kasmweb/core-oracle-8 Oracle Linux 8 base image for Kasm Workspace… 0
bitnami/oraclelinux-extras-base 0
oraclejp/weather-collector 0
oraclejp/paasdocs-preview 0
bitnami/oraclelinux-base-buildpack Oracle Linux bitnami-base-buildpack 0
bitnami/oraclelinux-runtimes Oracle Linux runtime-optimized images 0 [OK]根据学长的经验我们选择了truevoly/oracle-12c
镜像
1
2
3
4
5
6
7
8
9
10
11
12
13docker pull truevoly/oracle-12c
Using default tag: latest
latest: Pulling from truevoly/oracle-12c
863735b9fd15: Pull complete
4fbaa2f403df: Pull complete
44be94a95984: Pull complete
a3ed95caeb02: Pull complete
b8bc6e8767ee: Pull complete
c918da326197: Pull complete
448e1619a038: Pull complete
faadd00cf98e: Downloading [========> ] 463MB/2.768GB
197958b982b1: Download complete
1d3ee67a57bb: Download complete- 由于服务器的带宽不同,下载速度可能也会不同,下载完毕后查看本地的镜像
1
2
3docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
truevoly/oracle-12c latest 21789d4d876f 3 years ago 5.7GB- 运行镜像(关于docker的run命令的进一步解释)
1
2docker run -d -p 1521:1521 --name oracle12c 21789d4d876f //
b5f0b283e506e0296a0987f92380a63ee970fe8417066b8ef00ed347ca7b2611oracle12c是取名,21789d4d876f是镜像的id,-d表示后台运行;-p表示端口映射格式为“主机端口:容器端口”,oracle的端口一般为1521,因此容器端口为1521,将主机端口设置为1521后,可以直接通过访问主机的1521端口来访问到容器内的1521端口;该命令返回运行容器的id
- 查看运行中的容器
1
docker ps
- 进入容器内部,然后使用sqlplus命令进入数据库,超管账号(username=system,password=oracle,这个应该会根据不同的版本有所不同)
1
2docker exec -it 容器id bash
sqlplus- 由于超管账号下有许多系统表,因此不能直接用来存放我们的表格。我们使用超管创建一个新的账号,并给予权限,用于存放数据库表格。
1
2create user TEST_ACCOUNT identified by TEST_PASSWORD;
grant CONNECT, RESOURCE, DBA TO TEST_ACCOUNT;使用图形化界面连接数据库
关于数据库的图形化软件有很多,如sqldeveloper等,我选择了JetBrains的DataGrip,可以从官网下载,也可以使用scoop或homebrew包管理工具直接下载
(正版需在JetBrains官网上进行学生认证,要上传学生证)1
2brew install datagrip // macos
scoop install datagrip // windows安装完毕后,用图形化工具连接数据库,输入账号密码后点击“测试连接”,若测试成功则成功连接上
有了图形化界面后,便可以将已经建好的表手动导入数据库之中,这将是一个繁琐的工作……
Back-End
本项目后端开发由我和szb同学共同完成,使用ASP.NET WebApi框架,版本5.0(目前已停止维护,.net6.0已发布)
这是我们的github账号链接:Gxyrious, cerebellumking
这是项目仓库:Back-End
ASP.NET项目的创建与初始化
- 在Visual Studio中新建.net项目,如图所示
这是项目初始化后的目录文件:
其中,Controllers文件夹放的是控制器,用于写具体的api函数;
Program.cs和Startup.cs中存放了是项目的配置和启动操作,在Startup.cs中已经配置了swagger的api界面,直接点击运行就可以看到WeatherForecastController.cs中写的Get方法的api函数,其请求参数为空,响应参数为一个Array,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12[ ]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}而WeatherForecast.cs则是作为一个Model,定义了WeatherForecast类,和Controller同属于一个namespace之下,因此可以直接使用该Model
使用ORM(对象关系映射)将数据库中的表格映射为项目中的类
首先下载一些程序包:首先点击,工具-NuGet包管理器-管理解决方案的NuGet程序包中,
下载如下几个工具包,如下图所示,由于使用的.net版本为5.0,故我们选择的包都是5.0的最后一个版本。
- Microsoft.EntityFrameworkCore.Design
- Microsoft.EntityFrameworkCore.Tools
- Oracle.EntityFrameworkCore
我们使用Microsoft.EntityFrameworkCore中的DbContext类。当我们在某个控制器的api接口中想对数据库进行增删改查时,可以直接创建一个ModelContext实例,通过该实例的一系列成员函数来与数据库会话,从而封装了sql查询语句。
首先进入“工具-NuGet包管理器-程序包管理器控制台”中
然后在命令行中输入如下命令(将*替换为自己的服务器ip和数据库账号密码)
1
Scaffold-DbContext "Data Source=**.**.**.**/xe;Password=******;User ID=***;" Oracle.EntityFrameworkCore -OutputDir Models -context ModelContext -Force
这时候我们就会发现在目录中多了一个Models文件夹,其中将该db用户下的所有表格都生成了一个.cs文件,以及还有一个ModelContext.cs文件
1
2
3
4
5
6
7
8
9
10
11
12
13public partial class ModelContext : DbContext
{
public ModelContext()
{
}
public ModelContext(DbContextOptions<ModelContext> options)
: base(options)
{
}
// 此处省略很多行......
}这时我们就已经成功将数据库映射为.Net中的类和对象了。
创建Controller
- 右击Controller文件,添加控制器,以最简单的LoginController为例
在原来的基础上添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19using ASP.NET.Core.Test.Models; // 使用Models命名空间
namespace ASP.NET.Core.Test.Controllers
{
[ ]
[ ]
public class LoginController : ControllerBase
{
private readonly ModelContext myContext; // 创建一个模型上下文对象
// 构造函数,在每次调用该Controller中的api函数时,都会创建一个context对象用于操作数据库
public LoginController(ModelContext modelContext)
{
myContext = modelContext;
}
// 在此处敲api函数
}
}当然,为了让api调用时能够传入一个ModelContext对象,我们需要在startup.cs的ConfigureServices函数中增加一行代码
services.AddScoped<ModelContext>()
1
2
3
4
5
6
7
8
9
10
11using ASP.NET.Core.Test.Models; // 使用Models
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<ModelContext>(); // 这行代码让每次调用api时都自动传入一个context
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ASP.NET.Core.Test", Version = "v1" });
});
}接下来在LoginController.cs中添加登录api函数,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24[ ]
public string login(string user_phone,string password)
{
Message message = new();
try
{
var user_info = myContext.Users
.Where(user => user.UserPhone == user_phone && user.UserPassword == password)
.Select(user => new
{
user.UserId,
user.UserName,
}).First();
message.Add("userid", user_info.UserId);
message.Add("username", user_info.UserName);
message.Add("errorCode", 200);
}
catch(Exception error)
{
Console.WriteLine(error.ToString());
}
return message.ReturnJson();
}