JDBC多表联查

JDBC多表联查

在单一表进行查询时,只需要对表中的单个字段进行解析即可;例如下面代码:

@Overridepublic List<ClassBean> selectAllDao() {List list = new ArrayList();try {String sql = "select * from class";rs = select(sql);while(rs.next()) {ClassBean cb = new ClassBean();cb.setClassId(rs.getInt("classid"));cb.setClassName(rs.getString("classname"));list.add(cb);}} catch (Exception e) {e.printStackTrace();}finally {DaoUtil.closeResource(conn, statement, rs);}return list;}

在进行多表联查时会遇到第一个问题就是在实体类中不存在从表的字段,紧接着第二个问题在就是主表与从表的对应关系是一对一还是一对多关系。

以学生和班级表为例:从图中可以看出表对应关系

在这里插入图片描述

两个表的结构如下:

在这里插入图片描述
在这里插入图片描述

创建两个实体类:

student的实体类,加入外部属性,也就是引入class的属性,以为学生和班级是一对一的关系,因此只需要一个班级对象即可:

public class Student {private int sid;private String sname;private Date birthday;private String ssex;private int classId;	//外部属性private Banji bj;//get、set、构造器、toString方法省略
}

Banji表(class是Java关键字,所以用拼音)分析可知,一个班级里有多个学生,因此需要引入一个集合外部属性,用来存储班级中的多个学生:

public class Banji {private int classId;private String className;//外部属性private List<Student> stu;//get、set、构造器、toString方法省略
}

在这里将部分的代码进行了封装,形成了两个类:

DaoUtil工具类:

