大家好,今天我和大家分享一下基于数据库的简单学生管理系统,前面我也写过简单的学生管理系统,不过那些都是用数组或集合来实现的,它们保存的数据在程序运行结束后就会消失。而我今天和大家分享的基于数据库的简单学生管理系统它能在程序运行结束后依然还有保存的数据。
在讲之前,我们要了解怎么样让Java代码和数据库连接起来。Java代码和数据库是通过JDBC连接起来的,Java代码通过JDBC向数据库传SQL语句,数据库执行SQL语句通过JDBC向Java代码传执行结果。
前面我也写过 JDBC操作数据库的步骤。
1、加载数据库驱动
2、获取数据库的连接
3、获取用于执行sql命令的执行对象
4、执行
5、处理结果
6、回收资源
工具类MyJDBC:里面包含一些用 JDBC操作数据库的方法还有更新和查询的方法。注意我这里除了更新的方法外其他方法的异常都捕获了,因为像涉及到转钱这样的更新操作,需要用事务处理,我们这里把异常捕获了,可能影响事务的处理。
public class MyJDBC {
//加载驱动的类路径
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
//数据库连接的URL地址
private static final String URL = "jdbc:mysql://127.0.0.1:3306/studemo?serverTimezone=UTC";
//连接数据库的用户名
private static final String USER = "root";
//连接数据库的密码
private static final String PASSWORD = "123456";
//加载驱动
static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConn() {
Connection conn = null;
try {
conn = DriverManager.getConnection(URL, USER, PASSWORD);
return conn;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
//关闭资源
public static void close(ResultSet rs, Statement ps, Connection conn) {
try {
if (Objects.nonNull(rs)) {
rs.close();
}
if (Objects.nonNull(ps)) {
ps.close();
}
if (Objects.nonNull(conn)) {
conn.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//更新操作的方法
public static int update(String sql, Object... params) throws SQLException {
PreparedStatement ps = null;
Connection conn = null;
int rs = -1;
try {
//获取连接
conn = getConn();
//获取用于执行sql命令的执行对象
ps = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
//执行
rs = ps.executeUpdate();
return rs;
} finally {
//关闭资源
close(null, ps, conn);
}
}
//查询操作的方法
public static List query(Class t, String sql, Object... params) {
List list = new ArrayList<>();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取连接
conn = getConn();
//获取用于执行sql命令的执行对象
ps = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
//执行
rs = ps.executeQuery();
//处理结果
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
while (rs.next()) {
//通过反射获取一个对象
T obj = t.newInstance();
//用反射为对象的属性赋值
for (int i = 1; i <= count; i++) {
//用反射通过属性名获取对象属性
Field field = t.getDeclaredField(metaData.getColumnLabel(i));
field.setAccessible(true);
//设置属性值
field.set(obj, rs.getObject(i));
}
//把对象放入集合中
list.add(obj);
}
return list.size() > 0 ? list : null;
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} finally {
//关闭资源
close(rs, ps, conn);
}
return null;
}
}
了解了Java代码怎么和数据库连接起来后,我们就可以通过Java代码对数据库进行操作,更新操作返回的是数据库中受影响的行数,查询操作,返回的是数据库中的数据,我们可以定义一个实体类当模板,让它的对象来接收保存数据库中的数据。
实体类TbStudent:TbStudent中的属性要和数据库中的对应,类型也要对应。
public class TbStudent {
private Integer sno;
private String sname;
private String ssex;
private Integer sage;
private String ssubject;}
DAO(数据访问对象):StudentDAO只是执行一些SQL语句没有逻辑操作。因为我查询单个学生信息用的是查询所有的学生信息的方法,这里我多做了一些判断。
public class StudentDAO {
//添加操作
public int insert(TbStudent s) throws SQLException {
String sql = "insert into tb_student values(?,?,?,?,?)";
return MyJDBC.update(
sql,
s.getSno(),
s.getSname(),
s.getSsex(),
s.getSage(),
s.getSsubject());
}
//删除操作
public int delete(Integer sno) throws SQLException {
String sql = "delete from tb_student where sno=?";
return MyJDBC.update(sql, sno);
}
//查询单个学生信息操作
public TbStudent selectFromID(Integer sno) {
String sql = "select * from tb_student where sno=?";
if (Objects.nonNull(MyJDBC.query(TbStudent.class, sql, sno))) {
return MyJDBC.query(TbStudent.class, sql, sno).get(0);
}
return null;
}
//查询所有学生信息操作
public List selectAll() {
String sql = "select * from tb_student";
return MyJDBC.query(TbStudent.class, sql);
}
//修改操作
public int update(TbStudent s) throws SQLException {
String sql = "update tb_student set ssubject=? where sno=?";
return MyJDBC.update(sql,
s.getSsubject(),
s.getSno());
}
}
业务逻辑StudentServer:执行逻辑判断,添加,删除和修改学生信息需要判断是否存在该学生。
public class StudentServer {
StudentDAO studentDAO = new StudentDAO();
//添加学生功能
public boolean addStu(TbStudent s) {
try {
//查询该学生是否存在
TbStudent stu = studentDAO.selectFromID(s.getSno());
if (Objects.nonNull(stu)) {
System.out.println("已经存在该名学生");
return false;
}
//添加功能
studentDAO.insert(s);
return true;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return false;
}
//根据学生学号删除学生功能
public boolean deleteStu(Integer sno) {
try {
//查询该学生是否存在
TbStudent stu = studentDAO.selectFromID(sno);
if (Objects.isNull(stu)) {
System.out.println("没有该名学生");
return false;
}
//删除功能
studentDAO.delete(sno);
return true;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return false;
}
//显示所有学生信息功能
public void showAllStu() {
List students = studentDAO.selectAll();
if (Objects.isNull(students)) {
System.out.println("没有学生信息");
}else {
students.forEach(System.out::println);
}
}
//根据学生学号修改学生学科功能
public boolean modifyStu(Integer sno, String major) {
try {
//查询该学生是否存在
TbStudent stu = studentDAO.selectFromID(sno);
if (Objects.isNull(stu)) {
System.out.println("没有该名学生");
return false;
}
TbStudent s = new TbStudent();
s.setSno(sno);
s.setSsubject(major);
//修改功能
studentDAO.update(s);
return true;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return false;
}
//根据学生学号显示学生信息功能
public boolean showStuFromID(Integer sno) {
TbStudent s = studentDAO.selectFromID(sno);
if (Objects.nonNull(s)) {
System.out.println(s);
return true;
}
return false;
}
}
测试
public class test {
static Scanner sc = new Scanner(System.in);
static StudentServer ss = new StudentServer();
private static void msg(String msg) {
System.out.println(msg);
}
private static void start() {
msg("======学生成绩管理系统=====");
msg("[1] 添加学生信息");
msg("[2] 学生信息列表");
msg("[3] 删除指定学生信息");
msg("[4] 查询指定学生信息");
msg("[5] 修改指定学生的学科");
msg("[0] 退出系统");
msg("========================");
msg("请输入指令:");
int i = sc.nextInt();
switch (i) {
case 1:
addStu();
break;
case 2:
showAll();
break;
case 3:
delStu();
break;
case 4:
showStuFromID();
break;
case 5:
modify();
break;
case 0:
msg("谢谢使用,再见!");
System.exit(0);
break;
default:
msg("指令错误,请重新输入");
start();
break;
}
}
/**
* 删除指定学号的学生信息
*/
private static void delStu() {
msg("输出你想删除的学生学号");
Integer sno = sc.nextInt();
if (ss.deleteStu(sno)) {
msg("删除成功");
} else {
msg("删除失败");
}
start();
}
/**
* 学生信息列表
*/
private static void showAll() {
ss.showAllStu();
start();
}
/**
* 添加学生信息
*/
private static void addStu() {
msg("请输入学号:");
Integer sno = sc.nextInt();
msg("请输入姓名");
String name = sc.next();
msg("请输入性别");
String sex = sc.next();
msg("请输入年龄");
Integer age = sc.nextInt();
msg("请输入学科");
String major = sc.next();
//根据读取的学生信息创建学生对象
TbStudent s = new TbStudent(sno, name, sex, age, major);
if (ss.addStu(s)) {
msg("添加成功");
} else {
msg("添加失败");
}
start();
}
/**
* 显示指定学号的学生信息
*/
private static void showStuFromID() {
msg("输出你想显示的学生学号");
Integer sno = sc.nextInt();
if (ss.showStuFromID(sno)) {
msg("显示成功");
} else {
msg("没有这名学生,显示失败");
}
start();
}
/**
* 修改指定学号学生的学科
*/
private static void modify() {
msg("输出你想修改的学生学号");
Integer sno = sc.nextInt();
msg("输出你想修改的学科");
String major = sc.next();
if (ss.modifyStu(sno, major)) {
msg("修改成功");
} else {
msg("没有这名学生,修改失败");
}
start();
}
public static void main(String[] args) {
start();
}
}
总结:基于数据库实现简单的学生管理系统中,我们掌握好用JDBC操作数据库的6大步骤和SQL语句,就能实现对数据库的操作。不过想要封装增删改的方法就需要对这6大步骤非常熟悉,查询方法简单的封装:我们可以不用考虑封装方法的通用性,不用泛型,固定数据类型,不用反射,直接根据实体类中的属性名来取对应的数据库中值。