1、需求分析
高校成绩管理系统是一个记录和管理学生成绩的系统,该系统可以使学生、教师和管理员进行查询、更新、插入、删除各项信息操作。高校成绩管理系统使得学校、老师对学生信息的管理更加简单,更加高效,在提供便捷的同时也使成本得以降低。
使用计算机对成绩信息的管理,具有手工管理所无法比拟的优点:信息存储及时,检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。这些优点能够极大地提高学生成绩管理的效率,也是高校成绩正规化管理的重要途径。
应用环境:SQL Server 2008 R2 Management Studio、Visual Studio 2019
根据实际工作需要,提出了以下数据和业务处理需求:
1.1小组分工
小组完成一个高校成绩管理系统,本人主要做学生的退补选课,选课结果的增删改,并且完成了登陆界面,输入账号自动识别相应用户的身份,转到不同的界面,以及相应的修改密码操作。
1.2 数据需求描述
图1-1 初级数据流图
图1-2 系统功能模块图
1.3 系统功能需求
- 学生:
-
课程的退补选
-
学生查询可选课程
-
进行选课
-
对所选课程进行补选、退选
-
查询信息
-
学生成绩查询,得到个人每学期成绩单
-
学生课表查询,可打印出每学期课表
-
学生选课结果查询
-
学生个人信息查询
-
登录密码修改
- 教师:
-
教师教学班成绩录入
-
学生名册浏览
-
成绩录入
-
成绩提交
-
成绩分析
-
打印成绩单
-
登录密码修改
- 管理员:
-
对教学班的增删改查
-
新增教学班
-
对已结课的教学班进行删除
-
对教学班中的数据进行修改
-
对教学班的信息进行查询
-
登录密码修改
1.4 其他性能需求
-
对于并发用户数的需求,可供多个学生或老师同时使用此系统。
-
在用户进行输入修改时,可以进行检查并产生提示。
-
响应时间应该尽可能的小。
-
安全性需求高。
-
2、概念结构设计
2.1 局部E-R图
图2-1 学生实体及其属性图
图2-2 课程实体及其属性图
图2-3 教师实体及其属性图
图2-4 教学班实体及其属性图
图2-5 教室资源实体及其属性图
图2-6班级实体及其属性图
图2-7联系产生的实体及其属性图
2.2 优化全局E-R图
图2-8 优化全局E-R图
3、逻辑结构设计
3.1 关系模式设计
实体型的关系模式转换:
Login登录表(用户名,密码)
student学生表(学号,学生姓名,性别,出生日期,生源所在地,已修学分,联系方式
,班级号)
teacher教师表(教师号,教师姓名,性别,出生日期,职称,联系方式,学院编号)
college学院表(学院编号,学院名称)
course课程表(课程号,课程名称,学时,学分,开设学期,考察方式,课程类别,学院编号)
class教学班表(教学班号,学年,学期,上课时间,课程号,教师号,教室编号,校区,楼号)
grade班级表(班级号,专业名称,学年,学院编号)
classroom教室资源表(教室编号,校区,楼号,场地类别,座位数)
report选课表(学号,教学班号,学年,平时成绩,期末成绩,总评,备注)
report2选课表(编号,学号,教学班号,学年,平时成绩,期末成绩,总评,备注)
3.2 数据类型定义
- login登录表
表3-1
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
name | char | 12 | 主键,唯一,非空 | 用户名 |
psw | char | 12 | 密码 |
- student学生表
表3-2
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
Sno | char | 12 | 主键,唯一,非空 | 学号 |
Sname | char | 15 | 学生姓名 | |
Ssex | char | 2 | 性别 | |
Sborn | char | 10 | 出生日期 | |
Saddress | char | 15 | 生源地 | |
Scredit | int | 已修学分 | ||
Stel | char | 11 | 联系方式 | |
Gno | char | 12 | 外键 | 班级号 |
3、teacher教室表
表3-3
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
Tno | char | 12 | 主键,唯一,非空 | 教师号 |
Tname | char | 15 | 教师姓名 | |
Tsex | char | 2 | 性别 | |
Tbirth | char | 10 | 出生日期 | |
Tpost | char | 15 | 职称 | |
Tcall | char | 11 | 联系方式 | |
Cnol | char | 12 | 外键 | 学院编号 |
4、course课程表
表3-4
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
Cono | char | 12 | 主键,唯一,非空 | 课程号 |
Coname | char | 15 | 课程名称 | |
Coperiod | int | 学时 | ||
Cocredit | int | 学分 | ||
Coterm | int | 开设学期 | ||
Coway | char | 5 | 考查方式 | |
CoType | char | 20 | 课程类别 | |
Cno | char | 12 | 外键 | 学院编号 |
5、report2选课表
表3-5
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
REno | char | 20 | 主键、唯一、非空 | 编号 |
Sno | char | 12 | 外键 | 学号 |
Rusual | int | 平时成绩 | ||
Rtest | int | 期末成绩 | ||
Rfinal | int | 总评 | ||
Rremark | char | 5 | 备注 | |
Clno | char | 20 | 外键 | 教学班号 |
Clyear | char | 12 | 外键 | 学年 |
6、college学院表
表3-6
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
name | char | 12 | 主键,唯一,非空 | 用户名 |
psw | char | 12 | 密码 |
7、grade班级表
表3-7
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
Gno | char | 12 | 主键、唯一、非空 | 班级编号 |
Mname | char | 15 | 专业名称 | |
Year | int | 年级 | ||
Cno | char | 12 | 外键 | 学院编号 |
8、classroom教室资源表
表3-8
字段名 | 数据类型 | 长度 | 完整性约束 | 描述 |
---|---|---|---|---|
Rno | char | 12 | 主键、唯一、非空 | 教室编号 |
Area | char | 5 | 主键、唯一、非空 | 校区 |
Building | char | 12 | 主键、唯一、非空 | 楼号 |
Type | char | 12 | 场地类别 | |
Seat | int | 座位数 |
3.3 关系模式的优化
为查询操作更加的方便快速高效,创建一下视图:
- 视图Scores: 方便查询学生的成绩
表3-9
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
Clno | char | 12 | 是 |
Clyear | char | 12 | 是 |
Mname | char | 15 | 否 |
Sno | char | 12 | 否 |
Sname | char | 15 | 否 |
Rusual | int | 否 | |
Rtest | int | 否 | |
Rfinal | int | 否 | |
Rremark | char | 2 | 否 |
2、视图C_Cl
表3-10
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
Cono | char | 12 | 是 |
Coname | char | 15 | 否 |
Clno | char | 12 | 否 |
Clyear | char | 12 | 否 |
Tno | char | 12 | 否 |
3、视图CJ: 查询成绩用的视图
表3-11
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
Sno | char | 12 | 是 |
Sname | char | 15 | 否 |
Clyear | char | 12 | 否 |
Clterm | int | 否 | |
Coname | char | 15 | 否 |
Rusual | int | 否 | |
Rtest | int | 否 | |
Rfinal | int | 否 | |
Rremark | char | 2 | 否 |
4、视图KB:查询课表
表3-12
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
Sno | char | 12 | 是 |
Clyear | char | 12 | 是 |
Clterm | int | 否 | |
Coname | char | 15 | 否 |
Clnumber | char | 12 | 否 |
Tname | char | 10 | 否 |
Area | char | 5 | 否 |
Building | char | 12 | 否 |
Rno | char | 12 | 否 |
Coway | char | 5 | 否 |
Coperiod | int | 否 | |
Cocredit | int | 否 | |
CoType | char | 20 | 否 |
5.视图XK:查询课表
表3-13
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
Clyear | char | 12 | 是 |
Clterm | int | 否 | |
Cono | char | 12 | 否 |
Coname | char | 15 | 否 |
Cname | char | 15 | 否 |
Cocredit | int | 否 | |
CoType | char | 20 | 否 |
Sno | char | 12 | 否 |
Sname | char | 15 | 否 |
Tno | char | 12 | 否 |
Tname | char | 10 | 否 |
Clnumber | char | 12 | 否 |
Coperiod | int | 否 | |
Area | char | 5 | 否 |
Building | char | 12 | 否 |
Rno | char | 12 | 否 |
Ssex | char | 2 | 否 |
Mname | char | 15 | 否 |
Stel | char | 11 | 否 |
6、视图RR:选课结果
表3-14
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
序号 | char | 20 | 是 |
课程 | char | 15 | 否 |
教师 | char | 10 | 否 |
上课时间 | char | 12 | 否 |
上课地点 | char | 24 | 否 |
学分 | int | 否 | |
课程类型 | char | 20 | 否 |
学号 | char | 12 | 否 |
7、视图S:查询个人信息
表3-14
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
Sno | char | 12 | 是 |
Sname | char | 15 | 否 |
SC | char | 15 | 否 |
SG | char | 15 | 否 |
B | char | 10 | 否 |
S | char | 2 | 否 |
T | char | 11 | 否 |
A | char | 15 | 否 |
8、视图RC:
表3-15
字段 | 数据类型 | 字段大小 | 必填字段 |
---|---|---|---|
学院 | char | 15 | 是 |
教学班号 | char | 15 | 否 |
教学班 | char | 15 | 否 |
教师 | char | 10 | 否 |
课程类型 | char | 20 | 否 |
上课时间 | char | 12 | 否 |
上课地点 | char | 24 | 否 |
学分 | int | 否 | |
开课学年 | char | 12 | 否 |
开课学期 | int | 否 | |
学时 | int | 否 |
4、物理结构设计
4.1 聚簇设计
聚簇索引:学生学号Sno、教师编号Tno、登陆用户名name、教学班号Clno、班级编号Gno、学院编号Cno、课程号Cono
4.2 索引设计
聚簇索引:学生姓名Sname、教师联系方式Tcall
唯一索引:无
5.数据库实施
5.1基本表建立
5.1.1 student学生表
1.建表语句
create table student(
Sno char(12) primary key,
Sname char(15),
Ssex char(2),
Sborn char(10),
Saddress char(15),
Scredit int,
Stel char(11),
Gno char (12),
constraint S_Gno foreign key (Gno) references grade);
5.1.2 college学院表
1.建表语句
create table college(
Cno char(12) primary key,
Cname char(15));
5.1.3 grade班级表
1.建表语句
create table grade(
Gno char(12) primary key,
Mname char(15),
Year int,
Cno char(12),
constraint G_Cno foreign key(Cno) references college);
5.1.4 teacher教师表
1.建表语句
create table teacher(
Tno char(12) primary key,
Tname char(10),
Tsex char(2),
Tbirth char(10),
Tpost char(15),
Tcall char(11),
Cno char(12),
constraint T_Cno foreign key(Cno) references college
);
5.1.5 course课程表
1.建表语句
create table course(
Cono char(12) primary key,
Coname char(15),
Coperiod int,
Cocredit int,
Coterm int,
Coway char(5),
CoType char(5),
Cno char(12),
constraint Co_Cno foreign key(Cno) references college);
5.1.6 class教学班
1.建表语句
create table class(
Clno char(12) primary key,
Clyear char(12) primary key,
Clterm int,
Clnumber char(12),
Cono char(12),
Tno char(12),
Rno char(12),
Area char(5),
Building char(12),
constraint Cl_Building foreign key(Building) references classroom,
constraint Cl_Area foreign key(Area) references classroom,
constraint Cl_Rno foreign key(Rno) references classroom,
constraint Cl_Cono foreign key(Cono) references course,
constraint Cl_Tno foreign key(Tno) references teacher);
5.1.7 report选课表1
1.建表语句
create table report(
Sno char(12),
Clno char(12),
Clyear char(12),
Rusual int,
Rtest int,
Rfinal int,
Rremark char(2),
constraint R_Sno foreign key(Sno) references student,
constraint R_Clno foreign key(Clno) references class
constraint R_Clyear foreign key(Clyear) references class);
5.1.8 report选课表2
1.建表语句
create table report(
REno char(20) primary key,
Sno char(12),
Rusual int,
Rtest int,
Rfinal int,
Rremark char(2),
Clno char(12),
Clyear char(12),
constraint R_Sno foreign key(Sno) references student,
constraint R_Clno foreign key(Clno) references class);
5.1.9 classroom教室资源表
1.建表语句
create table classroom(
Rno char(12),
Area char(5),
Building char(12),
Type char(12),
Seat int(3),
primary key(Rno,Area,Building)
);
5.2 视图的建立
5.2.1可选课程视图
create view
RC(学院,教学班号,教学班,教师,课程类型,上课时间,上课地点,学分,开课学年,开课学期,学时)
as(
select
Cname,Clno,Coname,Tname,CoType,Clnumber,Building+Rno,Cocredit,Clyear,Clterm,Coperiod
from college,class,course,teacher
where college.Cno=course.Cno
and class.Cono=course.Cono
and class.Tno=teacher.Tno)
WITH CHECK OPTION
5.2.2选课结果视图
create view RR(序号,课程,教师,上课时间,上课地点,学分,课程类型,学号)
as(
select REno,Coname,Tname,Clnumber,Building+Rno,Cocredit,CoType,Sno
from course,class,teacher,report2
where class.Tno=teacher.Tno
and class.Clno=report2.Clno
and class.Cono=course.Cono
)
with check option
5.2.2个人信息视图
create view S(Sno,Sname,SC,SG,B,S,T,A)
as(
select Sno,Sname,Cname,Mname,Sborn,Ssex,Stel,Saddress
from student,grade,college
where student.Gno=grade.Gno
and grade.Cno=college.Cno)
with check option
5.3 索引的建立
5.3.1建立学生姓名一索引
Create unique index Sname on student(Sname);
5.3.2 建立教师电话唯一索引
Create unique index Tcall on teacher(Tcall);
6、应用系统开发与试运行
6.1 开发平台和开发环境介绍。
开发平台:SQL Server 2018 Management Studio、Visual Studio 2019
开发环境:利用c#语言和数据库sql语言
前台界面与后台数据库连接说明,代码实现。
C#数据库编程:其中有几个重要的数据库访问对象:DataSet对象、Connection对象、Command对象、DataReader对象、DataAdapter对象,用以上几个对象实现前台界面与后台数据库连接。
与数据库连接类SqlConnect:
namespace database
{
class SqlConnect
{
public SqlConnection conn = null;
public SqlConnect()//构造函数,连接数据库
{
if (conn == null)
{
conn = new SqlConnection("Data
Source=(local);database=University_CourseSystem_Mis;uid=admin;password=123456;");
if (conn.State == ConnectionState.Closed) conn.Open();
}
}
public void CloseConnect()//关闭连接函数
{
if (conn.State == ConnectionState.Open) conn.Close();
}
public SqlDataReader aa(string sql)//判断是否有该元组
{
if (conn.State == ConnectionState.Closed) conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
SqlDataReader sdr;
sdr = cmd.ExecuteReader();
return sdr;
}
public DataSet Getds(string sql)//获取DATESET类型的数据库查询结果
{
if (conn.State == ConnectionState.Closed) conn.Open();
DataSet ds = new DataSet();//表集合
SqlDataAdapter da = new SqlDataAdapter(sql, conn);//查询
da.Fill(ds);//填充
conn.Close();//关闭连接
return ds;//返回结果
}
public int OperateData(string sql)//修改数据库结果
{
if (conn.State == ConnectionState.Closed) conn.Open();
SqlCommand sqlcom = new SqlCommand();
sqlcom.CommandText = sql;//文本
sqlcom.CommandType = CommandType.Text;//类型
sqlcom.Connection = conn;//连接
int x = sqlcom.ExecuteNonQuery();//执行
conn.Close();//关闭
return x;//返回一个影响行数
}
public void Tos(string s){//将查询结果的某个具体值绑定到公共参数上
SqlCommand sc = conn.CreateCommand();
sc.CommandText = s;
SqlDataReader r = sc.ExecuteReader();
r.Read();
pub.Sname = Convert.ToString(r["Sname"]);
pub.SC= Convert.ToString(r["SC"]);
pub.SG = Convert.ToString(r["SG"]);
pub.B= Convert.ToString(r["B"]);
pub.S = Convert.ToString(r["S"]);
pub.T = Convert.ToString(r["T"]);
pub.A = Convert.ToString(r["A"]);
}
public DataSet BindDataGridView(DataGridView dgv, string sql)//数据视图
{
if (conn.State == ConnectionState.Closed) conn.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
da.Fill(ds);
dgv.DataSource = ds.Tables[0];
return ds;
}
}
}
6.3 系统各功能设计和运行界面截图。
登录界面:分别学生、教师、管理员三种用户登录(自动识别不同身份的用户名,登陆进不同的主界面)
图6-1登录界面
6.3.1学生功能:
1、学生登录
图6-2 学生登录界面
2、学生主界面
图6-3 学生登陆的主界面
3、查询个人信息
图6-4 学生查询个人信息
4、学生选课界面
图6-5 学生选课界面
图6-6 根据可选课程进行筛选,以及验证数据库
图6-7 文本框输入模糊查询结果
图6-8 选课
图6-9 不会重复选同一节课
图6-10 查看已选课程,并验证数据库
图6-11 退选
图6-12 验证是否退课成功
图6-13 同一时间段的两节课禁止选
5、修改密码
图6-14 修改密码需要两次输入相同密码
图6-15 密码修改成功
6.3.2教师界面测试:
图6-16 教师账号登陆
图6-17 教师账号登陆
6.3.3管理员界面测试:
图6-18 管理员账号登陆
图6-19 管理员账号登陆
7、实验总结
7.1 遇到的问题和解决的办法
a)前期没有充分的思考用户需求导致思路不清晰
一开始和队友大概的分析了用户需求,并没有十分详细的了解并且系统的分析,所以在建基本表以及写嵌入式语言、写前端时需要反复的改基本表的属性以及一些条件约束等等。所以在以后的大实验过程中,前期的讨论与充分的分析十分重要,应当重视。
b)在vs上写嵌入式sql语句时常见错误
在vs上写sql语句时,需要用到双引号。而一些属性需要单引号才可以使用。所以在执行系统时,会遇到不能进行此操作这种提示。遇到这类的问题,我首先会排查是否是sql语句写的不正确,我会将这条语句复制到数据库进行执行,如果在数据库中执行成功,则大多是单引号双引号的问题,再进行排查即可。
c)如何获取数据库内容
窗体中有组件可以放数据库数据,但是不知道如何在选中行直接获取某一列的值以及或者是DateSet中的某一个单元格的值,为了解决这个问题,查了比较多的资料,才成功解决了该问题。
- 第一种是用SqlCommand来绑定相应的值,并显示在固定位置:
public void Tos(string s){//将查询结果的某个具体值绑定到公共参数上
SqlCommand sc = conn.CreateCommand();
sc.CommandText = s;
SqlDataReader r = sc.ExecuteReader();
r.Read();
pub.Sname = Convert.ToString(r["Sname"]);
pub.SC= Convert.ToString(r["SC"]);
pub.SG = Convert.ToString(r["SG"]);
pub.B= Convert.ToString(r["B"]);
pub.S = Convert.ToString(r["S"]);
pub.T = Convert.ToString(r["T"]);
pub.A = Convert.ToString(r["A"]);
}
- 第二种获取数据库视图中某一个单元的具体值:
private void dataGView_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
int index = dataGView.CurrentRow.Index;
pub.Rcl = dataGView.Rows[index].Cells[1].Value.ToString();//教学班编号
//MessageBox.Show(pub.Rcl);
pub.Ry = dataGView.Rows[index].Cells[8].Value.ToString();//学期
pub.Rn = dataGView.Rows[index].Cells[5].Value.ToString();//节数
}
- 第三种,获取dataset中某行某列的值,还可以判断查询结果是否为空
sql = "select \* from RR where 上课时间='" + pub.Rn + "'";//是否有时间冲突
ds = con.Getds(sql);
time = ds.Tables[0].Rows[0]["序号"].ToString();
if (ds == null \|\| ds.Tables[0].Rows.Count == 0)//是否查询结果为空
d) 数据库绑定下拉框
可以将数据库中的属性值绑定到下拉框中,但是如何再绑定后的下拉框中再加一个项,增加一个全部项,增加查询条件:
protected void cmbTBind()
{
try
{
cmbT.DropDownStyle = ComboBoxStyle.DropDownList;
cmbT.Items.Clear();
ds = con.Getds("select distinct 课程类型 from RC");
DataRow dt = ds.Tables[0].NewRow();//增加项
dt["课程类型"] = "全部";
ds.Tables[0].Rows.InsertAt(dt, 0);
cmbT.DisplayMember = "课程类型";
cmbT.DataSource = ds.Tables[0];
cmbT.SelectedIndex = 0;
//cmbT.Items.Insert(0, "全部");
}
catch (Exception)
{
MessageBox.Show("不能作该操作!", "提示", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
7.2 系统设计的不足
- 并发操作
在这次的构建系统中,我没有思考到并发操作这一问题。高校学生管理系统是一个多用户会同时在线的系统,如何保证在并发操作时,实现数据的安全性、正确性是十分重要的。所以我认为并发操作不可缺少。
- 基本表之间的联系以及属性的约束
在建表的过程中,通过不断的讨论和设计,已经建立了一个较为完整的系统结构,但是在设计实际过程中就发现有很多实际问题,比如选课的时候,不可能选同一节课,同一时间也不可能选两节课,这就需要很多的唯一索引,但是在建表的时候并没有考虑到,所以只能用代码来尽量优化。
7.3 进一步改进思路
- 安全性
学生以及老师的登录用户名和密码需要进行保护,最重要的是管理员的用户名与密码。可以通过动态定时改变密码,也可以创建一个触发器,设置当输入密码错误,就自动更换一个密码,并传送到管理员的手机中等等的方法。
- 用户登录问题
在登录界面上,可以设置一个注册界面,并且当设置成功时,将学号或者用户名自动添加到学生信息表和教师信息表中,同时将用户名与密码添加到login表中。
- 界面的美化
c#写的前端界面不够简洁好看,可以尝试使用javaweb的方法写html和jsp文件,实现前端界面的美化以及一些前端的表示逻辑。
- 管理员和教师的功能实现
我的数据库部分只需要实现学生的选课功能,但是在界面设计的时候也放了一些查询的功能,以及管理员和教师登陆后的主界面窗口,时间足够的话,可以将小组实验尝试合并,形成一个完整的数据库管理系统,使系统的功能更加的丰富饱满,提高系统的实用性。
7.4 实验体会
在这次短学期中,利用短短4天的时间要完成学生选课模块的功能,写了,虽然只需要完成这一个功能,但是为了提高实用性,不断地优化和改进选课模块的各个细节以及现实问题,做了较多的考虑和修改。
而且在实际执行sql语言后,发现前期与队友分析的一些用户需求不够全面完整,所以反反复复修改了好几次基本表。所有的sql语言其实不是特别的难,需要的是编写代码的时候的细心。
再解决完一些基础问题、实现基础功能之后,最大的问题是如何优化该功能,为了更加的方便操作贴近生活,增加可选功能,一个一个细节的慢慢优化,可能编写基础框架只用了优化的1/4时间,并且再改进过程中查询了大量的资料,了解了很多相关知识,才能够最后实现预想的成果,比如选中某一行数据,在点击按钮就可以添加选课,而不需要再次筛选条件来插入选课记录。在查询现有的可选课程时,参考了正方系统的选课界面,添加四个条件选项,并且还可以通过文本搜索来实现查询,尽量将系统做到人性化。
源码链接:https://github.com/bumor/database.git