Java Web开发–Java篇[13]–联表操作

Java是面向对象的,关系数据库中的表的每一行代表一组数据且每一列数据含义相同。所以很容易就想到,Java中的一个对象可以对应到数据库表的一行元素,那么Java对象的每个属性就可以自然对应到数据库一行中的一列。

这样做是非常有意义的,因为最终要把数据库中的数据显示在网页上,还得先使用Java语言把数据库中的数据查询出来,然后放在Java对象里面,最后通过一些方式把Java对象里面的内容输出到网页上,是这么一个过程。

好的,如果是单独一张表,对应到一个Java类和对象,非常简单自然,本篇主要演示下多张表且表之间有关系的情况下,如何设计与使用Java类和对象。

首先准备三张表:学生信息表(student_info),班级信息表(class_info)和房间信息表(room_info) 。我们前提是这是一个小学哈,一个学生只属于一个班级,一个班级包含多个学生,一个班级固定在一个房间上下课。

OK,我们使用Navicat建立表后结构如下:
这里写图片描述
然后插入一些测试数据如下(可以先执行truncate student_info语句将之前测试的student_info表数据清空):

INSERT INTO `class_info` VALUES ('1', '一年级一班', '1');
INSERT INTO `class_info` VALUES ('2', '一年级二班', '2');
INSERT INTO `class_info` VALUES ('3', '三年级四班', '3');
INSERT INTO `room_info` VALUES ('1', '二楼201房间');
INSERT INTO `room_info` VALUES ('2', '二楼202房间');
INSERT INTO `room_info` VALUES ('3', '三楼301房间');
INSERT INTO `student_info` VALUES ('1', '张三', '1');
INSERT INTO `student_info` VALUES ('2', '李四', '1');
INSERT INTO `student_info` VALUES ('3', '赵柳', '2');

猫哥希望大家能看出来,张三和李四是一年级一班的,教室在二楼201房间。

OK,可以设计类了,本篇的所有类和代码还是在sql包下,同一个包下的类可以直接访问比较方便哈哈。

首先设计跟表对应的类StudentInfo、ClassInfo、RoomInfo。如下:

