Java Web简明教程–Java篇[13]–联表操作

简介: 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 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 getClassStudents() {
  return classStudents;
    }
    public void setClassStudents(ArrayList 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 students=new ArrayList();//返回值
  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操作类里面的内容都是一样的,无外乎增删改查,那么有什么办法可以精简我们的操作,以实现程序设计避免重复的基本原则,且听下回分解。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
SQL Java 关系型数据库
Java Web 简明教程
本教程用于介绍Java Web开发入门的方方面面,包括开发环境、工具、网页、Java、数据库等。
175 0
|
Java 数据库
Java Web简明教程–Servlet篇[6]–漂亮的终结篇
本篇是Java Web开发系列的最后一篇,接下来猫哥将开始《猫哥带你去战斗—使用JSP+Servlet开发培训班作业管理系统》,新的系列将承接Java Web开发,主要依赖HTML、Java、Servlet、JSP这些基本技术开发一个培训班作业管理系统。
110 0
|
前端开发 Java 程序员
Java Web简明教程–Servlet篇[5]–犀利的内置对象
前面几篇写的内容挺多挺乱,稍微理顺下: 1,网站无非是前后台交互 2,目前我们的后台可以认为是Servlet 3,前台可以认为是JSP和HTML 4,Servlet因为可以写out.println(" ");等输出到前台的html内容,所以一定程度上它的输出可以认为是前台。 5,JSP因为可以在<%%>中间写Java代码后台逻辑,所以可以当后台使用
104 0
|
SQL Java 关系型数据库
Java Web简明教程–Servlet篇[4]–JSP顺势而生
前一篇讲了利用HttpServletRequest可以获取网页请求相关的信息,之前我们已知道利用HttpServletResponse可以向网页返回(输出)信息。前一篇已经演示了获取网页请求中参数的方法,本篇就先来演示下Servlet如何响应网页的请求返回对应的信息给用户。
Java Web简明教程–Servlet篇[4]–JSP顺势而生
|
Java 关系型数据库 MySQL
Java Web简明教程–Servlet篇[3]–获取网页数据
上篇讲了网页可以通过get或post方式向Servlet抛出请求,有时候呢,请求是带参数的。比如网页端想查询三班所有学生姓名,那么这个请求传递给Servlet处理时候,就要携带一个“三班”的参数信息,Servlet根据"三班"来返回该班学生姓名。所以,本篇主要内容:
234 0
Java Web简明教程–Servlet篇[3]–获取网页数据
|
开发框架 安全 Java
Java Web简明教程–Servlet篇[2]–get与post
本篇主要涉及2个内容: 使用MyEclipse简化创建Servlet的过程 get与post请求的区别
165 0
Java Web简明教程–Servlet篇[2]–get与post
|
Java 应用服务中间件 开发者
Java Web简明教程–Servlet篇[1]–手(首)写Servlet
Java Web简明教程–Servlet篇[1]–手(首)写Servlet
176 0
Java Web简明教程–Servlet篇[1]–手(首)写Servlet
|
Java 数据库连接
Java Web简明教程–Servlet篇[0]–Servlet是干嘛的
Java Web简明教程–Servlet篇[0]–Servlet是干嘛的
128 0
|
存储 XML SQL
Java Web简明教程–Java篇[14]–数据库操作简化
Java Web简明教程–Java篇[14]–数据库操作简化
|
SQL 关系型数据库 MySQL
Java Web简明教程–Java篇[12]–使用连接池的MySQL操作类
Java Web简明教程–Java篇[12]–使用连接池的MySQL操作类
111 0
推荐文章
更多