学习一门语言必须要有的精神之如何将一道练习题做到极致(Java+云数据库)

在上一篇文章:程序员必备技能!给别人的代码挑错之Java教材上的"计算器"实例中,我挑了教材例题里的三个毛病,今天,我自己写了一道练习题,打算揪一揪自己的毛病

先来看看题目吧:

定义一个学生类Sudent,属性包括学号、班号、姓名、性别、年龄、班级总人数,方法包括获得学号、获得班号、获得姓名、获得性别、获得年龄、获得班级总人数、修改学号、修改班号、修改姓名、修改性别、修改年龄,以及一个toString()方法将Student类中的所有属组合成一个字符串。定义一个学生数组对象。设计Test类进行测试。

我的第一版是这样写的(想直接看改进版的可以戳这):

Student.java
package project1;
import java.util.Scanner;

/**
 * @author 郑博培
 */
public class Student<age, name> {
    int id;
    String classId;
    String name;
    String sex;
    int age;
    int classNumber;

    public Student(int id,String classId,String name,String sex,int age,int classNumber){
        this.id = id;
        this.classId = classId;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.classNumber = classNumber;
    }

    public void getId(){
        System.out.println("学号:" + this.id);
    }

    public void getClassId(){
        System.out.println("班号:" + this.classId);
    }

    public void getName(){
        System.out.println("姓名:" + this.name);
    }

    public void getSex(){
        System.out.println("性别:" + this.sex);
    }

    public void getAge(){
        System.out.println("年龄:" + this.age);
    }

    public void getClassNumber(){
        System.out.println("性别:" + this.classNumber);
    }

    public void setId(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学号: ");
        this.id = sc.nextInt();
        System.out.println("学号已修改为:" + this.id);
    }

    public void setClassId(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入班号: ");
        this.classId = sc.next();
        System.out.println("班号已修改为:" + this.classId);
    }

    public void setName(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入姓名: ");
        this.name = sc.next();
        System.out.println("姓名已修改为:" + this.name);
    }

    public void setSex(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入性别: ");
        this.sex = sc.next();
        System.out.println("性别已修改为:" + this.sex);
    }

    public void setAge(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年龄: ");
        this.age = sc.nextInt();
        System.out.println("年龄已修改为:" + this.age);
    }

    public void setClassNumber(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入班号: ");
        this.classNumber = sc.nextInt();
        System.out.println("班级总人数已修改为:" + this.classNumber);
    }

    @Override
    public String toString(){
        String info;
        info = this.id + " " + this.classId + " " + this.name + " " + this.sex + " " + this.age + " " + this.classNumber;
        System.out.println("学号 班号 姓名 性别 年龄 班级总人数");
        System.out.println("个人信息: " + info);
        return info;
    }

}

TestStudent.java
package project1;
import java.util.Scanner;

/**
 * @author Administrator
 */
public class TestStudent {
    public static void main(String[] args) {
        int item;
        Student leagueSecretary = new Student(11, "1801", "郑博培", "男", 20, 28);
        leagueSecretary.toString();
        Scanner sc = new Scanner(System.in);
        System.out.println("**********Menu**********");
        System.out.println("1.修改学号");
        System.out.println("2.修改班号");
        System.out.println("3.修改姓名");
        System.out.println("4.修改年龄");
        System.out.println("5.退出");
        System.out.println("*******************************");
        System.out.println("输入您要进行的操作:");
        item = sc.nextInt();
        switch (item) {
            case 1:
                leagueSecretary.setId();
                break;
            case 2:
                leagueSecretary.setClassId();
                break;
            case 3:
                leagueSecretary.setName();
                break;
            case 4:
                leagueSecretary.setAge();
                break;
            case 5:
                break;
            default:
                System.out.println("输入有误!");
        }
        leagueSecretary.toString();
    }
}

这样写是把一条数据当成一个对象来实现的,对于只有一条数据的对象来说比较好解决,可是如果数据量很大呢?