package sql;
public class StudentInfo {
	private String studentId;
	private String studentName;
	private ClassInfo studentClass;//一个学生对应一个班级,所以此处直接写一个ClassInfo对象
	public String getStudentId() {
		return studentId;
	}
	public void setStudentId(String studentId) {
		this.studentId = studentId;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	public ClassInfo getStudentClass() {
		return studentClass;
	}
	public void setStudentClass(ClassInfo studentClass) {
		this.studentClass = studentClass;
	}
}
package sql;
import java.util.ArrayList;
public class ClassInfo {
	private String classId;
	private String className;
	private ArrayList<StudentInfo> classStudents;//一个班级包含多个学生,所以此处使用一个StudentInfo类型的列表
	private RoomInfo roomInfo;//一个班级对应一个房间,所以直接写一个RoomInfo对象
	public String getClassId() {
		return classId;
	}
	public void setClassId(String classId) {
		this.classId = classId;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	public ArrayList<StudentInfo> getClassStudents() {
		return classStudents;
	}
	public void setClassStudents(ArrayList<StudentInfo> classStudents) {
		this.classStudents = classStudents;
	}	
	public RoomInfo getRoomInfo() {
		return roomInfo;
	}
	public void setRoomInfo(RoomInfo roomInfo) {
		this.roomInfo = roomInfo;
	}
}
package sql;
public class RoomInfo {
	private String roomId;
	private String roomName;
	private ClassInfo classInfo;//一个房间对应一个班级
	public String getRoomId() {
		return roomId;
	}
	public void setRoomId(String roomId) {
		this.roomId = roomId;
	}
	public String getRoomName() {
		return roomName;
	}
	public void setRoomName(String roomName) {
		this.roomName = roomName;
	}
	public ClassInfo getClassInfo() {
		return classInfo;
	}
	public void setClassInfo(ClassInfo classInfo) {
		this.classInfo = classInfo;
	}
}

OK,我们需要对这三个表进行增删改查操作,所以定义一个接口如下:

package sql;
import java.util.List;
public interface ObjectOperation {//对象操作接口,用于执行数据库中对象对应表的增删改查操作
	public List selectAll();//选取表中所有数据
	public Object selectById(String id);//按id获取一条记录
	public int add(Object obj);//添加数据
	public int deleteById(String id);//按id删除一条记录
	public int update(Object obj);//按obj对象的信息修改一条记录
}

最后我们实现一个具体的操作类及演示:

package sql;
import java.sql.*;
import java.util.*;
public class StudentOperation implements ObjectOperation{//继承ObjectOperation接口,说明遵循ObjectOperation定义的规范,或者说具备ObjectOperation家族遗传的特点
	@Override//重写方法
	public List selectAll() {
		MysqlHandler hand=new MysqlHandler();
		ResultSet rs=null;
		ArrayList<StudentInfo> students=new ArrayList<StudentInfo>();//返回值
		try {
			//此处可看到我们只关联了class_info的id和name,没有继续关联到RoomInfo,这个是看具体需求来设计的
			//一般来说去到第二层的字段就够用了
			rs=hand.query("select * from student_info s,class_info c where s.student_class_id=c.class_id");
			while(rs.next()){
				StudentInfo stu=new StudentInfo();//返回值中的一个
				ClassInfo cla=new ClassInfo();//StudentInfo对象还包含一个ClassInfo对象
				cla.setClassId(rs.getString("class_id"));
				cla.setClassName(rs.getString("class_name"));
				stu.setStudentId(rs.getString("student_id"));
				stu.setStudentName(rs.getString("student_name"));
				stu.setStudentClass(cla);
				students.add(stu);//添加到列表
			}
			hand.sayGoodbye();//释放资源
			return students;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	@Override
	public Object selectById(String id) {
		MysqlHandler hand=new MysqlHandler();
		ResultSet rs=null;
		StudentInfo stu=new StudentInfo();
		try {
			rs=hand.query("select * from student_info s,class_info c where s.student_class_id=c.class_id and s.student_id='"+id+"'");
			while(rs.next()){
				ClassInfo cla=new ClassInfo();
				cla.setClassId(rs.getString("class_id"));
				cla.setClassName(rs.getString("class_name"));
				stu.setStudentId(rs.getString("student_id"));
				stu.setStudentName(rs.getString("student_name"));
				stu.setStudentClass(cla);
			}
			hand.sayGoodbye();
			return stu;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	@Override
	public int add(Object obj) {
		StudentInfo stu=(StudentInfo)obj;//类型转换,其实此处应该加try{}以防转换失败,此处为了简明扼要省略
		MysqlHandler hand=new MysqlHandler();
		try {
			//此处关联的ClassInfo我们只插入了id,因为按照逻辑一般是先有了班级,然后班级里面添加学生
			//所以学生信息添加的时候只需要设定他属于哪个班级就行了
			int re=hand.execute("insert into student_info(student_name,student_class_id) values('"+stu.getStudentName()+"','"+stu.getStudentClass().getClassId()+"')");
			hand.sayGoodbye();
			return re;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	@Override
	public int deleteById(String id) {
		MysqlHandler hand=new MysqlHandler();
		try {
			//删除学生信息比较简单
			//如果是删除班级信息呢?班级里面还有学生怎么办?所以稍微复杂点,此处跟数据库设计关系比较大,本篇暂不涉及
			int re=hand.execute("delete from student_info where student_id='"+id+"'");
			hand.sayGoodbye();
			return re;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	@Override
	public int update(Object obj) {
		StudentInfo stu=(StudentInfo)obj;
		MysqlHandler hand=new MysqlHandler();
		try {
			//以id选定记录,按stu里面的内容修改
			int re=hand.execute("update student_info set student_name='"+stu.getStudentName()+"',student_class_id='"
					+stu.getStudentClass().getClassId()+"' where student_id='"+stu.getStudentId()+"'");
			hand.sayGoodbye();
			return re;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	public static void main(String[] args) {//测试
		StudentOperation stuOper=new StudentOperation();
		//查询全部
		show();
		//删除
		stuOper.deleteById("1");
		show();
		//修改
		StudentInfo stu=(StudentInfo)stuOper.selectById("2");//查询特定一个
		stu.setStudentName("火星人");
		stuOper.update(stu);
		show();
		//添加
		ClassInfo cla=new ClassInfo();
		cla.setClassId("1");
		StudentInfo stuForAdd=new StudentInfo();
		stuForAdd.setStudentName("霸王龙");
		stuForAdd.setStudentClass(cla);
		stuOper.add(stuForAdd);
		show();
		
	}
	//查询
	public static void show(){
		StudentOperation stuOper=new StudentOperation();
		List students=stuOper.selectAll();
		for(Object obj:students){
			StudentInfo stu=(StudentInfo)obj;
			System.out.println("姓名:"+stu.getStudentName()+" 班级:"+stu.getStudentClass().getClassName());
		}
	}
}

OK,其他类的设计也是如此,到此我们实现了数据库连接池的使用、数据库操作类的使用、数据库表对象化的增删改查操作。

但是,大家好像也发现了,现在的代码非常的冗余,其实每个StudentOperation操作类里面的内容都是一样的,无外乎增删改查,那么有什么办法可以精简我们的操作,以实现程序设计避免重复的基本原则,且听下回分解。


如有问题请扫码联系我
在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页