Kotlin实现简单的学生信息管理系统

news2024/12/23 22:52:25

文章目录

  • 一、实验内容
  • 二、实验步骤
    • 1、页面布局
    • 2、数据库
    • 3、登录活动
    • 4、增删改查
  • 三、运行演示
  • 四、实验总结
  • 五、源码下载

一、实验内容

根据Android数据存储的内容,综合应用SharedPreferences和SQLite数据库实现一个用户信息管理系统,强化对SharedPreferences的理解的使用,熟练掌握SQLite的操作。要求:

  1. 巩固Android应用开发工具(Eclipse或者AndroidStudio)的常规用法;
  2. 巩固Activity、UI控件的常规用法;
  3. 掌握SharedPpreferences数据存储的使用;
  4. 掌握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">
    <EditText
        android: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" />
    <EditText
        android: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" />
    <EditText
        android: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" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android: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"/>
        <Button
            android: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>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="20dp">
        <Button
            android: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"/>
        <Button
            android: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>
    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@color/black"/>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:text="学号"
            android:textSize="20sp"
            android:gravity="center"
            android:layout_height="wrap_content"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:text="姓名"
            android:textSize="20sp"
            android:gravity="center"
            android:layout_height="wrap_content"/>
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:text="年龄"
            android:textSize="20sp"
            android:gravity="center"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@color/black"/>
    <ListView
        android: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:SQLiteDatabase

    fun 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都加1
        var 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 = adapter
                    Toast.makeText(this, "查询所有学生信息", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

三、运行演示

1、首先进入登录界面,输入账号和密码然后点击登录即可,右上角是使用次数。

在这里插入图片描述

2、进入主界面,我们输入学号、姓名和年龄进行添加学生。

在这里插入图片描述
3、点击添加按钮,添加成功。再依次添加几个学生。

在这里插入图片描述

4、点击查询,此时学号是不存在的,所以就查询了所有学生的信息。

在这里插入图片描述
5、我们输入学号4,然后点击查询,可以看到查询到信息并自动补全了。

在这里插入图片描述
6、修改姓名和年龄,然后再点修改,再点击查询,发现已经修改好了信息。

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

7、我们再查询小益的信息,然后删除小益的信息。
在这里插入图片描述
在这里插入图片描述

四、实验总结

其实学生系统涉及到数据库的操作完全和前面的其他系统相似,真正做起来还是比较繁琐的。哪里有什么容易代码,都是在一个个bug解决中完成的。理论引导实战,光理论只会纸上谈兵,光实践缺少方法论,基础打牢了才能进阶,不然上限不会高,基础决定了你的上限。

五、源码下载

源代码已上传CSDN,点击下载
源代码已上传GitHub,点击下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ks通过恶意低绩效来变相裁员(六)各方核心利益点分析

目录 公司利益点 管理层利益点 直接管理者利益点 一线干活的同学 一线嫡系同学 公司利益点 核心利益点&#xff1a;围绕财报营收&#xff0c;降本&#xff0c;拿到好看的财报数据&#xff0c;让资本市场继续看好自己 核心手段&#xff1a; 扩展新业务&#xff0c;挖掘已…

基于数据驱动的智能空调系统需求响应可控潜力评估研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

深入理解多线程

一、线程基本概念 1、概述 线程是允许应用程序并发的一种机制。线程共享进程内的所有资源。 线程是调度的基本单位。 每个线程都有自己的 errno。 所有 pthread 函数均以返回 0 表示成功&#xff0c;返回一个正值表示失败。 编译 pthread 程序需要添加链接库&#xff08;…

【Java】反射机制和代理机制

目录一、反射1. 反射概念2. 反射的应用场景3. 反射机制的优缺点4. 反射实战获取 Class 对象的四种方式二、代理机制1. 代理模式2. 静态代理3. 动态代理3.1 JDK动态代理机制1. 介绍2.JDK 动态代理类使用步骤3. 代码示例3.2 CGLIB 动态代理机制1.介绍2.CGLIB 动态代理类使用步骤3…

程序员压力大?用 PyQt 做一个美*女GIF设置桌面,每天都有好心情

嗨害大家好鸭&#xff01;我是小熊猫~ 要说程序员工作的最大压力不是来自于工作本身&#xff0c; 而是来自于需要不断学习才能更好地完成工作&#xff0c; 因为程序员工作中面对的编程语言是在不断更新的&#xff0c; 同时还要学习熟悉其他语言来提升竞争力… 好了&#xff0c…

使用Python通过拉马努金公式快速求π

使用Python通过拉马努金公式快速求π 一、前言 π是一个数学常数&#xff0c;定义为&#xff1a;圆的周长与直径的比值。 π是一个无理数&#xff0c;也是一个超越数&#xff0c;它的小数部分无限不循环。 π可以用来精确计算圆周长、圆面积、球体积等几何形状的关键值。 有关…

【电子学会】2022年12月图形化二级 -- 老鹰捉小鸡

老鹰捉小鸡 小鸡正在农场上玩耍&#xff0c;突然从远处飞来一只老鹰&#xff0c;小鸡要快速回到鸡舍中&#xff0c;躲避老鹰的抓捕。 1. 准备工作 &#xff08;1&#xff09;删除默认白色背景&#xff0c;添加背景Farm&#xff1b; &#xff08;2&#xff09;删除默认角色小…

进制间转换

md&#xff0c;离开学校好多年了&#xff0c;这些基础趁现在还记得记录一下&#xff0c;不然怕哪天还给老师就尴尬了&#xff0c;方便复习 基本概念 二进制&#xff1a;&#xff08;逢2进1&#xff09;由0和1组成。十六进制&#xff1a;&#xff08;逢16进1&#xff09;由0-9&a…

编码器SIQ-02FVS3驱动

一.简介 此编码器可以是功能非常强大&#xff0c;可以检测左右转动&#xff0c;和按键按下&#xff0c;所以说这一个编码器可以抵三个按键&#xff0c;而且体积非常小&#xff0c;使用起来比三个按键要高大尚&#xff0c;而且驱动也简单。唯一不足的点就是价格有点小贵6-8元才…

Faster RCNN 论文阅读

1.网络架构 VGG16网络 anchors:人工放上去的 RPN对anchors进行二分类&#xff0c;正样本&#xff0c;负样本 RoIP&#xff1a;前面的框框已经圈出目标&#xff0c;但还不知道具体属于哪个类&#xff0c;它就是干这个工作的 2.VGG网络 VGG网络可以任意替换其他的任意神经网络&am…

Spring核心模块——Aware接口

Aware接口前言基本内容例子结尾前言 Spring的依赖注入最大亮点是所有的Bean对Spring容器对存在都是没有意识到&#xff0c;Spring容器中的Bean的耦合度是很低的&#xff0c;我们可以将Spring容器很容易换成其他的容器。 但是实际开发的时候&#xff0c;我们经常要用到Spring容…

虚拟机安装Windows 10

虚拟机安装Windows 10 镜像下载 方法一&#xff1a;下载我制作好的镜像文件->百度网盘链接 提取码&#xff1a;Chen 方法二&#xff1a;自己做一个 进入微软官网链接 下载"MediaCreationTool20H2" 运行该工具 点击下一步选择路径&#xff0c;等他下载好就欧克了…

我就不信你还不懂HashSet/HashMap的底层原理

&#x1f4a5;注&#x1f4a5; &#x1f497;阅读本博客需备的前置知识如下&#x1f497; &#x1f31f;数据结构常识&#x1f31f;&#x1f449;1️⃣八种数据结构快速扫盲&#x1f31f;Java集合常识&#x1f31f;&#x1f449;2️⃣Java单列集合扫盲 ⭐️本博客知识点收录于…

MicroBlaze系列教程(7):AXI_SPI的使用(M25P16)

文章目录 AXI_SPI简介MicroBlaze硬件配置常用函数使用示例波形实测参考资料工程下载本文是Xilinx MicroBlaze系列教程的第7篇文章。 AXI_SPI简介 Xilinx AXI-SPI IP共有两个:一个是标准的AXI_SPI,即4线制SPI,CS、SCLK、MOSI和MISO,另一个是AXI_Quad SPI,支持配置成标准SP…

pygame10 扫雷游戏3

上一节课我们完成了扫雷游戏地图中雷数量的显示&#xff0c;今天我们将把雷的生成做出来 一、地雷的生成 地图中有20*20共400个格子&#xff0c;我们可以设定一共可以生成40个地雷&#xff0c;为了使得每次生成的地图都不一样&#xff0c;可以使用随机数randint&#xff0c;每…

为什么使用Junit单元测试?Junit的详解

Hi I’m Shendi 为什么使用Junit单元测试&#xff1f;Junit的详解 Junit简介 Junit是一个Java语言的单元测试框架。 单元测试是一个对单一实体&#xff08;类或方法&#xff09;的测试 JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架&#xff08;regression test…

AUTOSAR FunctionalSafety

概述 随着汽车功能复杂度的急剧增加,功能安全作为一个系统特征开始被重视,影响着系统设计决策。软件作为一个因素影响着系统级的复杂度。新的技术和概念可以被用在软件开发中来减少复杂度,来实现功能安全。 AUTOSAR提供了一些安全措施和机制来支持安全系统开发,但是并不是…

MATLAB绘制椭圆形相关系矩阵图

数据/代码准备 数据及代码下载&#xff1a; 下载专区-《MATLAB统计分析与应用&#xff1a;40个案例分析》程序与数据 绘图函数&#xff1a; matrixplot(data, PARAM1,val1, PARAM2,val2, ...) 案例 数据如下&#xff1a; MATLAB代码如下&#xff1a; clc close all clear …

升级 vue3 常见问题总汇

Ⅰ、前言 虽然 vue3 是没有删除 vue2 的 选项式 API &#xff0c; 但是我们升级vue3 还是需要修改很多问题的下面来看看我们升级常见的一些问题 &#x1f447; 文章目录Ⅰ、前言Ⅱ、解决兼容问题1、路由的创建方式2、路由的方法变化3、升级 vuex 到 4.x4、作用域 插槽语法修改…

Hyperf使用RabbitMQ消息队列

Hyperf连接使用RabbitMQ消息中间件 传送门 使用Docker部署RabbitMQ&#xff0c;->传送门<使用Docker部署Hyperf&#xff0c;->传送门-< 部署环境 安装amqp扩展 composer require hyperf/amqp安装command命令行扩展 composer require hyperf/command配置参数 假…