前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hibernate关联查询

Hibernate关联查询

作者头像
爱撒谎的男孩
发布2019-12-31 14:59:40
1.3K0
发布2019-12-31 14:59:40
举报
文章被收录于专栏:码猿技术专栏

文章目录

  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=?
代码语言:javascript
复制
@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类,使用懒加载
代码语言:javascript
复制
@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 + "]";
	}
}
  • 测试方法
代码语言:javascript
复制
@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注解中设置属性
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Hibernate关联查询
    • 关联查询之延迟加载(lazy)
      • 什么是延迟加载
      • 什么是关联查询的延迟加载
      • 一对一
      • 一对多或者多对一
      • 多对多
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档