当前位置: 首页 > 编程日记 > 正文

关于一对多,多对多的多表查询的控制

一、一对多

以班级Classes和学生Student为例:
回忆sql语句:

//内链接,两种方式效果一样,查询的是两边都有的数据
SELECT c.*,s.* FROM classes c,student s WHERE s.cid=c.cid;

SELECT c.cname,s.sname FROM classes c INNER JOIN student s ON s.cid=c.cid;

//左外连接,在内链接基础上,左边表有而右边表没有,两种方式等效;
SELECT c.* ,s.* FROM student s LEFT OUTER JOIN classes c ON s.cid=c.cid;
SELECT c.* ,s.* FROM student s LEFT  JOIN classes c ON s.cid=c.cid;

//右外连接,在内链接基础上,右边有而左边无,两种方式等效;
SELECT c.* ,s.* FROM classes c RIGHT  OUTER JOIN student s ON s.cid=c.cid;
SELECT c.* ,s.* FROM classes c RIGHT  JOIN student s ON s.cid=c.cid;
HQL语句:
//查询所有:
from Classes c,Student s where c.cid=s.classes.cid;
//选择某些属性查询
select c.cname,s.sname from Classes c,Student s where c.cid=s.classes.cid;
//选择某些属性,封装为bean查询;
select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname)  from Classes c,Student s where c.cid=s.classes.cid;
//内链接查询,得到的是两个bean
from Classes c inner join c.students s;
//内敛链接查询,得到的是Classes对象,对象中包含studet集合
from Classes c inner join fetch c.students s;
from Student s inner join fetch s.classes c;
select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname)  from Student s inner join  s.classes c ;
from Classes c left outer join fetch c.students s;
from Student s left outer join fetch s.classes;
示例代码:
/**
* 1.一对多
* sql:select c.*,s.* from classes c,student s where c.cid=s.cid;
* hql:from Classes c,Student s where c.cid=s.classes.cid,注意与上句的区别;
* 得到的list是object[],数组中的元素是Classes和Student对象;
*
*/
@Test
public void testOneToMany_EQ(){
Session   session = sessionFactory.openSession();
Query query = session.createQuery( "from Classes c,Student s where c.cid=s.classes.cid");
List list = query.list();
System. out.println(query.list().size());
session.close();
}
/**
* 2.带属性的查询;
* list中装的是object[];
*/
@Test
public void testOneToMany_EQ_Property(){
Session   session = sessionFactory.openSession();
Query query = session.createQuery( "select c.cname,s.sname from Classes c,Student s where c.cid=s.classes.cid");
query.list();
session.close();
}
/**
* 3.带属性查询,将查询结果封装成一个bean;
* 得到的list中装的是classView对象;
*/
@Test
public void testOneToMany_EQ_Property_Constructor(){
Session   session = sessionFactory.openSession();
Query query = session.createQuery( "select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname) " +
"from Classes c,Student s where c.cid=s.classes.cid");
List list = query.list();
session.close();
}
/**
* 4.内连接
* 结果与例子1一样;
*/
@Test
public void testOneToMany_InnerJoin_Query(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Classes c inner join c.students s");
Query query = session.createQuery(buffer.toString());
query.list();
session.close();
}
/**
* 5.迫切内连接1:获取所有有学生的班级及班级下的学生;
* 要想得到的集合中装的Classes对象,对象中set集合中装student,可以使用迫切内链接。
*
*/
@Test
public void testOneToMany_InnerJoin_Fetch_Query_1(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Classes c inner join fetch c.students s");
Query query = session.createQuery(buffer.toString());
List list = query.list();
session.close();
}
/**
* 6.迫切内连接2
* 从学生端出发;
*/
@Test
public void testOneToMany_InnerJoin_Fetch_Query_2(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Student s inner join fetch s.classes c");
Query query = session.createQuery(buffer.toString());
query.list();
session.close();
}
/**
* 7.迫切内连接3:获取属性,封装结果;
* select new cn.itheima03.hibernate.domain.ClassView(c.cname,s.sname)
*   from Student s inner join fetch s.classes c;
* 上述的 hql语句会报错,因为from后面想要的结构和select想要的结构是冲突的,所以
如果在from后面加fetch,不能写select语句,如果加select,不能写fetch,两者只能选择其一
*
*/
@Test
public void testOneToMany_InnerJoin_Fetch_Query_Property(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
//下面的写法不对;
//        buffer.append("select new cn.itheima03.hibernate.domain.ClassView(c.cname,s.sname) " +
//                 " from Student s inner join fetch s.classes c");
//不要fetch;
buffer.append( "select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname)  " +
"  from Student s inner join  s.classes c " );
Query query = session.createQuery(buffer.toString());
List list = query.list();
session.close();
}
/**
* 8.迫切左外连接
* 从班级出发,得到班级对应的学生
*/
@Test
public void testOneToMany_LeftJoin_Fetch(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Classes c left outer join fetch c.students s");
Query query = session.createQuery(buffer.toString());
List<Classes> list = query.list();
for (Classes classes : list) {
System. out.println("classes:" +classes.getCname());
Set<Student> students = classes.getStudents();
for (Student student : students) {
System. out.println("     student:" +student.getSname());
}
}
session.close();
}
/**
* 9.迫切左外连接2
* 从学生出发,得到对应的班级
*/
@Test
public void testOneToMany_RightJoin_Fetch(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Student s left outer join fetch s.classes ");
Query query = session.createQuery(buffer.toString());
List<Student> list = query.list();
for (Student student : list) {
System. out.println("student:" +student.getSname());
if (student.getClasses()!=null) {
System. out.println("     " +student.getClasses().getCname());
}
}
session.close();
}
二。多对多
学生Student和课程Course为例:
Student里有装Course的set集合,Course里也有装Student的set集合;
多对多与一对多操作差不多
/**
* 1.得到所有的学生以及其对应的课程
* 从学生端出发
* list装的是学生;
*/
@Test
public void testManyToMany_LeftJoin_Fecth(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Student s left outer join fetch s.courses");
Query query = session.createQuery(buffer.toString());
List list = query.list();
session.close();
}
/**
* 2.得到所有的课程及课程下对应的学生;
* list装的是课程
*/
@Test
public void testManyToMany_LeftJoin_Fecth_2(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Course c left outer join fetch c.students s");
Query query = session.createQuery(buffer.toString());
query.list();
session.close();
}
/**
* 3.一对多和多对多的结合
* 得到所有班级下的所有学生以及所有学生下的所有课程;
* 从班级出发
*/
@Test
public void testManyToManyAndOneToMany(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Classes c left outer join fetch" +
" c.students s left outer join fetch s.courses");
Query query = session.createQuery(buffer.toString());
List<Classes> classeList = query.list();
//去掉集合中的重复元素
Set<Classes> sets = new HashSet<Classes>(classeList);
classeList = new ArrayList<Classes>(sets);
System. out.println(classeList.size());
for(Classes classes:classeList){//遍历班级
System. out.println(classes.getCname());
Set<Student> students = classes.getStudents();//得到班级下的学生
for(Student student:students){//遍历学生
System. out.println(student.getSname());
Set<Course> courses = student.getCourses();
for(Course course:courses){//遍历学生下的课程
System. out.println(course.getCname());
}
}
}
session.close();
}
/**
* 从中间表出发,班级有学生,学生修课程,故从学生角度出发进行查询;
*/
@Test
public void testManyToManyAndOneToMany_2(){
Session   session = sessionFactory.openSession();
StringBuffer buffer = new StringBuffer();
buffer.append( "from Student s left outer join fetch s.classes c
left outer join fetch s.courses cc");
Query query = session.createQuery(buffer.toString());
List<Student> studentList = query.list();
for(Student student:studentList){
System. out.println(student.getSname());
Classes classes = student.getClasses();
System. out.println(classes.getCname());
Set<Course> courses = student.getCourses();
for(Course course:courses){
System. out.println(course.getCname());
}
}
session.close();
}
/*******************************************************************************/
/**
* 面向对象的查询
*/
@Test
public void testQueryCriteria(){
Session   session = sessionFactory.openSession();
List<Classes>  classesList = session.createCriteria(Classes.class).list() ;
System. out.println(classesList.size());
session.close();
}
@Test
public void testQueryCriteria_Where(){
Session   session = sessionFactory.openSession();
Classes classes = (Classes)session.createCriteria(Classes.class).add(Restrictions.eq("cid" , 1L)).uniqueResult();
System. out.println(classes.getCname());
session.close();
}
}
总结:
无论是一对多还是多对多,hql语句中含有fetch时,得到的list装的是From 后面的对象,对象中可能有相关联对象的集合或者对象;

