专栏首页码猿技术专栏Hibernate关联查询

Hibernate关联查询

文章目录

  1. 1. Hibernate关联查询
    1. 1.1. 关联查询之延迟加载(lazy)
      1. 1.1.1. 什么是延迟加载
      2. 1.1.2. 什么是关联查询的延迟加载
      3. 1.1.3. 一对一
        1. 1.1.3.1. 测试
          1. 1.1.3.1.1. 测试默认的情况(饿汉式的加载)
          2. 1.1.3.1.2. 测试懒加载
        2. 1.1.3.2. 总结
      4. 1.1.4. 一对多或者多对一
      5. 1.1.5. 多对多

Hibernate关联查询

关联查询之延迟加载(lazy)

什么是延迟加载

  • 前面单独讲过延迟加载就是在根据id查询获取的对象中只是有一个id的属性值,只有当使用其他属性的时候才会发出sql语句查询数据库,session.load(Class<T> cls,id)就是这个原理

什么是关联查询的延迟加载

  • 简单的说就是在关联关系中,根据id查询对象的时候仅仅发出sql语句查询的是当前的实体类的表,并没有查询另外一张表的数据,只有当需要使用另外一张表的对象中的属性时才会发出sql语句查询另外一张表

一对一

  • 在一对一的关系中默认使用的不是延迟加载,而是饿汉式的加载方式(EAGER),即是查询一个对象,并且也会随之查询另外一个对象的数据,发出的sql语句是左外连接查询
  • 使用懒加载可以减轻数据库服务器的压力,只有当用到数据的时候才会发出select语句查询
  • 我们可以使用@OneToOne(fetch=FetchType.LAZY)其中的fetch有两个值,一个是FetchType.LAZY(懒加载),一个是FetchType.EAGER(饿汉式)

测试

  • 使用前面讲过的StudentTeacher
测试默认的情况(饿汉式的加载)
  • 由于是默认的就是饿汉式的查询方式,因此不需要改变实体类
  • 测试方法
    • 我们根据id查询husband的数据,这里发出的sql语句是左外连接语句,相当于: select * from husband h left join wife w on h.wifeid=w.id where h.id=?
@Test
	public void Test1() {
		Session session = null;
		Transaction transaction = null;
		try {
			// 创建session
			session = HibernateUntil.getSession();
			// 开始事务
			transaction = session.beginTransaction();
			//查询id=1的husband数据,这里将会使用左外连接查询数据,直接联表查询
			Husband husband=session.get(Husband.class, 1);

			//获取Husband中的Wife对象属性
			Wife wife=husband.getWife();

			//输出wife的属性age的值,由于前面已经查询过了,因此这里不再发出sql语句
			System.out.println(wife.getAge());

			// 提交事务
			transaction.commit();
		} catch (Exception exception) {
			transaction.rollback(); // 事务回滚
		} finally {
			if (session!=null) {
				session.close();
			}
		}
测试懒加载
  • 需要在@OneToOne注解中添加fetch属性,我们测试单向外键关联的懒加载(通过Husband类访问Wife的信息)
  • Husband类,使用懒加载
@Entity   //指定实体类
@Table(name="husband")   //指定对应数据库的表名为husband
public class Husband {
	private int id;
	private String name;
	private int age;
	private Wife wife;   //Wife对象
	@Id
	@GeneratedValue   //主键生成策略,自增长
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@OneToOne(fetch=FetchType.LAZY)   //设置wife的主键为Husband的外键,默认的对应表中的字段为wife_id
	@JoinColumn(name="wifeid") // 默认外键的名字为wife_id.我们使用这个注解改变外键的名字为wifeid
	public Wife getWife() {
		return this.wife;
	}
	public void setWife(Wife wife) {
		this.wife = wife;
	}
	@Column(length=20)   //设置长度为20
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Husband [id=" + id + ", name=" + name + ", age=" + age
				+ ", Wife=" + this.wife + "]";
	}
}
  • 测试方法
@Test
	public void Test1() {
		Session session = null;
		Transaction transaction = null;
		try {
			// 创建session
			session = HibernateUntil.getSession();
			// 开始事务
			transaction = session.beginTransaction();
			//查询id=1的husband数据,这里使用懒加载,只会查找husband的表,并不会联表查询
			Husband husband=session.get(Husband.class, 1);

			//获取Husband中的Wife对象属性,此处依然没有查询wife表
			Wife wife=husband.getWife();

			//输出wife的属性age的值,此处发出sql语句查询wife表,验证了只有当用到的wife属性的时候才会发出查询语句
			System.out.println(wife.getAge());

			// 提交事务
			transaction.commit();
		} catch (Exception exception) {
			transaction.rollback(); // 事务回滚
		} finally {
			if (session!=null) {
				session.close();
			}
		}
	}

总结

  1. 默认使用的饿汉式的查询方式,因此在访问数据量过大的时候,我们可以设置懒加载的方式
  2. 如果是双向外键关联的关系,我们可以在两个@OneToOne都设置fetch属性的值为懒加载

一对多或者多对一

  • 如果是@ManyToOne的方式,那么默认的就是EAGER方式进行查找。当我们使用get语句查找Many的对象的时候,那么我们会看到发出的select语句其实也在查找作为其属性的One的那一方的信息,但是如果我们设置LAZY,那么使用get语句查找Many的时候将不会直接查找One的一方,而是在用到One的信息的时候才会发出select语句查找One的一方。可以提高性能,使用如下:@ManyToOne(fetch=FetchType.LAZY)
  • 使用@OneToMany默认的fetchLAZY,即是当查询One的一方的时候只是发出了查找One的一方的select语句。只有当调用其中的Many一方的对象的属性的时候才会发出select语句查询。

多对多

  • 多对多的关联查询默认使用的懒加载(LAZY)
  • 如果想要设置饿汉式加载,可以使用@ManyToMany(fetch=FetchType.EAGER),这里就不在演示了
  • 如果在双向外键关联中都要饿汉式加载,那么可以在两个@ManyToMany注解中设置属性

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Hibernate常用API

    爱撒谎的男孩
  • SpringBoot整合Spring-data-jpa

    爱撒谎的男孩
  • 跳跃链表

    爱撒谎的男孩
  • R 热图绘制heatmap①

    用户1359560
  • cssjshtml vue.js if else-if show

    葫芦
  • 私有PaaS在乐视的实践

    PaaS在云平台中的作用 * 打通接入层、应用层、服务层 * 承载了云平台95%以上的业务

    字母哥博客
  • 斯坦福大学使用机器学习做次季节温度/降水预报

    文章下载地址: https://arxiv.org/pdf/1809.07394.pdf

    zhangqibot
  • 善用API统一描述语言提升RestAPI开发效率

    团队内部RestAPI开发采用设计驱动开发的模式,即使用API设计文档解耦前端和后端的开发过程,双方只在联调与测试时耦合。在实际开发和与前端合作的过程中,受限于...

    貟王軍
  • Java 类加载机制详解

    Java 虚拟机一般使用 Java 类的流程为:首先将开发者编写的 Java 源代码(.java文件)编译成 Java 字节码(.class文件),然后类加载器...

    哲洛不闹
  • Javascript判断图片加载是否成功的方法(转)

    在做页面的时候,经常碰到要在页面加载完全之后再去展现。这时候我们会直接想到使用window.onload的方式,或者是采用Jquery的ready方法判断,这在...

    山河木马

扫码关注云+社区

领取腾讯云代金券