有成百上千条数据时,有没有更优的办法?

在这里插入图片描述
当然有方法!我们引入数据库不就好了吗?

关于数据库的使用方法,大家可以查看我的这篇文章:
Java连接MySQL时解决java.lang.ClassNotFoundException

这里我使用的云数据库,其实使用方法跟本地的数据库是一样的,在"StudentSQL.java"文件里的思路是:

  1. 连接云端MySQL数据库(初始化)
  2. 获取数据库输出内容(get方法)
  3. 通过Java语句修改云端数据库(set方法)

连接云端MySQL数据库(初始化)

对云数据库不太了解的同学可以查看这篇文章:
写给大忙人看的数据库迁移上云与爬取云数据库实例(MySQL)

public class StudentSQL {

    int studentId = 0;
    String classId;
    String name;
    String sex;
    int age;
    int classNumber;
    private final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    private final String DB_URL = "jdbc:mysql://mysql.rds.aliyuncs.com:3306/";
    private final String USER = "";
    private final String PASS = "";
    Connection conn = null;
    Statement stmt = null;
    String sql;

    public StudentSQL() throws ClassNotFoundException, SQLException {
        Class.forName(JDBC_DRIVER);
        System.out.println("连接数据库...");
        conn = DriverManager.getConnection(DB_URL, USER, PASS);
        System.out.println("云数据库已成功连接!");
        // 执行查询
        stmt = conn.createStatement();
    }
}
  • DB_URL需要填写自己的数据库地址,如果是本地数据库的话就是127.0.0.1,端口号都是3306
  • USER是数据库的账户名
  • PASS是数据库的密码
    因为涉及数据库安全,这里我就不公开了哈哈哈,如果是学习需要,可以私聊我

简单解释一下,构造方法里实现的是数据库连接,因为构造方法只在对象创建时运行,而数据库连接也只需要连接一次,因此我把数据库连接放到了构造方法里

这是云数据库的student表界面:
在这里插入图片描述

获取数据库输出内容(get方法)

在这个程序里,我的get方法很多,下面为大家一一道来:

getOutput
public void getOutput(String sql) throws SQLException {
        ResultSet rs = stmt.executeQuery(sql);
        // 展开结果集数据库
        while(rs.next()){
            // 通过字段检索
            try {
                if (rs.findColumn("studentId") != 0) {
                    this.studentId = rs.getInt("studentId");
                    System.out.print("  studentId: " + this.studentId);
                }
            }catch (SQLException e){}

            try {
                if (rs.findColumn("classId") != 0){
                    this.classId = rs.getString("classId");
                    System.out.print("  classId: " + this.classId);
                }
            }catch (SQLException e){}

            try {
                if (rs.findColumn("name") != 0){
                    this.name = rs.getString("name");
                    System.out.print("  name: " + this.name);
                }
            }catch (SQLException e){}

            try {
                if (rs.findColumn("sex") != 0){
                    this.sex = rs.getString("sex");
                    System.out.print("  sex: " + this.sex);
                }
            }catch (SQLException e){}

            try {
                if (rs.findColumn("age") != 0){
                    this.age = rs.getInt("age");
                    System.out.print("  age: " + this.age);
                }
            }catch (SQLException e){}

            try {
                if (rs.findColumn("classNumber") != 0){
                    this.classNumber = rs.getInt("classNumber");
                    System.out.print("  classNumber: " + this.classNumber);
                }
            }catch (SQLException e){}
            System.out.println();
        }
        System.out.println("已全部输出!");
    }

这里给大家讲一下try语句,我们知道,如果数据库返回的内容里没有某个字段时,使用getString()或者getInt()是会报错的,findColumn()也是如此,而try{}catch{}语句就能很好地解决这一问题

从字面理解,try就是尝试,尝试运行这条语句,如果语句运行失败,程序并不会终止,会继续运行

