Kotlin实现简单的学生信息管理系统
文章目录
- 一、实验内容
- 二、实验步骤
- 1、页面布局
- 2、数据库
- 3、登录活动
- 4、增删改查
- 三、运行演示
- 四、实验总结
- 五、源码下载
一、实验内容
根据Android数据存储的内容,综合应用SharedPreferences和SQLite数据库实现一个用户信息管理系统,强化对SharedPreferences的理解的使用,熟练掌握SQLite的操作。要求:
- 巩固Android应用开发工具(Eclipse或者AndroidStudio)的常规用法;
- 巩固Activity、UI控件的常规用法;
- 掌握SharedPpreferences数据存储的使用;
- 掌握SQLite数据库及SQLiteOpenHelper的使用。
二、实验步骤
1、页面布局
本次布局提倡从简原则,按照往常习惯,我肯定是创建多个Activity,然后每个Activity设置下页面,分别从主页面跳转到各个页面。既然是实验,那就从简,实现核心的思想就可以了,底层逻辑实现出来,表面内容那不是花时间设计下就行了。言归正传,主页面布局如下,没有任何亮点可言,比较常规,只给Button和TextView都设置了background。
完整的layout代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><EditTextandroid:id="@+id/et_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入学号"android:textSize="20sp"android:textColor="@color/black"android:padding="10dp"android:layout_margin="20dp"android:inputType="text"android:background="@drawable/et_selector" /><EditTextandroid:id="@+id/et_name"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入姓名"android:textSize="20sp"android:textColor="@color/black"android:padding="10dp"android:layout_margin="20dp"android:inputType="text"android:background="@drawable/et_selector" /><EditTextandroid:id="@+id/et_age"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入年龄"android:textSize="20sp"android:textColor="@color/black"android:padding="10dp"android:layout_margin="20dp"android:inputType="text"android:background="@drawable/et_selector" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_insert"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="添加"android:background="@drawable/btn_selector"android:textSize="20sp"android:layout_margin="10dp"android:textColor="@color/black"/><Buttonandroid:id="@+id/btn_delete"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="删除"android:background="@drawable/btn_selector"android:textSize="20sp"android:layout_margin="10dp"android:textColor="@color/black"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_marginBottom="20dp"><Buttonandroid:id="@+id/btn_update"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="修改"android:background="@drawable/btn_selector"android:textSize="20sp"android:layout_margin="10dp"android:textColor="@color/black"/><Buttonandroid:id="@+id/btn_query"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:text="查询"android:background="@drawable/btn_selector"android:textSize="20sp"android:layout_margin="10dp"android:textColor="@color/black"/></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="2dp"android:background="@color/black"/><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:layout_width="0dp"android:layout_weight="1"android:text="学号"android:textSize="20sp"android:gravity="center"android:layout_height="wrap_content"/><TextViewandroid:layout_width="0dp"android:layout_weight="1"android:text="姓名"android:textSize="20sp"android:gravity="center"android:layout_height="wrap_content"/><TextViewandroid:layout_width="0dp"android:layout_weight="1"android:text="年龄"android:textSize="20sp"android:gravity="center"android:layout_height="wrap_content"/></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="2dp"android:background="@color/black"/><ListViewandroid:id="@+id/lv_stu"android:layout_width="match_parent"android:layout_height="match_parent"/>
</LinearLayout>
2、数据库
考查对SQLite的熟练程度,其实就是Android提供了一个数据库帮助类,帮我们进行数据库的各种操作。我们要做的就是建库建表,写个增删改查的方法,然后剩下的事情交给系统。这里是学生表的建表语句,一切属性都能用text表示。
private val CREATE_STUDENT = "create table Student (" +"id text primary key," +"name text," +"age text)"
再看学生类,简直封装的太好了,Kotlin的魅力所在,换做Java又是属性、构造函数、get和set方法。
class Student(val id:String, val name:String, val age:String) {}
下面看数据库的增删改查操作,所有的操作都是针对数据库的Student表来的,增加、删除和修改都很简单,使用ContentValues添加键值对。查询是最关键的,使用cursor游标一行行遍历表数据,各种约束条件可以自己加,正常全查就完事了。
val dbHelper = DBHelper(context, "stu.db", 1)lateinit var db:SQLiteDatabasefun openDB() {db = dbHelper.writableDatabase}fun closeDB() {if (db != null) dbHelper.close()}// 插入学生fun insertStudent(stu: Student) {val values = ContentValues().apply {put("id", stu.id)put("name", stu.name)put("age", stu.age)}db.insert("Student", null, values)}// 删除学生fun deleteStudent(stu: Student) {db.delete("Student", "id = ?", arrayOf(stu.id))}// 更新学生fun updateStudent(stu: Student) {val values = ContentValues()values.put("name", stu.name)values.put("age", stu.age)db.update("Student", values, "id = ?", arrayOf(stu.id))}// 查询所有学生fun queryAllStudent():ArrayList<Student> {val cursor = db.query("Student", null, null, null, null, null, null)val stuList = ArrayList<Student>()if (cursor.moveToFirst()) {do {val id = cursor.getString(cursor.getColumnIndex("id"))val name = cursor.getString(cursor.getColumnIndex("name"))val age = cursor.getString(cursor.getColumnIndex("age"))val stu = Student(id, name, age)stuList.add(stu)} while (cursor.moveToNext())}cursor.close()return stuList}
3、登录活动
登录活动用的是sharedPreferences,它使用方法非常easy,首先初始化一个sharedPreferences
对象,文件名和访问类型自定义。读数据就是调用getString
获取键值对,设定个默认值。写数据就是调用sharedPreferences.edit()
赋值给editor对象,然后putString
读取键值对。还记录了下app的使用次数。
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityLoginBinding.inflate(layoutInflater)setContentView(binding.root)sharedPreferences = getSharedPreferences("data", Context.MODE_PRIVATE)var editor = sharedPreferences.edit()// 得到之前的使用次数,然后每次打开app都加1var count = sharedPreferences.getString("count", "0");binding.tvCount.text = (count!!.toInt() + 1).toString()// 保存键值对到sharedpreferences中editor.putString("count", (count!!.toInt() + 1).toString())editor.apply()binding.btnLogin.setOnClickListener{editor.putString("account", binding.etAccount.toString().trim())editor.putString("password", binding.etPassword.toString().trim())editor.apply()Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show()val intent = Intent(this, MainActivity::class.java)startActivity(intent)finish()}}
4、增删改查
其实对数据表的增删改查逻辑在StudentDao中已经封装好了,我们在Activity里面也只是调用方法实现界面和数据库的交互罢了。具体的操作逻辑如下:
输入学号、姓名和年龄后点击添加可以添加学生;输入学号点击查询可以查询学生信息,然后点击删除会删除信息,点击修改会修改输入框中的学生信息,最后如果输入的学号不存在而且你点查询了,会显示所有学生的信息,如果存在只会显示该学生的信息。
override fun onClick(p0: View?) {var stuId = binding.etId.text.toString()var stuName = binding.etName.text.toString()var stuAge = binding.etAge.text.toString()var stu = Student(stuId, stuName, stuAge)var flag = (studentDao.queryById(stuId) != null)when(p0?.id) {R.id.btn_insert->{if (flag) {Toast.makeText(this, "学生已存在,无法添加", Toast.LENGTH_SHORT).show()} else {studentDao.insertStudent(stu)Toast.makeText(this, "添加成功!", Toast.LENGTH_SHORT).show()}}R.id.btn_delete->{if (flag) {studentDao.deleteStudent(stu)Toast.makeText(this, "删除成功!", Toast.LENGTH_SHORT).show()} else {Toast.makeText(this, "该学生不存在,无法删除", Toast.LENGTH_SHORT).show()}}R.id.btn_update->{if (flag) {studentDao.updateStudent(stu)Toast.makeText(this, "修改成功!", Toast.LENGTH_SHORT).show()} else {Toast.makeText(this, "该学生不存在,无法修改", Toast.LENGTH_SHORT).show()}}R.id.btn_query->{if (flag) {// 如果存在则补全信息binding.etAge.setText(studentDao.queryById(stuId)?.age)binding.etName.setText(studentDao.queryById(stuId)?.name)Toast.makeText(this, "查询到该学生信息", Toast.LENGTH_SHORT).show()} else {// 不存在则显示所有学生信息studentList = studentDao.queryAllStudent()adapter = StudentAdapter(this, R.layout.item_student, studentList)binding.lvStu.adapter = adapterToast.makeText(this, "查询所有学生信息", Toast.LENGTH_SHORT).show()}}}}
三、运行演示
1、首先进入登录界面,输入账号和密码然后点击登录即可,右上角是使用次数。
2、进入主界面,我们输入学号、姓名和年龄进行添加学生。
3、点击添加按钮,添加成功。再依次添加几个学生。
4、点击查询,此时学号是不存在的,所以就查询了所有学生的信息。
5、我们输入学号4,然后点击查询,可以看到查询到信息并自动补全了。
6、修改姓名和年龄,然后再点修改,再点击查询,发现已经修改好了信息。
7、我们再查询小益的信息,然后删除小益的信息。
四、实验总结
其实学生系统涉及到数据库的操作完全和前面的其他系统相似,真正做起来还是比较繁琐的。哪里有什么容易代码,都是在一个个bug解决中完成的。理论引导实战,光理论只会纸上谈兵,光实践缺少方法论,基础打牢了才能进阶,不然上限不会高,基础决定了你的上限。
五、源码下载
源代码已上传CSDN,点击下载 |
---|
源代码已上传GitHub,点击下载 |
相关文章:

Kotlin实现简单的学生信息管理系统
文章目录一、实验内容二、实验步骤1、页面布局2、数据库3、登录活动4、增删改查三、运行演示四、实验总结五、源码下载一、实验内容 根据Android数据存储的内容,综合应用SharedPreferences和SQLite数据库实现一个用户信息管理系统,强化对SharedPreferen…...
413. 等差数列划分
413. 等差数列划分 如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。 例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。 给你一个整数数组 nums ,返回数组 nums 中所有为等差数…...

设计模式七大原则
一、设计模式概念 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中,而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大(Christopher Alexander&#x…...

【Mybatis系列】Mybatis常见的分页方法以及源码理解
Mybatis-Plus的selectPage 引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency>添加分页插件 Configuration public class My…...

Java面向对象:多态特性的学习
本文介绍了Java面向对象多态特性, 多态的介绍. 多态的实现条件–1.发生继承.2.发生重写(重写与重载的区别)3.向上转型与向下转型.4.静态绑定和动态绑定5. 实现多态 举例总结多态的优缺点 避免在构造方法内调用被重写的方法… Java面向对象:多态特性的学习一.什么是多态?二.多态…...

id函数 / 可变类型变量 / 不可变类型变量 / +=操作
前言 再说正文之前,需要大家先了解一下对象,指针和引用的含义,不懂得同学可以参考我上一篇博客“(12条消息) 引用是否有地址的讨论的_xx_xjm的博客-CSDN博客” 正文 一:python中一切皆对象 “python中一切皆对象”这句话我相信…...

aws apigateway 使用apigateway集成lambda
参考资料 代理集成,https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html非代理集成,https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/getting-started-…...

Linux SPI 驱动实验
目录 一、Linux 下 SPI 驱动框架简介 1、SPI 主机驱动 2、SPI 设备驱动 SPI 设备数据收发处理流程 3、SPI 设备和驱动匹配过程 二、添加SPI 设备信息 1、添加 ICM20608 所使用的 IO 2、 在 ecspi3 节点追加 icm20608 子节点 三、编写 ICM20608 驱动 1、修改makefile…...

[1.4]计算机系统概述——操作系统的体系结构
第一章 计算机系统概述 操作系统的体系结构 大内核/单内核/宏内核微内核 通过之前的学习,我们知道计算机系统的层次结构是这样的。 但是操作系统的内部其实还可以再进一步地划分。 一部分是内核的功能,一部分是非内核的功能。 操作系统最核心的功能&…...

FPGA的GigE Vision IP相机图像采集方案设计,转换为千兆UDP,支持10G MAC
1 概述 GigE Vision是一个比较复杂的协议,要在FPGA中完全实现具有较大的难度。如果FPGA作为接收端希望实现GigE Vision相机的配置和图像采集功能,则只需要实现其中小部分功能即可。本文对原有GigE Vision协议的结构进行了裁剪,仅保留设备搜索…...

大数据相关面试题
linux 常见linux高级命令? top、iotopnetstatdf -hjmap -heaptarrpmps -efshell 用过的shell工具? awk Awk 命令详解 - 简书 awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来…...

AI绘画第二步,抄作业复现超赞的效果!
上一篇,讲了如何安装AI绘画软件,但是装完后发现生成效果很渣!而网上那些效果都很赞。真的是理想很丰满,现实很骨感。今天就是来聊聊如何抄作业,最大程度的还原那些超赞的效果。换一种说法就是,教大家如何使…...
Python的并发编程
我们将一个正在运行的程序称为进程。每个进程都有它自己的系统状态,包含内存状态、打开文件列表、追踪指令执行情况的程序指针以及一个保存局部变量的调用栈。通常情况下,一个进程依照一个单序列控制流顺序执行,这个控制流被称为该进程的主线…...

【Linux】基本系统维护命令
😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享C/C相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页…...

高数:数列的收敛
数列特点无限个数特定顺序数列和集合区别集合可以乱序,数列不行集合出现重复元素依然相同,数列出现新的重复元素就不相等[1,2,3,4][1,2,3,3,4]对集合来说相等,…...

不平凡的一天——
作者:指针不指南吗 专栏:个人日常记录 🐾或许会很慢,但是不可以停下来🐾 文章目录1.自我介绍2.上学期3.不凡的一天4.新学期写个博客,简单记录一下,新学期加油!!ÿ…...
【Java基础】Map遍历的5种方式
目录 创建一个集合 方式一:Iterator 迭代器遍历 map.entrySet().iterator(); map.keySet().iterator(); 方式二:For Each方式遍历 map.forEach(BiConsumer action) 方式三:获取Collection集合 map.values().forEach() 方式四&#x…...

第十四届蓝桥杯三月真题刷题训练——第 2 天
目录 题目1:奇数倍数 代码: 题目2:求值 代码: 题目3:求和 代码: 题目4:数位排序 代码: 题目1:奇数倍数 题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即…...

自然语言处理历史最全预训练模型(部署)汇集分享
什么是预训练模型?预练模型是其他人为解决类似问题而创建的且已经训练好的模型。代替从头开始建立模型来解决类似的问题,我们可以使用在其他问题上训练过的模型作为起点。预训练的模型在相似的应用程序中可能不是100%准确的。本文整理了自然语…...

csdn写文章自定义表格怎么做
前言 CSDN写文章时,经常会用到表格,不同于Word文档中直接插入表格(自定义几行几列),使用CSDN自带的md文本编辑器时,很难快速插入想要的表格样式,追究原因,也是因为md的语法问题&…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...

云原生安全实战:API网关Envoy的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口,负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...

Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...