session.load(Class<T> cls,id)
就是这个原理
在一对一的关系中默认使用的不是延迟加载,而是饿汉式的加载方式(EAGER),即是查询一个对象,并且也会随之查询另外一个对象的数据,发出的 sql
语句是左外连接查询
使用懒加载可以减轻数据库服务器的压力,只有当用到数据的时候才会发出 select
语句查询
我们可以使用 @OneToOne(fetch=FetchType.LAZY)
其中的fetch有两个值,一个是 FetchType.LAZY
(懒加载),一个是 FetchType.EAGER
(饿汉式)
Student
和 Teacher
类 由于是默认的就是饿汉式的查询方式,因此不需要改变实体类
测试方法
我们根据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(); } } }
@OneToOne
都设置 fetch
属性的值为懒加载
如果是 @ManyToOne
的方式,那么默认的就是 EAGER
方式进行查找。当我们使用get语句查找Many的对象的时候,那么我们会看到发出的select语句其实也在查找作为其属性的One的那一方的信息,但是如果我们设置LAZY,那么使用get语句查找Many的时候将不会直接查找One的一方,而是在用到One的信息的时候才会发出select语句查找One的一方。可以提高性能,使用如下: @ManyToOne(fetch=FetchType.LAZY)
使用 @OneToMany
默认的 fetch
是 LAZY
,即是当查询One的一方的时候只是发出了查找One的一方的select语句。只有当调用其中的Many一方的对象的属性的时候才会发出select语句查询。
懒加载(LAZY)
@ManyToMany(fetch=FetchType.EAGER)
,这里就不在演示了 @ManyToMany
注解中设置属性