既然上面提到了getString()、getInt()和findColumn(),这里我也解释一下:

  • getString()是获取字段的值,且值是String类型的方法
  • getInt()是获取字段的值,且值是Int类型的方法
  • findColumn()可以获取字段的索引,因此也可以用来判断字段是否存在
getAll
public void getAll() throws SQLException {
        sql = "SELECT * FROM student";
        getOutput(sql);
    }

很简单的SQL语句:

SELECT * FROM 表名

获取该表里的全部数据,星 * 就是全部的意思

getId
public void getId() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("学号范围:2020000001~2020999999");
        System.out.println("请输入学号: ");
        int studentId = sc.nextInt();
        sql = "SELECT * FROM `student` WHERE `studentId` = " + studentId;
        getOutput(sql);
    }

比刚刚的SQL语句更复杂了一些,加了一个where用作判断,其实很简单,就是字面意思

getClassId
public void getClassId() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("以下是所有班号: ");
        sql = "SELECT `classId` FROM `student` GROUP BY `classId` ";
        getOutput(sql);
        System.out.println("请输入班号: ");
        String classId = sc.next();
        sql = "SELECT * FROM `student` WHERE `classId` = '" + classId + "' ";
        getOutput(sql);
    }
getName
public void getName() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入姓名: ");
        String name = sc.next();
        sql = "SELECT * FROM `student` WHERE `name` = '" + name + "' ";
        getOutput(sql);
    }
getSex
public void getSex() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入性别: ");
        String sex = sc.next();
        sql = "SELECT * FROM `student` WHERE `sex` = '" + sex + "' ";
        getOutput(sql);
    }
getAge
public void getAge() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年龄: ");
        int age = sc.nextInt();
        sql = "SELECT * FROM `student` WHERE `age` = " + age;
        getOutput(sql);
    }
getClassNumber
public void getClassNumber() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入班级总人数: ");
        int classNumber = sc.nextInt();
        sql = "SELECT * FROM `student` WHERE `classNumber` = " + classNumber;
        getOutput(sql);
    }

其实只要看懂前面几个get方法就可以了,后面的都是换汤不换药

通过Java语句修改云端数据库(set方法)

set方法也有很多,但本质其实就是SQL语句里的UPDATE,当你理解其中一两个以后,剩下的就很简单了

setInfo
public void setInfo() throws SQLException {
        System.out.println("请输入该生的学号:");
        Scanner sc = new Scanner(System.in);
        this.studentId = sc.nextInt();
        sql = "SELECT * FROM `student` WHERE `studentId` = '" + this.studentId + "' ";
        getOutput(sql);
        int item;
        modify:
        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.println("6.班级总人数");
            System.out.println("7.退出");
            System.out.println("*******************************");
            System.out.println("输入您要进行的操作:");
            item = sc.nextInt();
            switch (item) {
                case 1:
                    setStudentId();
                    break;
                case 2:
                    setClassId();
                    break;
                case 3:
                    setName();
                    break;
                case 4:
                    setSex();
                    break;
                case 5:
                    setAge();
                    break;
                case 6:
                    setClassNumber();
                    break;
                case 7:
                    break modify;

                default:
                    System.out.println("输入有误!");
            }
        }
    }

这里以学号作为标准,因为姓名有可能出现同名同姓的情况,而学号不会,每个人都有自己的学号

从学号获取学生的信息,再拉个菜单,选择要修改哪些字段,这样一来,思路便清晰了许多,其实这一步跟前面的getOutput是类似的

setStudentId
public void setStudentId() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学号: ");
        String studentId = sc.next();
        System.out.println("将学号从" + this.studentId + "改成" + studentId);
        System.out.println("学号是重要字段,已为您提交工单!");
    }

因为学号是主键,所以这里不会直接去修改学号,一定要修改的话,需要再次确认

setClassId
public void setClassId() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入班号: ");
        String classId = sc.next();
        sql = "UPDATE `student` SET `classId` = '" + classId + "' WHERE `studentId` = " + this.studentId;
        boolean rs = stmt.execute(sql);
        sql = "SELECT * FROM `student` WHERE `studentId` = '" + studentId + "' ";
        getOutput(sql);
    }