转载于:https://www.cnblogs.com/master-zxc/p/6737021.html

相关文章:

JavaScript对象,方括号和算法

by Dmitri Grabov德米特里格拉波夫(Dmitri Grabov) JavaScript对象&#xff0c;方括号和算法 (JavaScript Objects, Square Brackets and Algorithms) One of the most powerful aspects of JavaScript is being able to dynamically refer to properties of objects. In this…

《Java 8 实战》(二)—— Lambda

Lambda表达式可以理解为简洁地表示可传递的匿名函数的一种方式&#xff1a;它没有名称&#xff0c;但它有参数列表/函数主体/返回类型&#xff0c;可能还有一个可以抛出的异常列表。 Lambda表达式由参数/箭头和主体组成&#xff1a; (Apple a1, Apple a2) -> a1.getWeight(…

c++回调函数 callback

&#xff08;1&#xff09;Callback方式Callback的本质是设置一个函数指针进去&#xff0c;然后在需要需要触发某个事件时调用该方法, 比如Windows的窗口消息处理函数就是这种类型。比如下面的示例代码&#xff0c;我们在Download完成时需要触发一个通知外面的事件&#xff1a;…

【微信小程序之画布】终:手指触摸画板实现

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 先看效果图&#xff1a; wxml <!--pages/shouxieban/shouxieban.wxml--> <view class"container"><view>手写板&#xff08;请在下方区域手写内容&…

Android开发中应避免的重大错误

by Varun Barad由Varun Barad Android开发中应避免的重大错误 (Critical mistakes to avoid in Android development) As many pioneers and leaders in different fields have paraphrased:正如许多不同领域的开拓者和领导人所说&#xff1a; In any endeavor, it is import…

机房收费系统(VB.NET)——超具体的报表制作过程

之前做机房收费系统用的报表是GridReport&#xff0c;这次VB.NET重构中用到了VisualStudio自带的报表控件。刚開始当然对这块功能非常不熟悉&#xff0c;只是探究了一段时间后还是把它做出来了。 以下把在VisualStudio&#xff08;我用的是VisualStudio2013&#xff0c;假设与您…

微信小程序实现画布自适应各种手机尺寸

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 解决的问题&#xff1a; 画布&#xff0c;动画等js里面的操作&#xff0c;默认是px而不是rpx, 无法根据手机屏幕自适应 达到的效果&#xff1a; 让画布&#xff0c;动画在不同分辨…

网易新闻首页实现

http://www.2cto.com/kf/201409/330299.html IOS后台运行机制详解&#xff08;二&#xff09; http://blog.csdn.net/enuola/article/details/9148691转载于:https://www.cnblogs.com/itlover2013/p/4403061.html

阿联酋gitex_航空公司网站不在乎您的隐私后续行动:阿联酋航空以以下方式回应我的文章:...

阿联酋gitexby Konark Modi通过Konark Modi 航空公司网站不在乎您的隐私后续行动&#xff1a;阿联酋航空对我的文章进行了全面否认 (Airline websites don’t care about your privacy follow-up: Emirates responds to my article with full-on denial) Yesterday, The Regis…

微信小程序把缓存的数组动态渲染到页面

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 代码实现的目的&#xff1a;当页面销毁的时候&#xff0c;页面的参数状态还是能够保存。 show_img函数实现&#xff1a; 创建一个数组保存到缓存&#xff0c;遍历缓存的list_stutas对…

Find Minimumd in Rotated Sorted Array

二分搜索查最小数&#xff0c;from mid to分别为区间的第一个&#xff0c;中位数&#xff0c;和最后一个数 if(from<mid&&mid<to)//顺序&#xff0c;第一个即为最小值 return from; if(from>mid)//发现逆序&#xff0c;则最小值在这个区间&#xff0c;2分搜索…

在DataTable中更新、删除数据

在DataTable中选择记录 /*在DataTable中选择记录*//* 向DataTable中插入记录如上&#xff0c;更新和删除如下:* ----但是在更新和删除前&#xff0c;首先要找出要更新和删除的记录。* 一种方法是遍历DataRow&#xff0c;搜索想要的记录&#xff0c;* --〉然而更聪明的办法是使用…

使用TensorFlow进行机器学习即服务

by Kirill Dubovikov通过基里尔杜博维科夫(Kirill Dubovikov) 使用TensorFlow进行机器学习即服务 (Machine Learning as a Service with TensorFlow) Imagine this: you’ve gotten aboard the AI Hype Train and decided to develop an app which will analyze the effective…

浏览器加载、解析、渲染的过程

最近在学习性能优化&#xff0c;学习了雅虎军规 &#xff0c;可是觉着有点云里雾里的&#xff0c;因为里面有些东西虽然自己也一直在使用&#xff0c;但是感觉不太明白所以然&#xff0c;比如减少DNS查询&#xff0c;css和js文件的顺序。所以就花了时间去了解浏览器的工作&…

《转》java设计模式--工厂方法模式(Factory Method)

本文转自&#xff1a;http://www.cnblogs.com/archimedes/p/java-factory-method-pattern.html 工厂方法模式&#xff08;别名&#xff1a;虚拟构造&#xff09; 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类…

微信小程序去除左上角返回的按钮

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 解决方法有两种&#xff1b; 1.把该页面设置为tab页面或者主页 ; 2.进入该页面使用 wx.reLaunch(); 示例 wx.reLaunch({url: ../detail/detail,}) 这样有一个弊端&#xff0c;就是…

我的第一个web_登陆我的第一个全栈Web开发人员职位

我的第一个webby Robert Cooper罗伯特库珀(Robert Cooper) 登陆我的第一个全栈Web开发人员职位 (Landing My First Full Stack Web Developer Job) This is the story of the steps I took to get my first job as a full stack web developer. I think it’s valuable to sha…

HTTP请求报文和HTTP响应报文(转)

原文地址&#xff1a;http://blog.csdn.net/zhangliang_571/article/details/23508953 HTTP报文是面向文本的&#xff0c;报文中的每一个字段都是一些ASCII码串&#xff0c;各个字段的长度是不确定的。HTTP有两类报文&#xff1a;请求报文和响应报文。 HTTP请求报文 一个HTTP请…

微信小程序用户未授权bug解决方法,微信小程序获取用户信息失败解决方法

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; bug示例图&#xff1a; 导致这个bug的原因是 wx.getUserInfo(OBJECT) 接口做了调整&#xff1b; 请看官方文档的描述&#xff1a; wx.getUserInfo(OBJECT) 注意&#xff1a;此接口有…

格式化json日期'/Date(-62135596800000)/'

日期经过json序列化之后&#xff0c;变成了/Date(-62135596800000)/字符串&#xff0c;在显示数据时&#xff0c;我们需要解释成正常的日期。 Insus.NET和js库中&#xff0c;写了一个jQuery扩展方法&#xff1a; $.extend({JsonDateParse: function (value) {if (value /Date(…

aws lambda使用_使用AWS Lambda安排Slack消息

aws lambda使用Migrating to serverless brings a lot of questions. How do you do some of the non-serverless tasks, such as a cronjob in a serverless application?迁移到无服务器带来了很多问题。 您如何执行一些非无服务器的任务&#xff0c;例如无服务器应用程序中的…

微信小程序模块化开发 include与模板开发 template

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 1. include 是引用整个wxml文件&#xff0c;我通常会配合js&#xff0c;css一起使用&#xff1b; 使用场景&#xff0c;需要封装事件和微信 api 的公共模块。 2.template &#xff…

winform解析json

在使用C#开发爬虫程序时&#xff0c;会遇到需要解析json字符串的情况。对于json字符串可以使用正则表达式的形式进行解析&#xff0c;更为方便的方法是使用Newtonsoft.Json来实现。 Nuget添加应用包 在工程上右键——【管理Nuget程序包】浏览找到要安装的程序包Newtonsoft.Jso…

Oracle11g密码忘记处理方法

c:\>sqlplus /nolog sql>connect / as sysdba sql>alter user 用户名 identified by 密码;&#xff08;注意在这里输入的密码是区分大小写的&#xff09; 改完之后你可以输入 sql>connect 用户名/密码 as sysdba进行验证 转载于:https://www.cnblogs.com/imhuanxi…

hic染色体构想_了解微服务:从构想到起点

hic染色体构想by Michael Douglass迈克尔道格拉斯(Michael Douglass) 了解微服务&#xff1a;从构想到起点 (Understanding Microservices: From Idea To Starting Line) Over the last two months, I have invested most of my free time learning the complete ins-and-outs…

[python]关于字符串查找和re正则表达式的效率对比

最近需要在python中做大日志文件中做正则匹配 开始直接在for in 中每行做re.findall&#xff0c;后来发现&#xff0c;性能不行&#xff0c;就在re前面做一个基本的字符串包含判断 (str in str)&#xff0c;如果不包含直接continue 效率对比&#xff1a; 1、只做一次包含判断&a…

微信小程序客服功能 把当前页面的信息卡片发送给客服

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 需求&#xff1a;微信小程序客服带详情页 &#xff0c; 场景&#xff1a;一个人通过微信小程序接入微信客服&#xff0c;聊天后带上入口链接 效果图&#xff1a; 写法&#xff1a; …

phpcms标签大全V9

转自&#xff1a;http://blog.csdn.net/cloudday/article/details/7343448调用头部 尾部{template "content","header"} 、 {template "content","footer"}{siteurl($siteid)} 首页链接地址 <a href"{siteurl($siteid)}/&q…

多伦多到温莎_我想要freeCodeCamp Toronto的Twitter来发布报价,所以我做了一个免费的bot来做到这一点。...

多伦多到温莎If you read About time, you’ll know that I’m a big believer in spending time now on building things that save time in the future. To this end, I built a simple Twitter bot in Go that would occasionally post links to my articles and keep my ac…

Linux常用命令汇总(持续更新中)

命令说明注意点cat access.log | wc -l统计行数awk命令可以做到同样的想过&#xff1a;cat access.log | awk END {print NR}grep vnc /var/log/messages查看系统报错日志等同于&#xff1a;sudo dmesg -T | grep "(java)"netstat -lnt | grep 590*查看端口状态 nets…