猫哥带你去战斗—Java Web开发—Java篇[13]—联表操作
2017-02-21 16:52
435 查看
Java是面向对象的,关系数据库中的表的每一行代表一组数据且每一列数据含义相同。所以很容易就想到,Java中的一个对象可以对应到数据库表的一行元素,那么Java对象的每个属性就可以自然对应到数据库一行中的一列。
这样做是非常有意义的,因为最终要把数据库中的数据显示在网页上,还得先使用Java语言把数据库中的数据查询出来,然后放在Java对象里面,最后通过一些方式把Java对象里面的内容输出到网页上,是这么一个过程。
好的,如果是单独一张表,对应到一个Java类和对象,非常简单自然,本篇主要演示下多张表且表之间有关系的情况下,如何设计与使用Java类和对象。
首先准备三张表:学生信息表(student_info),班级信息表(class_info)和房间信息表(room_info) 。我们前提是这是一个小学哈,一个学生只属于一个班级,一个班级包含多个学生,一个班级固定在一个房间上下课。
OK,我们使用Navicat建立表后结构如下:
然后插入一些测试数据如下(可以先执行
猫哥希望大家能看出来,张三和李四是一年级一班的,教室在二楼201房间。
OK,可以设计类了,本篇的所有类和代码还是在sql包下,同一个包下的类可以直接访问比较方便哈哈。
首先设计跟表对应的类StudentInfo、ClassInfo、RoomInfo。如下:
OK,我们需要对这三个表进行增删改查操作,所以定义一个接口如下:
最后我们实现一个具体的操作类及演示:
OK,其他类的设计也是如此,到此我们实现了数据库连接池的使用、数据库操作类的使用、数据库表对象化的增删改查操作。
但是,大家好像也发现了,现在的代码非常的冗余,其实每个StudentOperation操作类里面的内容都是一样的,无外乎增删改查,那么有什么办法可以精简我们的操作,以实现程序设计避免重复的基本原则,且听下回分解。
这样做是非常有意义的,因为最终要把数据库中的数据显示在网页上,还得先使用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操作类里面的内容都是一样的,无外乎增删改查,那么有什么办法可以精简我们的操作,以实现程序设计避免重复的基本原则,且听下回分解。
相关文章推荐
- 猫哥带你去战斗—Java Web开发—Java篇[14]—数据库操作简化
- 猫哥带你去战斗——Java Web开发——Java篇[11]——数据库连接池
- 猫哥带你去战斗——Java Web开发——Java篇[5]——大王,有异常!
- 猫哥带你去战斗——Java Web开发——Java篇[4]——常用容器
- 猫哥带你去战斗——Java Web开发——Java篇[1]——从内存讲起
- 猫哥带你去战斗——Java Web开发——Java篇[7]——认识数据库
- 猫哥带你去战斗——Java Web开发——Java篇[3]——常用类型
- 猫哥带你去战斗——Java Web开发——Java篇[0]——小谈动态网页
- 猫哥带你去战斗——Java Web开发——Java篇[9]——使用SQL语句实现增删改查
- 猫哥带你去战斗—Java Web开发—Java篇[12]—使用连接池的MySQL操作类
- 猫哥带你去战斗——Java Web开发——Java篇[10]——static和鸡蛋
- 猫哥带你去战斗——Java Web开发——网页篇[6]——布局
- 猫哥带你去战斗——Java Web开发——开发环境介绍[2]
- 猫哥带你去战斗——Java Web开发——网页篇[2]——基本标签
- 猫哥带你去战斗—Java Web开发—Servlet篇[0]—Servlet是干嘛的
- 猫哥带你去战斗——Java Web开发——开发环境介绍[3]——图文安装流程
- 猫哥带你去战斗—Java Web开发—Servlet篇[3]—获取网页数据
- 猫哥带你去战斗——Java Web开发——网页篇[4]——表单
- 猫哥带你去战斗—Java Web开发—Servlet篇[1]—手(首)写Servlet
- 猫哥带你去战斗——Java Web开发——开发环境介绍[0]