这里用了两个sql语句,第二句其实是做对比的,用来查看是否成功修改了

setName
public void setName() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入姓名: ");
        String name = sc.next();
        sql = "UPDATE `student` SET `name` = '" + name + "' WHERE `studentId` = " + this.studentId;
        boolean rs = stmt.execute(sql);
        sql = "SELECT * FROM `student` WHERE `studentId` = '" + studentId + "' ";
        getOutput(sql);
    }

这里需要注意的是name和this.name不是同一个变量,name只能在这个void里使用,存放的是修改(修正)后的姓名

setSex
public void setSex() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入性别: ");
        String sex = sc.next();
        sql = "UPDATE `student` SET `sex` = '" + sex + "' WHERE `studentId` = " + this.studentId;
        boolean rs = stmt.execute(sql);
        sql = "SELECT * FROM `student` WHERE `studentId` = '" + studentId + "' ";
        getOutput(sql);
    }
setAge
public void setAge() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年龄: ");
        int age = sc.nextInt();
        sql = "UPDATE `student` SET `age` = '" + age + "' WHERE `studentId` = " + this.studentId;
        boolean rs = stmt.execute(sql);
        sql = "SELECT * FROM `student` WHERE `studentId` = '" + studentId + "' ";
        getOutput(sql);
    }

setClassNumber
public void setClassNumber() throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入班号: ");
        int classNumber = sc.nextInt();
        sql = "UPDATE `student` SET `classNumber` = '" + classNumber + "' WHERE `studentId` = " + this.studentId;
        boolean rs = stmt.execute(sql);
        sql = "SELECT * FROM `student` WHERE `studentId` = '" + studentId + "' ";
        getOutput(sql);
    }

另外,细心的朋友应该会发现:

  • set方法里提交sql语句用的是:
    boolean rs = stmt.execute(sql);

  • get方法里提交sql语句用的是:
    ResultSet rs = stmt.executeQuery(sql);

这个地方是需要注意的,不然就会报错

下面我们把测试类写上:

package project1;
import java.sql.SQLException;
import java.util.Scanner;

/**
 * @author Administrator
 */
public class TestStudentSQL {
    public static void main(String []args) throws SQLException, ClassNotFoundException {
        StudentSQL newConnect = new StudentSQL();
        int item;
        connect:
        while (true) {
            Scanner sc = new Scanner(System.in);
            System.out.println("**********Menu**********");
            System.out.println("1.查看所有同学信息");
            System.out.println("2.按学号查找");
            System.out.println("3.按班号查找");
            System.out.println("4.按姓名查找");
            System.out.println("5.按性别查找");
            System.out.println("6.按年龄查找");
            System.out.println("7.按班级总人数查找");
            System.out.println("8.修改学生信息");
            System.out.println("9.退出");
            System.out.println("*******************************");
            System.out.println("输入您要进行的操作:");
            item = sc.nextInt();
            switch (item) {
                case 1:
                    newConnect.getAll();
                    break;
                case 2:
                    newConnect.getId();
                    break;
                case 3:
                    newConnect.getClassId();
                    break;
                case 4:
                    newConnect.getName();
                    break;
                case 5:
                    newConnect.getSex();
                    break;
                case 6:
                    newConnect.getAge();
                    break;
                case 7:
                    newConnect.getClassNumber();
                    break;
                case 8:
                    newConnect.setInfo();
                    break;
                case 9:
                    break connect;
                default:
                    System.out.println("输入有误!");
            }
        }
        newConnect.closeDatabase();
        System.out.println("云服务器已断开连接");
    }
}

测试类主要实现的是方法的调用,因此代码应该尽可能地简洁

以上就是全部内容,大家也可以根据我的代码,继续修改出一个更完善的程序

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.郑先生_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值