package com.li.dao;import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;public class DaoUtil {private static DataSource ds = null;static {try {FileInputStream stream = new FileInputStream("./src/druid.properties");		Properties pro = new Properties();pro.load(stream);			//创建连接			ds = DruidDataSourceFactory.createDataSource(pro);	}catch(Exception e) {e.printStackTrace();}}//创建连接对象方法public static Connection getConn() {Connection conn = null;try {conn = ds.getConnection();} catch (SQLException e) {e.printStackTrace();}return conn;}//关闭资源操作public static void closeResource(Connection conn,PreparedStatement prestatm, ResultSet rs) {if(conn != null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(prestatm != null) {try {prestatm.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(rs != null) {try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}

BaseDao工具类:

package com.li.dao;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;public class BaseDao {protected Connection conn;protected PreparedStatement prestatm;protected ResultSet rs;protected ResultSet query(String sql, Object ... arge) {ResultSet rs = null;try {conn = DaoUtil.getConn();prestatm  = conn.prepareStatement(sql);if(arge != null) {for(int i = 0; i< arge.length; i++) {prestatm.setObject(i+1, arge[i]);}}rs = prestatm.executeQuery();} catch (Exception e) {e.printStackTrace();}return rs;}
}

学生的实现类(接口省略):

package com.li.dao.impl;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;import com.li.bean.Banji;
import com.li.bean.Student;
import com.li.dao.BaseDao;
import com.li.dao.DaoUtil;
import com.li.dao.IStudentDao;public class StudentDaoImpl extends BaseDao implements IStudentDao{@Overridepublic List<Student> findAllStudent() {List<Student> list = new ArrayList();try {String sql = "select * from student left join class on student.classid = class.classid";rs = query(sql);while (rs.next()) {Student stu = new Student();Banji bj = new Banji();// 学生的数据stu.setBirthday(rs.getDate("birthday"));stu.setClassId(rs.getInt("classid"));stu.setSid(rs.getInt("sid"));stu.setSname(rs.getString("sname"));stu.setSsex(rs.getString("ssex"));//给班级属性赋值bj.setClassId(rs.getInt("classid"));bj.setClassName(rs.getString("classname"));//将班级对象赋值给班级中定义的实体类stu.setBj(bj);list.add(stu);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {DaoUtil.closeResource(conn, prestatm, rs);}return list;}}

班级的集合中存放班级编号等信息,班级编号的集合中又存放学生,就是集合中套集合:

在这里插入图片描述

Banji实现类(接口省略):

package com.li.dao.impl;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;import com.li.bean.Banji;
import com.li.bean.Student;
import com.li.dao.BaseDao;
import com.li.dao.DaoUtil;
import com.li.dao.IBanjiDao;public class BanjiDaoImpl extends BaseDao implements IBanjiDao{@Overridepublic List<Banji> findAllBanji() {List<Banji> blist = new ArrayList(); String sql = "select * from class left join student on class.classid = student.classid";rs = query(sql);try {while(rs.next()) {boolean falg = false;int index = -1;for(int i = 0; i <blist.size(); i++) {//判断班级集合中是否存在某字段的班级编号if(rs.getInt("classid") == blist.get(i).getClassId()) {falg =true;index = i;break;}}//已经存在班级集合if(falg) {Student stu =  new Student();stu.setBirthday(rs.getDate("birthday"));stu.setClassId(rs.getInt("classid"));stu.setSid(rs.getInt("sid"));stu.setSname(rs.getString("sname"));stu.setSsex(rs.getString("ssex"));Banji banji = blist.get(index);banji.getStu().add(stu);}//不存在班级集合else {//新建班级集合并放入List<Student> slist = new ArrayList();Banji bj = new Banji();bj.setClassId(rs.getInt("classId"));bj.setClassName(rs.getString("classname"));bj.setStu(slist);//新建学生类放入集合中Student stu =  new Student();stu.setBirthday(rs.getDate("birthday"));stu.setClassId(rs.getInt("classid"));stu.setSid(rs.getInt("sid"));stu.setSname(rs.getString("sname"));stu.setSsex(rs.getString("ssex"));slist.add(stu);blist.add(bj);}}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {DaoUtil.closeResource(conn, prestatm, rs);}return blist;}
}

测试类:

public static void main(String[] args) {IBanjiDao bjd = new BanjiDaoImpl();List<Banji> list = bjd.findAllBanji();IStudentDao sdi = new StudentDaoImpl();List<Student> list = sdi.findAllStudent();list.forEach(System.out::println);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235189.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring MVC 参数接收

参数接收 Springmvc中&#xff0c;接收页面提交的数据是通过方法形参来接收&#xff1a; 处理器适配器调用springmvc使用反射将前端提交的参数传递给controller方法的形参 springmvc接收的参数都是String类型&#xff0c;所以spirngmvc提供了很多converter&#xff08;转换器…

网络名称解读 -入门5

WAN: Wide Area Network(跨区域&#xff09;&#xff0c;LAN&#xff1a; Local Area NetworkWAN MAC&#xff0c; 用来连接上级网络&#xff0c; LAN MAC&#xff0c; 用于内部网路。 LAN & WAN 3.1&#xff0c;LAN表示子网&#xff0c;通过掩码来筛选子网内主机数量&…

Unity Delaunay三角剖分算法 动态生成

Unity Delaunay三角剖分算法 动态生成 Delaunay三角剖分Delaunay三角剖分 定义Delaunay 边Delaunay 空圆特性 Delaunay 三角形Delaunay 最大化最小角特性 Delaunay 三角形特征Delaunay 算法Delaunay Lawson算法Delaunay Bowyer-Watson算法 Unity Delaunay三角剖分 应用Unity 工…

Vulnhub-VULNCMS: 1渗透

文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、获取shell三、获取密码文件四、提权 一、前言 由于在做靶机的时候&#xff0c;涉及到的渗透思路是非常的广泛&#xff0c;所以在写文章的时候都是挑重点来写&#xff0c;尽量的不饶弯路。具体有…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -后端鉴权拦截器实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

邻接矩阵、可达性矩阵、完全关联矩阵、可达性矩阵的计算

邻接矩阵&#xff1a;很简单&#xff0c;就是两个点有关系就是1&#xff0c;没有关系就是0 可达性矩阵&#xff1a;非常简单&#xff0c;两点之间有路为1&#xff0c;没有路为0 可发行矩阵的计算&#xff1a;有n个元素&#xff0c;初始可达性矩阵为A&#xff0c;那么最终的矩阵…

K2P路由器刷OpenWrt官方最新版本固件OpenWrt 23.05.2方法 其他型号的智能路由器OpenWrt固件刷入方法也基本上适用

最近路由器在开机时总出问题,于是就那他来开刀,直接刷一个OpenWrt官方最新版本的固件, 刷其他第三方的固件总是觉得不安全, 而且很多第三方固件都带了些小工具,始终会有安全隐患, 而且占用内存空间太多,本来这个东西就没有多少内存,于是就干脆刷一个官方的原始固件(才6.3M, 相…

使用numpy处理图片——滤镜

大纲 3维数组切分打平重组法深度切分法 3维数组堆叠 我们在用手机拍照片时&#xff0c;往往会对照片进行滤镜处理&#xff0c;从而让照片更加美观。本文我们将实现几种滤镜效果——去除所有像素中的某一种原色&#xff0c;形成只有红绿、红蓝和绿蓝原色的照片。 为了突出色彩丰…

怎么投稿各大媒体网站?

怎么投稿各大媒体网站&#xff1f;这是很多写作者及自媒体从业者经常面临的问题。在信息爆炸的时代&#xff0c;如何将自己的文章推送到广大读者面前&#xff0c;成为了一个不可避免的挑战。本文将为大家介绍一种简单有效的投稿方法——媒介库发稿平台发稿&#xff0c;帮助大家…

可重入锁和不可重入锁

概念 Reentrant Re entrant&#xff0c;Re是重复、又、再的意思&#xff0c;entrant是enter的名词或者形容词形式&#xff0c;翻译为进入者或者可进入的&#xff0c;所以Reentrant翻译为可重复进入的、可再次进入的&#xff0c;因此ReentrantLock翻译为重入锁或者再入锁。 可…

SpringCloud微服务 【实用篇】| RabbitMQ快速入门、SpringAMQP

目录 一&#xff1a;初始RabbitMQ 1. 同步和异步通讯 1.1 同步调用 1.2 异步调用 2. MQ常见框架 二&#xff1a;RabbitMQ快速入门 1. RabbitMQ概述和安装 2. 常见消息队列模型 3. 快速入门案例 三&#xff1a;SpringAMQP 1. Basic Queue 简单队列模型 2. Work Queu…

尝试OmniverseFarm的最基础操作

目标 尝试OmniverseFarm的最基础操作。本地机器作为Queue和Agent&#xff0c;同时在本地提交任务。 主要参考了官方文档&#xff1a; Farm Queue — Omniverse Farm latest documentation Farm Agent — Omniverse Farm latest documentation Farm Examples — Omniverse Far…

遥感单通道图像保存为彩色图像

系列文章目录 第一章PIL单通道图像处理 文章目录 系列文章目录前言一、代码实现二、问题记录在这里插入图片描述 总结 前言 将单通道图像以彩色图像的形式进行保存主要使用了PIL库 一、代码实现 palette_data [***]&#xff1a;可以进行自定义设置 代码如下&#xff1a; fr…

docker微服务案例

文章目录 建立简单的springboot项目(boot3)boot2建立通过dockerfile发布微服务部署到docker容器编写Dockerfile打包成镜像运行镜像微服务 建立简单的springboot项目(boot3) 1.建立module 2. 改pom <?xml version"1.0" encoding"UTF-8"?> <…

Apache JMeter 5.5: 新手指南

如何获取并运行 JMeter 首先&#xff0c;要使用 JMeter&#xff0c;你需要从官网获取软件包。前往 Apache JMeter 的官方页面&#xff0c;然后下载所 需的压缩文件。 配置和启动 JMeter 获取了 JMeter 后&#xff0c;由于它是无需安装即可使用的工具&#xff0c;直接解压下载…

构建自己的私人GPT-支持中文

上一篇已经讲解了如何构建自己的私人GPT&#xff0c;这一篇主要讲如何让GPT支持中文。 privateGPT 本地部署目前只支持基于llama.cpp 的 gguf格式模型&#xff0c;GGUF 是 llama.cpp 团队于 2023 年 8 月 21 日推出的一种新格式。它是 GGML 的替代品&#xff0c;llama.cpp 不再…

PPT插件-大珩助手-选择同类

选择同类-颜色 对于选中的形状&#xff0c;一键选中当前页中的所有相同颜色的形状 选择同类-文本 一键选择当前页中的所有文本对象 选择同类-非文本 一键选择当前页中的所有非文本对象 选择同类-反选 一键选择当前页未选择的对象 软件介绍 PPT大珩助手是一款全新设计的…

TinyLog iOS v3.0接入文档

1.背景 为在线教育部提供高效、安全、易用的日志组件。 2.功能介绍 2.1 日志格式化 目前输出的日志格式如下&#xff1a; 日志级别/[YYYY-MM-DD HH:MM:SS MS] TinyLog-Tag: |线程| 代码文件名:行数|函数名|日志输出内容触发flush到文件的时机&#xff1a; 每15分钟定时触发…

groovy XmlParser 递归遍历 xml 文件,修改并保存

使用 groovy.util.XmlParser 解析 xml 文件&#xff0c;对文件进行修改&#xff08;新增标签&#xff09;&#xff0c;然后保存。 是不是 XmlParser 没有提供方法遍历每个节点&#xff0c;难道要自己写&#xff1f; 什么是递归&#xff1f; 不用说&#xff0c;想必都懂得~ …

如何通过兴趣爱好选职业?

一个错误的选择&#xff0c;可能造成终身的遗憾&#xff0c;一个正确的选择&#xff0c;可以让我们少奋斗几十年。所以无论现在付出多少代价&#xff0c;多花一些时间&#xff0c;去研究以下未来的职业方向&#xff0c;这是值得的。 职业定位&#xff08;专业定位&#xff09;…