七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置
前言
在上一章节我们在后端框架中引入 SQLite-net
ORM 并封装常用方法(SQLiteHelper),今天我们的任务是设计好班级管理相关的表、完善后端班级管理相关接口并对Swagger自定义配置。
七天.NET 8 操作 SQLite 入门到实战详细教程
- 第一天 SQLite 简介
- 第二天 在 Windows 上配置 SQLite 环境
- 第三天 SQLite 快速入门
- 第四天 EasySQLite 前后端项目框架搭建
- 第五天引入 SQLite-net ORM 并封装常用方法
EasySQLite 项目源码地址
班级管理相关的表设计
班级表的字段可以包括:
- 班级ID(ClassID):用于唯一标识每个班级[主键自增]。
- 班级名称(ClassName):班级的名称。
- 创建时间(CreateTime):班级创建的时间。
班级学生表的字段可以包括:
- 学生ID(StudentID):用于唯一标识每个学生[主键自增]。
- 班级ID(ClassID):所属班级的ID,与班级表中的班级ID相关联。
- 姓名(Name):学生的姓名。
- 年龄(Age):学生的年龄。
- 性别(Gender):学生的性别。
班级管理相关的表对应模型
SchoolClass
public class SchoolClass
{
/// <summary>
/// 班级ID [主键,自动递增]
/// </summary>
[PrimaryKey, AutoIncrement]
public int ClassID { get; set; }
/// <summary>
/// 班级名称
/// </summary>
public string ClassName { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
}
Student
public class Student
{
/// <summary>
/// 学生ID [主键,自动递增]
/// </summary>
[PrimaryKey, AutoIncrement]
public int StudentID { get; set; }
/// <summary>
/// 班级ID
/// </summary>
public int ClassID { get; set; }
/// <summary>
/// 学生姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 学生年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 学生性别
/// </summary>
public string Gender { get; set; }
}
接口统一的响应模型
为了实现统一的响应模型,这里创建一个名为 ApiResponse的泛型类。
public class ApiResponse<T>
{
/// <summary>
/// 是否成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 响应消息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 返回的数据
/// </summary>
public T Data { get; set; }
}
学校班级管理接口代码
/// <summary>
/// 学校班级管理
/// </summary>
[ApiController]
[Route("[controller]")]
public class SchoolClassController : ControllerBase
{
private readonly SQLiteAsyncHelper<SchoolClass> _schoolClassHelper;
/// <summary>
/// 依赖注入
/// </summary>
/// <param name="schoolClassHelper">schoolClassHelper</param>
public SchoolClassController(SQLiteAsyncHelper<SchoolClass> schoolClassHelper)
{
_schoolClassHelper = schoolClassHelper;
}
/// <summary>
/// 班级创建
/// </summary>
/// <param name="schoolClass">创建班级信息</param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResponse<int>> CreateClass([FromBody] SchoolClass schoolClass)
{
try
{
int insertNumbers = await _schoolClassHelper.InsertAsync(schoolClass);
if (insertNumbers > 0)
{
return new ApiResponse<int>
{
Success = true,
Message = "创建班级成功"
};
}
else
{
return new ApiResponse<int>
{
Success = false,
Message = "创建班级失败"
};
}
}
catch (Exception ex)
{
return new ApiResponse<int>
{
Success = false,
Message = ex.Message
};
}
}
/// <summary>
/// 获取所有班级信息
/// </summary>
[HttpGet]
public async Task<ApiResponse<List<SchoolClass>>> GetClasses()
{
try
{
var classes = await _schoolClassHelper.QueryAllAsync().ConfigureAwait(false);
return new ApiResponse<List<SchoolClass>>
{
Success = true,
Data = classes
};
}
catch (Exception ex)
{
return new ApiResponse<List<SchoolClass>>
{
Success = false,
Message = ex.Message
};
}
}
/// <summary>
/// 根据班级ID获取班级信息
/// </summary>
/// <param name="classId">班级ID</param>
/// <returns></returns>
[HttpGet("{classId}")]
public async Task<ApiResponse<SchoolClass>> GetClass(int classId)
{
try
{
var schoolClass = await _schoolClassHelper.QuerySingleAsync(c => c.ClassID == classId).ConfigureAwait(false);
if (schoolClass != null)
{
return new ApiResponse<SchoolClass>
{
Success = true,
Data = schoolClass
};
}
else
{
return new ApiResponse<SchoolClass>
{
Success = false,
Message = "班级不存在"
};
}
}
catch (Exception ex)
{
return new ApiResponse<SchoolClass>
{
Success = false,
Message = ex.Message
};
}
}
/// <summary>
/// 更新班级信息
/// </summary>
/// <param name="classId">班级ID</param>
/// <param name="updatedClass">更新的班级信息</param>
/// <returns></returns>
[HttpPut("{classId}")]
public async Task<ApiResponse<int>> UpdateClass(int classId, [FromBody] SchoolClass updatedClass)
{
try
{
var existingClass = await _schoolClassHelper.QuerySingleAsync(c => c.ClassID == classId).ConfigureAwait(false);
if (existingClass != null)
{
existingClass.ClassName = updatedClass.ClassName;
var updateResult = await _schoolClassHelper.UpdateAsync(existingClass).ConfigureAwait(false);
if (updateResult > 0)
{
return new ApiResponse<int>
{
Success = true,
Message = "班级信息更新成功"
};
}
else
{
return new ApiResponse<int>
{
Success = false,
Message = "班级信息更新失败"
};
}
}
else
{
return new ApiResponse<int>
{
Success = false,
Message = "班级不存在"
};
}
}
catch (Exception ex)
{
return new ApiResponse<int>
{
Success = false,
Message = ex.Message
};
}
}
/// <summary>
/// 班级删除
/// </summary>
/// <param name="classId">班级ID</param>
/// <returns></returns>
[HttpDelete("{classId}")]
public async Task<ApiResponse<int>> DeleteClass(int classId)
{
try
{
var deleteResult = await _schoolClassHelper.DeleteAsync(classId).ConfigureAwait(false);
if (deleteResult > 0)
{
return new ApiResponse<int>
{
Success = true,
Message = "班级删除成功"
};
}
else
{
return new ApiResponse<int>
{
Success = true,
Message = "班级删除失败"
};
}
}
catch (Exception ex)
{
return new ApiResponse<int>
{
Success = false,
Message = ex.Message
};
}
}
}
学生管理接口代码
/// <summary>
/// 学生管理
/// </summary>
[ApiController]
[Route("[controller]")]
public class StudentController : ControllerBase
{
private readonly SQLiteAsyncHelper<Student> _studentHelper;
/// <summary>
/// 依赖注入
/// </summary>
/// <param name="studentHelper">studentHelper</param>
public StudentController(SQLiteAsyncHelper<Student> studentHelper)
{
_studentHelper = studentHelper;
}
/// <summary>
/// 创建新的学生记录
/// </summary>
/// <param name="student">添加的学生信息</param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResponse<int>> CreateAsync([FromBody] Student student)
{
var response = new ApiResponse<int>();
try
{
var insertNumbers = await _studentHelper.InsertAsync(student).ConfigureAwait(false);
if (insertNumbers > 0)
{
response.Success = true;
response.Message = "添加成功";
}
else
{
response.Success = false;
response.Message = "插入失败";
}
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
}
return response;
}
/// <summary>
/// 查询所有学生记录
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<ApiResponse<List<Student>>> GetAllAsync()
{
var response = new ApiResponse<List<Student>>();
try
{
var students = await _studentHelper.QueryAllAsync().ConfigureAwait(false);
response.Success = true;
response.Data = students;
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
}
return response;
}
/// <summary>
/// 根据学生ID查询学生信息
/// </summary>
/// <param name="studentID">学生ID</param>
/// <returns></returns>
[HttpGet("{studentID}")]
public async Task<ApiResponse<Student>> GetByIdAsync(int studentID)
{
var response = new ApiResponse<Student>();
try
{
var student = await _studentHelper.QuerySingleAsync(x => x.StudentID == studentID).ConfigureAwait(false);
if (student != null)
{
response.Success = true;
response.Data = student;
}
else
{
response.Success = false;
response.Message = "未找到学生信息";
}
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
}
return response;
}
/// <summary>
/// 更新学生记录
/// </summary>
/// <param name="studentID">学生ID</param>
/// <param name="editstudent">更新的学生信息</param>
/// <returns></returns>
[HttpPut("{studentID}")]
public async Task<ApiResponse<int>> UpdateAsync(int studentID, [FromBody] Student editstudent)
{
var response = new ApiResponse<int>();
try
{
var student = await _studentHelper.QuerySingleAsync(x => x.StudentID == studentID).ConfigureAwait(false);
if (student != null)
{
student.Age = editstudent.Age;
student.Name = editstudent.Name;
student.Gender = editstudent.Gender;
student.ClassID = editstudent.ClassID;
int updateResult = await _studentHelper.UpdateAsync(student).ConfigureAwait(false);
if (updateResult > 0)
{
response.Success = true;
response.Message = "学生信息更新成功";
}
else
{
response.Success = false;
response.Message = "学生信息更新失败";
}
}
else
{
response.Success = false;
response.Message = "未找到学生信息";
}
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
}
return response;
}
/// <summary>
/// 删除学生记录
/// </summary>
/// <param name="studentID">学生ID</param>
/// <returns></returns>
[HttpDelete("{studentID}")]
public async Task<ApiResponse<int>> DeleteAsync(int studentID)
{
var response = new ApiResponse<int>();
try
{
int deleteResult = await _studentHelper.DeleteAsync(studentID).ConfigureAwait(false);
if (deleteResult > 0)
{
response.Success = true;
response.Message = "删除成功";
}
else
{
response.Success = false;
response.Message = "未找到学生信息";
}
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
}
return response;
}
}
对应服务注册
在Program.cs
类中:
// 注册服务
builder.Services.AddScoped<SQLiteAsyncHelper<SchoolClass>>();
builder.Services.AddScoped<SQLiteAsyncHelper<Student>>();
Swagger自定义和扩展
Swagger 提供了为对象模型进行归档和自定义 UI 以匹配你的主题的选项。
传递给 AddSwaggerGen 方法的配置操作会添加诸如作者、许可证和说明的信息。在 Program.cs
中添加如下Swagger自定义配置:
// 添加Swagger服务
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "EasySQLite API",
Version = "V1",
Description = ".NET 8操作SQLite入门到实战",
Contact = new OpenApiContact
{
Name = "GitHub源码地址",
Url = new Uri("https://github.com/YSGStudyHards/EasySQLite")
}
});
// 获取xml文件名
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
// 获取xml文件路径
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
// 添加控制器层注释,true表示显示控制器注释
options.IncludeXmlComments(xmlPath, true);
// 对action的名称进行排序,如果有多个,就可以看见效果了
options.OrderActionsBy(o => o.RelativePath);
});
项目右键,选择属性,找到生成下面的输出选中生成包含API文档的文件,如下图所示:
注意:关于XML文档文件路径是需要你先勾选上面生成包含API文档的文件的时候运行项目才会生成该项目的XML文档,然后可以把生成的XML文档放到你想要放到的位置。
配置完成查看Swagger API运行效果:
Swagger API调用效果展示
Navicat查看SQLite表数据
注意本文我们的数据库和表都是由代码自动创建生成的,也就是在SQLiteAsyncHelper里面。
创建成功后的数据库:
Navicat查看数据库表数据
DotNetGuide技术社区交流群
- DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目推荐、招聘资讯和解决问题的平台。
- 在这个社区中,开发者们可以分享自己的技术文章、项目经验、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
- 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台,为广大.NET开发者带来更多的价值和成长机会。
七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置的更多相关文章
- Ionic 入门与实战之第三章:Ionic 项目结构以及路由配置
原文发表于我的技术博客 本文是「Ionic 入门与实战」系列连载的第三章,主要对 Ionic 的项目结构作了介绍,并讲解了Ionic 中的路由概念以及相关配置. 原文发表于我的技术博客 1. Ioni ...
- Eclipse操作Servlet入门案例,创建类无法实现Servlet接口和继承HttpServlet类
问题描述: 从昨天下午到今天中午,这个问题被缠绕了良久.百度了很多,却都没有一言命中要害. 首先,还是基于对Web的理解. 第一:建立的是Dynamic Web Project: 第二:然后需要 ...
- Spring Boot从入门到实战:集成AOPLog来记录接口访问日志
日志是一个Web项目中必不可少的部分,借助它我们可以做许多事情,比如问题排查.访问统计.监控告警等.一般通过引入slf4j的一些实现框架来做日志功能,如log4j,logback,log4j2,其性能 ...
- docker-9 supervisord 参考docker从入门到实战
参考docker从入门到实战 使用 Supervisor 来管理进程 Docker 容器在启动的时候开启单个进程,比如,一个 ssh 或者 apache 的 daemon 服务.但我们经常需要在一个机 ...
- C#操作Sqlite快速入门及相关工具收集
Sqlite不需要安装即可使用.Sqlite是不是那个System.Data.SQLite.DLL临时创建了数据库引擎? 1.新建一个WinForm项目,引用System.Data.SQLite.DL ...
- 【图像处理】OpenCV+Python图像处理入门教程(七)图像形态学操作
图像形态学主要从图像内提取分量信息,该分量信息通常对表达图像的特征具有重要意义.例如,在车牌号码识别中,能够使用形态学计算其重要特征信息,在进行识别时,只需对这些特征信息运算即可.图像形态学在目标视觉 ...
- SQLite入门与分析(二)---设计与概念(续)
SQLite入门与分析(二)---设计与概念(续) 写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...
- SQLite 入门教程(三)好多约束 Constraints(转)
转于: SQLite 入门教程(三)好多约束 Constraints 一.约束 Constraints 在上一篇随笔的结尾,我提到了约束, 但是在那里我把它翻译成了限定符,不太准确,这里先更正一下,应 ...
- SQLite 入门教程(四)增删改查,有讲究 (转)
转于: SQLite 入门教程(四)增删改查,有讲究 一.插入数据 INSERT INTO 表(列...) VALUES(值...) 根据前面几篇的内容,我们可以很轻送的创建一个数据表,并向其中插入一 ...
- C#操作SQLite方法实例详解
用 C# 访问 SQLite 入门(1) CC++C#SQLiteFirefox 用 C# 访问 SQLite 入门 (1) SQLite 在 VS C# 环境下的开发,网上已经有很多教程.我也是从 ...
随机推荐
- WPF中非递归(无后台代码)动态实现TreeView
在UI界面中,树形视图是比较常用的表示层级结构的方式,WPF中提供了TreeView控件.对于TreeView控件的基本使用已经有很多文章.大都是介绍如何在XAML中使用硬编码的固定信息填充Treev ...
- [ABC140E] Second Sum
2023-02-13 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 双向链表 解题思路 \(1.\) 当我们用从小到大的顺序来求解时,把原来求 ...
- 2023-08-22:请用go语言编写。给定一个长度为N的正数数组,还有一个正数K, 返回有多少子序列的最大公约数为K。 结果可能很大,对1000000007取模。 1 <= N <= 10^5, 1
2023-08-22:请用go语言编写.给定一个长度为N的正数数组,还有一个正数K, 返回有多少子序列的最大公约数为K. 结果可能很大,对1000000007取模. 1 <= N <= 1 ...
- 万字长文硬核AQS源码分析
阅读本文前,需要储备的知识点如下,点击链接直接跳转. java线程详解 Java不能操作内存?Unsafe了解一下 一文读懂LockSupport AQS简介 AQS即AbstractQueuedSy ...
- 手机用户的开源福音「GitHub 热点速览」
不知道多少用安卓机的小伙伴,被开屏广告烦过.相比有些克制的 iOS 机,安卓机是个应用基本上都有开屏广告,少则 3s 多则 10s,本周获得 1k+ star 的 Android-Touch-Help ...
- tomcat配置域名绑定项目
有时候我们需要根据访问的不同域名,对应tomcat中不同的项目例如:一个网站同时做了两套,pc版和手机版.手机版对应的域名是m.we-going.com,就需要在tomcat配置文件中加入以下代码:& ...
- 【matplotlib基础】--动画
matplotlib的动画一直是一个强大但使用频率不高的功能,究其原因,一方面展示动画需要一定的媒介,没有图形和文字展示方便:二来大家更关心的是分析结果的最终图表,图表的动态展示则没有那么重要. 不过 ...
- python判断ip所属地区 python 判断ip 网段
IP地址是互联网中唯一标识一个设备的地址,有时候需要判断一个IP地址所属的地区,这就需要用到IP地址归属查询.本文将介绍Python如何通过IP地址查询所属地区并展示代码. 一. IP地址归属查询 I ...
- Docker Swarm + Harbor + Portainer 打造高可用,高伸缩,集群自动化部署,更新。
Docker Swarm是Docker官方自带的容器编排工具,Swarm,Compose,Machine合称Docker三剑客.Docker Swarm对于中小型应用来说,还是比较方便,灵活,当然K8 ...
- vue~封装一个文本框添加与删除的组件
标签组件的效果如下 组件作用 这是一个div,包含了两个文本框,后面是添加和删除按钮 添加按钮复制出新的div,除了文本框没有内容,其它都上面一样 删除按钮将当前行div删除 组件实现 <tem ...