写在前面的话:本文是利用java纯后端模拟实现学生管理系统的基本流程,使用的都是基本的java语法,并不涉及IO、File等知识。
学生信息的存储并不涉及数据库,本文使用ArrayList集合模拟数据库进行数据的存储,核心逻辑是相同的
项目结构图,如图所示。分成两部分:学生系统登录->登陆成功以后进入学生管理系统页面
addStudent:添加学生
delStudent:删除学生
enrollUser:注册用户
forgetUser:用户忘记密码
loginUser:用户登录
queryStudent:学生查询功能
updateStudent:学生信息更新
Student:学生类
User:用户类
studentySystem:学生系统登陆主页面
studentySystem代码如下:
public class studentSystem {
//static静态代码块 用于数据的初始化,因为这个代码块只运行一次
static ArrayList<User> listU = new ArrayList<>();
static {
listU.add(new User("zhangsan","123456","123432344489098764","17263549485"));
}
//可以使用final来提高代码的可读性
private static final String ADD_STUDENT = "1";//使用快捷键ctrl+shift+u 一键大小写
private static final String DEL_STUDENT = "2";
private static final String UPDATE_STUDENT = "3";
private static final String QUERY_STUDENT = "4";
private static final String EXIT = "5";
public static void main(String[] args) {
/*说明:应该在主页面创建新的集合,在子页面进行操作以后,数据应存储到公共的集合里面*/
getMain();
//登陆成功以后才进入系统
}
public static void mainStudentSystem() {
ArrayList<Student> list = new ArrayList<>();
loop:
while (true) {
System.out.println("--------------欢迎来到进入学生管理系统------------");
System.out.println("1:添加学生");
System.out.println("2:删除学生");
System.out.println("3:修改学生");
System.out.println("4:查询学生");
System.out.println("5:退出");
System.out.print("请输入您的选择: ");
Scanner sc = new Scanner(System.in);
String choose = sc.next();
switch (choose) {
case ADD_STUDENT:
addStudent.addStu(list);
break;
case DEL_STUDENT:
delStudent.delStu(list);
break;
case UPDATE_STUDENT:
updateStudent.updateStu(list);
break;
case QUERY_STUDENT:
queryStudent.queryStu(list);
break;
case EXIT:
System.out.println("退出");
break loop;
default:
System.out.println("没有该选项!");
}
}
getMain();
}
public static void getMain() {
//首先应该调用用户登录注册的方法1
Scanner sc = new Scanner(System.in);
//定义一个新的集合用来存储用户信息
loop:
while (true) {
System.out.println("-----------欢迎来到学生管理系统-----------");
System.out.println("请选择操作1登录 2注册 3忘记密码 4退出");
String choose = sc.next();
switch (choose) {
case "1":
loginUser.loginUser(listU);
break;
case "2":
enrollUser.enrollUser(listU);
break;
case "3":
forgetUser.forgetUser(listU);
break;
case "4":
System.exit(0);
default:
System.out.println("输入的选项有误!请重新输入!");
}
}
}
}
上述代码应用技术讲解:
static静态代码块 用于数据的初始化,因为这个代码块只运行一次,里面的数据随着class类的加载而加载,例如
static ArrayList<User> listU = new ArrayList<>(); 这里添加static是因为首先要保证list集合不会重新创建,这里集合创建以后就相当于固定了,如果写在main方法里面数据就不好进行传递
private static final String DEL_STUDENT = "2"; 定义一个常量来表示经常需要用到的数据 比如这里使用12345分别表示不同的选项 当使用到的时候不会重复的进行创建。
loginUser.loginUser(listU); 以用户登录为例调用loginUser类下的loginUser带参构造方法,传递过去用户的公共集合。
在main方法里面为了代码的简洁性,把登陆页面抽出来形成了一个方法getMain。用户运行主界面以后会调用getmain方法,在进行while死循环-->退出使用的是System.exit(此方法是直接结束虚拟机的运行)。使用switch--case方法进行判断用户输入的是哪一个选项卡。上述代码使用的是jdk8版本关于switch-case方法有更加简洁的方法,可自行百度。
loginUser:
public class loginUser {
static Scanner sc = new Scanner(System.in);
static String user;
public static void loginUser(ArrayList<User> list) {
System.out.print("请输入用户名: ");
user = sc.next();
boolean b = checkUsername(list, user);
if (b) {
//用户名已存在,进行验证码的判断
for (int i = 0; i < 3; i++) {
String yan = yan();//接受验证码
System.out.println("随机验证码为:" + yan);
System.out.print("请输入验证码: ");
String ma = sc.next();
if (ma.equalsIgnoreCase(yan)) {//忽略大小写
//验证码比对通过,这里应该是请输入密码
for (int i1 = 0; i1 < 3; i1++) {
System.out.print("请输入密码: ");
String pw = sc.next();
if (checkPasswd(list,pw)) {//判断密码是否相同
//密码相同,进行下一步
System.out.println("登录成功!");
studentSystem.mainStudentSystem();
} else {
System.out.println("密码有误,请重新输入!这是您第" + (i1 + 1) + "次机会,一共3次机会.");
}
}
} else {
System.out.println("验证码错误,请重新输入验证码!这是您第" + (i + 1) + "次机会,一共3次机会.");
}
}
System.out.println("登陆失败!您的机会已经用完!该账户已被锁定!");
} else {
//用户名不存在
System.out.println("用户名不存在,请先注册!");
}
}
//验证码,随机生成,以字符串的形式返回
public static String yan() {
//1.将所有的字母存入数组
char[] chs = new char[52];
for (int i = 0; i < chs.length; i++) {
//97对应的ASCII码表就是a
if (i <= 25) {
//添加小写字母a~z
chs[i] = (char) (97 + i);
} else {
//添加大写字母
chs[i] = (char) (65 + i - 26);
}
}
//2.随机四次
Random ra = new Random();
//3.定义一个字符串result接受随机的结果
String result = "";
//利用for循环循环4次
for (int i = 0; i < 4; i++) {
int randomIndexEnglish = ra.nextInt(chs.length);
result = result + chs[randomIndexEnglish];
}
//随机0~9 数字
int randomIndexMath = ra.nextInt(10);
result = result + randomIndexMath;
//生成随机索引
int suijiIndex = ra.nextInt(result.length()) - 1 + 1;//这里的result长度为4 范围是1~4
char[] charsResult = result.toCharArray();//把原来的字符串转换成字符数组
for (int i = 0; i < result.length(); i++) {
char arrTemp = charsResult[i];//将result字符串临时存储
charsResult[i] = charsResult[suijiIndex];
charsResult[suijiIndex] = arrTemp;
}
String str = new String(charsResult);
return str;
}
//判断用户是否存在
public static boolean checkUsername(ArrayList<User> list, String name) {
//1.获取集合里面的用户名
for (int i = 0; i < list.size(); i++) {
//循环遍历集合,获取需要的数据
// 获取到User自定义类信息
User stu = list.get(i);
//从student里面获取id信息
String Yname = stu.getUserName();
//如果已经存在,直接返回reue,并结束循环
if (Yname.equals(name)) {
return true;
}
}
return false;
}
//判断密码是否相同
public static boolean checkPasswd(ArrayList<User> list, String pwd) {
//根据用户名user获取在集合里面的索引
int num = 0;
for (int i = 0; i < list.size(); i++) {
if (user.equals(list.get(i).getUserName())) {
num = i;
break;
}
}
String passwd = list.get(num).getUserPassword();//用户在集合里面的密码
if (pwd.equals(passwd)) {
//密码相同
return true;
}
return false;
}
}
这里的static与主页面的用法相同,都是用于公共判断,如果写在局部变量里面当下面需要用到的时候会很麻烦。
checkUsername该方法用于判断用户是否已经存在,返回类型为布尔值,根据返回值进行if判断是否进入下一步。核心逻辑是使用for循环遍历List集合获取用户名,在与用户实际输入的用户名进行比对,一致的话就判定用户名已存在。
yan该方法用于产生一个随机的验证码,验证码要求是四个应为字母与一个数字进行随机的排序,并以String字符串的形式进行返回。小细节:使用equalsIgnoreCase会忽略大小写,如果单纯的使用equals进行比对验证码的话不会忽略大小写的限制,根据应用场景可以灵活切换。
checkPasswd用于检查用户输入的密码是否正确,核心逻辑在于首先使用for循环获取到用户名对应的索引,再根据索引查询集合中使用的密码,获取到密码以后与用户输入的密码进行比对完全一致的话判定密码正确。
studentSystem.mainStudentSystem();登陆成功以后进行调用studentSystem方法里面的mainStudentSystem方法运行系统的主页面。
enrollUser:注册用户
public class enrollUser {
static Scanner sc = new Scanner(System.in);
//注册用户
public static void enrollUser(ArrayList<User> list) {
User user = new User();
userName(list,user);
System.out.println(user);
list.add(user);
System.out.println("-----");
for (int i = 0; i < list.size(); i++) {
System.out.println(list);
}
}
//判断用户名
public static void userName(ArrayList<User> list,User user) {
//从键盘获取用户输入的用户名
loop:
while (true) {
System.out.print("请输入注册用户名: ");
String newName = sc.next();
//判断用户名是否唯一
boolean flag = checkUsername(list, newName);
if (!flag) {
//用户名唯一,接着判断用户名的长度是否合法
boolean flag2 = checkLength(newName);
if (flag2) {
//用户名长度是合理的,继续判断用户名是否是字母加数字的组合
boolean b = checkNum(newName);
if (b) {
//符合要求,可以继续进行注册
user.setUserName(newName);
passwd(list,user);
System.out.println("注册成功!");
break;
} else {
//不符合要求
System.out.println("您输入的用户名不是字母+数字的组合!请重新输入!");
}
} else {
//长度不合理
System.out.println("您输入的用户名长度不在3~15之间,请重新输入!");
}
} else {
//用户不唯一
System.out.println("您输入的用户名不唯一,请重新输入!");
}
}
}
//判断用户名是否唯一
public static boolean checkUsername(ArrayList<User> list, String name) {
//1.获取集合里面的用户名
for (int i = 0; i < list.size(); i++) {
//循环遍历集合,获取需要的数据
// 获取到User自定义类信息
User stu = list.get(i);
//从student里面获取id信息
String Yname = stu.getUserName();
//如果已经存在,直接返回reue,并结束循环
if (Yname.equals(name)) {
return true;
}
}
return false;
}
//判断用户名的长度是否合理
public static boolean checkLength(String name) {
int count = 0;
for (int i = 0; i < name.length(); i++) {
count++;
}
if (count >= 3 && count <= 15) {
//长度是合理的。
return true;
}
return false;
}
//判断用户名是否是字母加数字的组合
public static boolean checkNum(String name) {
boolean b = cNum(name);//判断是不是纯数字
int count = 0;
if (b) {
//是纯数字
} else {
//不是纯数字,继续判断是否含有其他的符号
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if ((c <= '9' && c >= '0') || (c <= 'z' && c >= 'a') || (c <= 'Z' && c >= 'A')) {
count++;
}
}
if (count == name.length()) {//如果count等于0那么就说明用户名复合要求
return true;
} else {
return false;
}
}
return false;
}
//判断是不是纯数字
public static boolean cNum(String name) {
int count = 0;
for (int i = 0; i < name.length(); i++) {
//循环遍历用户输入的name
char c = name.charAt(i);
if (c <= '9' && c >= '0') {
count++;
}
}
if (count == name.length()) {
return true;
}
return false;
}
//密码最终结果
public static void passwd(ArrayList<User> list,User user) {
while (true) {
//用户名输入成功,开始输入密码
boolean b1 = continuePasswd(user);//判断输入的用户密码
if (b1) {
//开始输入身份证号,调用另外一个方法
enroll(list,user);
break;
} else {
System.out.println("两次输入的密码不一致!请重新输入 ");
}
}
}
//判断用户密码两次输入的结果是否一样
public static boolean continuePasswd(User user) {
System.out.print("请输入注册用户密码: ");
String newPasswd = sc.next();
System.out.print("请再次输入注册密码: ");
String oldPass = sc.next();//第二次输入的密码
if (oldPass.equals(newPasswd)) {
user.setUserPassword(newPasswd);
return true;
}
return false;
}
//判断身份证号
public static void enroll(ArrayList<User> list,User user) {
while (true) {
System.out.print("请输入注册用户身份证号: ");
String nextEnroll = sc.next();//用户输入身份证
if (nextEnroll.length() == 18) {
char c1 = nextEnroll.charAt(0);
if (c1 == '0') {
System.out.println("身份证号码不可以使用0开头!请重新输入!");
} else {
//判断前17位是不是数字
int count = 0;
for (int i1 = 0; i1 < 17; i1++) {
char c2 = nextEnroll.charAt(i1);
if (c2 >= '0' && c2 <= '9') {
//说明是数字
count++;
}
}
if (count == 17) {
//前面17位都是数字
char c = nextEnroll.charAt(17);
if (c == 'X' || c == 'x' || (c >= '0' && c <= '9')) {
//说明输入的身份证号码是合理的
//开始输入手机号
user.setUserStatus(nextEnroll);
phoneNum(list,user);
break;
} else {
System.out.println("您输入的身份证号码最后一位不是X、x或0~9,请重新输入!");
}
} else {
System.out.println("身份证号码前17位必须都是数字!");
}
}
} else {
System.out.println("您输入的身份证号码不是18位!请重新输入!");
}
}
}
//输入以及检查手机号
public static void phoneNum(ArrayList<User> list,User user) {
while (true) {
System.out.print("请输入注册的手机号: ");
String phone = sc.next();
if (phone.length() == 11) {
if (phone.charAt(0) != '0') {
//手机号输入正确,把结果传到集合里面
user.setUserPhonenumber(phone);
break;
} else {
System.out.println("手机号不可以以0开头!");
}
} else {
System.out.println("手机号长度不对!请重新输入!");
}
}
}
}
要点:
passwd(list,user); 在代码里面可以看到很多类似的写法,这种写法就是递归调用,逻辑在于:注册的用户名"正确合法"吗?->密码符合要求吗?->进而判定身份证->判断手机号 身份证与手机号使用的是原始写法,并没有写正则表达式。因此看起来会相对繁琐。
forgetUser:
public class forgetUser {
static Scanner sc = new Scanner(System.in);
static String userName;
static String role;
static String phnum;
//忘记密码
public static void forgetUser(ArrayList<User> list) {
System.out.print("请输入用户名: ");
userName = sc.next();
//判断用户是否存在
if (loginUser.checkUsername(list, userName)) {
//用户存在
//判断输入的身份证号与集合存储的数据是否一致,一直返回true不一致返false
boolean b = roleAndPhonenumber(list);
if (b) {
//都一致了,进行修改密码
while (true) {
System.out.print("请输入新的密码: ");
String pd = sc.next();
System.out.print("请再次输入新的密码:");
String pd2 = sc.next();
if (pd2.equals(pd)) {
//把新的密码传给对应的集合里面
int index = getIndex(list);
list.get(index).setUserPassword(pd);
System.out.println("修改密码成功!");
break;
}
}
}
} else {
//用户不存在
System.out.println("需要修改的用户名:" + userName + "还未注册!");
}
}
//判断身份证与手机号
public static boolean roleAndPhonenumber(ArrayList<User> list) {
System.out.print("请输入注册身份证号:");
role = sc.next();
System.out.print("请输入注册手机号:");
phnum = sc.next();
//获取userName在集合里面的索引
int num = getIndex(list);
String status = list.get(num).getUserStatus();//用户在集合里面的身份证号码
String phone = list.get(num).getUserPhonenumber();//用户在集合里面的手机号码
if (status.equals(role)) {
//判断身份证与手机号是否一致
if (phone.equals(phnum)) {
return true;
}else {
System.out.println("您输入的手机号与注册时的不一致!");
}
}else{
System.out.println("您输入的身份证与注册时的不一致!");
}
return false;
}
public static int getIndex(ArrayList<User> list){
int num = 0;
for (int i = 0; i < list.size(); i++) {
if (userName.equals(list.get(i).getUserName())) {
num = i;
break;
}
}
return num;
}
}
要点:
在于根据用户注册的时候输入的身份证与手机哈进行判断是否是本人。
addStudent:
public class addStudent {
public static void addStu(ArrayList<Student> list) {
//1.创建新的集合来存储信息
//利用集合来进行添加操作
//2.创建新的Student类来存储添加的信息
Student stu = new Student();
Scanner sc = new Scanner(System.in);
System.out.print("请输入学生id: ");
String sid = sc.next();
//用户输入以后进行判断是否已经存在
if (!checkId(list,sid)){
stu.setId(sid);
System.out.print("请输入学生姓名: ");
String sname = sc.next();
stu.setName(sname);
System.out.print("请输入学生年龄: ");
int sage = sc.nextInt();
stu.setAge(sage);
System.out.print("请输入学生住址: ");
String saddress = sc.next();
stu.setAddress(saddress);
//3.将stu里面的信息添加到集合里面
list.add(stu);
System.out.println("添加成功!");
}else {
System.out.println("您输入的id已经存在,请重新输入!");
}
//4.进行id唯一性判断,单独写一个方法进行实现
}
//检查id是否唯一
public static boolean checkId(ArrayList<Student> list, String checkid) {
//1.获取集合里面的id
for (int i = 0; i < list.size(); i++) {
//循环遍历集合,获取需要的id数据
// 获取到Student自定义类信息
Student stu = list.get(i);
//从student里面获取id信息
String id = stu.getId();
//如果已经存在,直接返回reue,并结束循环
if (id.equals(checkid)) {
return true;
}
}
return false;
}
}
delStudent:
public class delStudent {
public static void delStu(ArrayList<Student> list) {
//基本逻辑:通过用户输入需要删除的id,id存在删除,不存在返回到初始菜单
//1.键盘录入
Student stu1 = new Student();
Scanner sc = new Scanner(System.in);
System.out.print("请输入需要删除的学生id: ");
String dropId = sc.next();
//2.循环遍历集合,获取Student对象
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
String cid = stu.getId();
if (dropId.equals(cid)) {
//id存在
list.remove(i);
System.out.println("删除成功");
return;//return一个方法,表示该方法直接结束,不会运行到后面的代码
}
}
//id不存在
System.out.println("需要删除的id不存在");
}
}
queryStudent:
public class queryStudent {
public static void queryStu(ArrayList<Student> list) {
Scanner sc = new Scanner(System.in);
//打印所有的学生信息
//进行集合非空判断
int len = list.size();
if (len == 0) {
System.out.println("当前无学生信息,请添加后在查询");
}else{
printAll(list);
}
}
//打印全部学生信息
public static void printAll(ArrayList<Student> list){
System.out.println("id\t姓名\t年龄\t家庭住址");
for (int i = 0; i < list.size(); i++) {
//循环遍历集合
Student stu = list.get(i);
System.out.println(stu.getId()+"\t"+stu.getName()+"\t"+stu.getAge()+"\t"+stu.getAddress());
}
}
//自定义查询
}
updateStudent:
public class updateStudent {
public static void updateStu(ArrayList<Student> list){
//基本逻辑:键盘录入需要修改的学生id,需要满足以下要求:id存在则继续录入信息,id不存在则提示不存在并回到初始菜单
Scanner sc = new Scanner(System.in);
//1.录入
System.out.print("请输入需要修改的学生id: ");
String upId = sc.next();
//这里可以直接return,不需要loop
loop:while (true) {
for (int i = 0; i < list.size(); i++) {
Student stuUp = list.get(i);//获取Student对象
String cid = stuUp.getId();//获取Student里面的id
if (cid.equals(upId)) {//比对键盘录入的id是否等于student里面的id
//id存在,提示用户进行修改
System.out.println("请输入需要修改的信息: ");
// System.out.print("请输入修改后的学生id: ");
// String xiuId = sc.next();
// stuUp.setId(xiuId);//重新把id传递过去
System.out.print("请输入修改后的学生姓名: ");
String xiuName = sc.next();
stuUp.setName(xiuName);//重新把name传递过去
System.out.print("请输入修改后的学生年龄: ");
int xiuAge = sc.nextInt();
stuUp.setAge(xiuAge);//重新把age传递过去
System.out.print("请输入修改后的学生住址: ");
String xiuAddress = sc.next();
stuUp.setAddress(xiuAddress);//重新把地址传递过去
System.out.println("修改成功!");
break loop;//这里应该跳出loop循环,单独的break会打印后面的代码
}
}
System.out.println("您想要修改的id不存在!");
break;
}
}
}
Student:常规javabean写法
public class Student {
private String id;
private String name;
private int age;
private String address;
public Student() {
}
public Student(String id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
/**
* 获取
* @return id
*/
public String getId() {
return id;
}
/**
* 设置
* @param id
*/
public void setId(String id) {
this.id = id;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
/**
* 获取
* @return address
*/
public String getAddress() {
return address;
}
/**
* 设置
* @param address
*/
public void setAddress(String address) {
this.address = address;
}
public String toString() {
return "student{id = " + id + ", name = " + name + ", age = " + age + ", address = " + address + "}";
}
}
User:
public class User {
private String userName;//用户名
private String userPassword;//密码
private String userStatus;//身份证号
private String userPhonenumber;//手机号
public User() {
}
public User(String userName, String userPassword, String userStatus, String userPhonenumber) {
this.userName = userName;
this.userPassword = userPassword;
this.userStatus = userStatus;
this.userPhonenumber = userPhonenumber;
}
/**
* 获取
* @return userName
*/
public String getUserName() {
return userName;
}
/**
* 设置
* @param userName
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* 获取
* @return userPassword
*/
public String getUserPassword() {
return userPassword;
}
/**
* 设置
* @param userPassword
*/
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
/**
* 获取
* @return userStatus
*/
public String getUserStatus() {
return userStatus;
}
/**
* 设置
* @param userStatus
*/
public void setUserStatus(String userStatus) {
this.userStatus = userStatus;
}
/**
* 获取
* @return userPhonenumber
*/
public String getUserPhonenumber() {
return userPhonenumber;
}
/**
* 设置
* @param userPhonenumber
*/
public void setUserPhonenumber(String userPhonenumber) {
this.userPhonenumber = userPhonenumber;
}
public String toString() {
return "User{userName = " + userName + ", userPassword = " + userPassword + ", userStatus = " + userStatus + ", userPhonenumber = " + userPhonenumber + "}";
}
}
运行结果: