Hibernate进阶之如何使用Hql内连接,外连接以及自连接

Hibernate进阶之如何使用Hql内连接,外连接以及自连接

一、sql语句中的 内连接、自连接和外连接:

1、使用等值连接/内连接查询,查询客户姓名,订单编号,订单价格
等值连接/内连接:只能查询出符合条件的记录:
select c.name,o.orderno,o.price
from customers c,orders o
where c.id = o.customers_id; 

2、使用左外连接,按客户分组,查询每个客户的订单数:
select c.name,count(o.orderno)
from customers c left join orders o
on c.id = o.customers_id
group by c.name;

3、使用右外连接,按客户分组,查询每个客户的订单数:
select c.name,count(o.orderno)
from orders o right join customers c
on c.id = o.customers_id
group by c.name;

外连接:既能查询出符合条件的记录,同时不符合条件的记录也能查询出

4、等值连接语法:
select    字段
from      表名,表名 
where     等值连接条件;

外连接语法:
select    字段
from      表名1 left/right join 表名2
on        等值连接条件;
group by  字段

 

二、HQL实战:

1、使用等值连接查询,查询客户姓名,订单编号,订单价格:
    select c.name,o.orderno,o.price
    from Customer c join c.orderSet o
    where c.id = o.customer.id
2、使用左外连接,按客户分组,查询每个客户的姓名和订单数:
             select c.name,count(o.orderno)
             from Customer c left join c.orderSet o

             group  by c.name 

这里需要注意的是:左外链接中left join on后面跟着的条件省略不写,否则会报错,Hibernate会自动加上去,如果要添加条件可以使用with。

3、使用自连接,求出xx的老板是yy
    select a.name,b.name
    from  Emp a,Emp b 

    where a.mgr = b.id     

 

三、具体小案例:

首先写配置文件(CustomerOrder.hbm.xml,Emp.hbm.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="example.hql">
	<class name="Customer" table="customers">
		<id name="id" column="id" type="int">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name" type="string"></property>
		<property name="age" column="age" type="int"></property>
		<!-- set标签用于映射单向一对多
			name表示单方的关联属性
			table表示多方对应表的名字
			key-cloumn表示多方对应表的外键
			one-to-many-class表示单方关联属性中的每个元素的类型
		 -->
		 <set name="orderSet" table="orders" cascade="all" inverse="true">
		 	<key column="customers_id"></key>
		 	<one-to-many class="Order"/>
		 </set>
	</class>
	<!-- 映射类的多方 -->
	<class name="Order" table="Orders">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="orderNo" column="orderNo"></property>
		<property name="price" column="price"></property>
		<many-to-one name="customer" column="customers_id"></many-to-one>
	</class>
	<query name="findCustomerByAge">
		<![CDATA[
			from Customer c where c.age>?
		]]>
	</query>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="example.hql">
	<class name="Emp" table="emps">
		<id name="id" column="id" type="int">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name" ></property>
		<property name="age" column="sal" ></property>
		<property name="age" column="mgr" ></property>
	</class>
</hibernate-mapping>

接下来写实体类Customer,Order,Emp员工类:

Customer:

package example.hql;
 
import java.util.LinkedHashSet;
import java.util.Set;
 
/**
 * 客户(一方)
 * @author Administrator
 *
 */
public class Customer {
 
	private Integer id;//对应表的主键
	private String name;
	private Integer age;
	private Set<Order> orderSet=new LinkedHashSet<Order>();//关联属性
	public Customer() {
	}
	public Customer(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Set<Order> getOrderSet() {
		return orderSet;
	}
	public void setOrderSet(Set<Order> orderSet) {
		this.orderSet = orderSet;
	}
	
}

Order类:

package example.hql;
/**
 * 订单(多的一方)
 * @author Administrator
 *
 */
public class Order {
 
	private Integer id;
	private String orderNo;//订单编号
	private Integer price;//价格
	private Customer customer;//关联的属性
	
	
	public Order(String orderNo, Integer price, Customer customer) {
		super();
		this.orderNo = orderNo;
		this.price = price;
		this.customer = customer;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Integer getPrice() {
		return price;
	}
	public void setPrice(Integer price) {
		this.price = price;
	}
	
	public String getOrderNo() {
		return orderNo;
	}
	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}
	public Order() {
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
}

Emp类:

package example.hql;
 
/**
 * 员工表
 * @author Administrator
 *
 */
public class Emp {
 
	private Integer id;
	private String name;
	private Integer sal;//薪水
	private Integer mgr;//直属领导编号
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getSal() {
		return sal;
	}
	public void setSal(Integer sal) {
		this.sal = sal;
	}
	public Integer getMgr() {
		return mgr;
	}
	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}
	public Emp() {
	}
	
	
}

最后实现内连接,外连接和自连接:

package example.hql;
 
import java.util.List;
 
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
 
import example.utils.HibernateUtils;
 
public class CustomerOrderDao2 {
 
	/**
	 * 使用等值连接查询,查询客户姓名,订单编号,订单价格
	 */
	@Test
	public void test01(){
		Session session=HibernateUtils.getSession();
		Transaction t=session.getTransaction();
		try{
			t.begin();
			String hql="select c.name,o.orderNo,o.price from Customer c join c.orderSet o where c.id=o.customer.id";
			Query query=session.createQuery(hql);
			List<Object[]> list= (List<Object[]>) query.list();
			//对象导航查询
			for(Object[] o:list){
				System.out.println(o[0]+","+o[1]);
			}
			t.commit();
		}catch (Exception e) {
			e.printStackTrace();
			t.rollback();
		}finally{
			HibernateUtils.closeSession();
		}
	}
	
	/**
	 *使用左外连接,按客户分组,查询每个客户的姓名和订单数
	 */
	@Test
	public void test02(){
		Session session=HibernateUtils.getSession();
		Transaction t=session.getTransaction();
		try{
			t.begin();
			String hql="select c.name,count(o.orderNo) from Customer c left join c.orderSet o group by c.name";
			Query query=session.createQuery(hql);
			List<Object[]> list= (List<Object[]>) query.list();
			//对象导航查询
			for(Object[] o:list){
				System.out.println(o[0]+","+o[1]);
			}
			t.commit();
		}catch (Exception e) {
			e.printStackTrace();
			t.rollback();
		}finally{
			HibernateUtils.closeSession();
		}
	}
	/**
	 *使用自连接,求出xx的老板是yy
	 */
	@Test
	public void test03(){
		Session session=HibernateUtils.getSession();
		Transaction t=session.getTransaction();
		try{
			t.begin();
			String hql="select e1.name,e2.name from Emp e1,Emp e2 where e1.mgr=e2.id";
			Query query=session.createQuery(hql);
			List<Object[]> list= (List<Object[]>) query.list();
			//对象导航查询
			for(Object[] o:list){
				System.out.println(o[0]+","+o[1]);
			}
			t.commit();
		}catch (Exception e) {
			e.printStackTrace();
			t.rollback();
		}finally{
			HibernateUtils.closeSession();
		}
	}
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114712.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • NAT配置实验_隧道模型受力及模型实验理解和认识

    NAT配置实验_隧道模型受力及模型实验理解和认识Iodine介绍Iodine,直译过来就是碘。碘元素在元素周期表中序号为53,正好是DNS使用的端口号。该工具用于建立DNS隧道,其分为服务端和客户端两部分(也常称为主控端和被控端),客户端对服务器端发送DNS请求建立连接。这两部分都是用C语言编写,支持EDNS、base32、base64、base128等多种编码规范。DNS隧道常分为中继和直连两种类型,中继是指DNS通过外网DNS服务器转发到服务端,直连是指直接通过服务端IP进行连接。Iodine对这两种类型都有支持。同时,Iodine支持多种DN

    2022年10月24日
  • python进阶(22)pydantic–数据类型校验

    python进阶(22)pydantic–数据类型校验pydantic库的作用pydantic库是一种常用的用于数据接口schema定义与检查的库。Pydantic在运行时强制执行类型提示,并在数据无效时提供用户友好的错误信息。pydantic安

    2022年7月30日
  • Android开发:用adb命令安装apk到手机

    Android开发:用adb命令安装apk到手机一、首先需要准备一个apk以及真机(我们以真机为例,就不说明模拟器了),然后adbdevices查看手机是否连接,直接输入adbdevices即可,如图:显示上图信息,说明连接成功,就可以推送安装apk了。如果出现下图,则可参照https://blog.csdn.net/y201314an/article/details/81022556进行修改环境变量…

    2022年4月29日
  • element级联选择器表单回显_级联选择器 数据回显

    element级联选择器表单回显_级联选择器 数据回显关于element级联选择器数据回显问题

    2022年4月21日
  • PCIe卡的主要引脚 及 热插拔

    PCIe卡的主要引脚 及 热插拔目录1PCIe总线使用的信号1.1收发数据信号1.2辅助信号2热插拔参考资料1PCIe总线使用的信号PCIex1,x4,x8,x16卡的连接器引脚如下图所示,数据收发引脚为白色,辅助引脚为灰色:mechanicalkey对应防呆缺口的位置。1.1收发数据信号PCIe总线的层次分层图:与收发数据相关的线就是每个通路(lane)的两对差分传输线。PCIex1,x2,x4,x8,x16分别代表有1,2,4,8,16条lane。1.2辅助信号在连接器上提供辅助引脚来辅助

    2022年5月7日
  • 快捷方式图标显示不正常_win10快捷方式不显示图标

    快捷方式图标显示不正常_win10快捷方式不显示图标win10系统的电脑近期遇到一个问题,那就是桌面上或者某磁盘中文件夹的程序快捷方式图标丢失显示异常,部分程序为一个白纸图标,不显示原本的程序图标,但是这些软件或者游戏的快捷方式能正常打开。那么游戏、软件等应用程序快捷方式不显示图标怎么办?下面装机之家分享一下Win10快捷方式图标变白纸解决方法。原因分析:在Win10系统中,首次对图标进行显示,为了加速图标的显示,之后系统会对图标进行缓存,如果缓存…

    2022年10月18日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号