Hibernate第三天

Hibernate第三天
1.多表映射
1.1.多表映射的总则
问题:我们为什么要学习多表映射?
答:
在实际开发中,我们数据库的表难免会有相互的关联关系,在操作表的时候就有可能会涉及到多张表的操作。试想一下,如果把我们web阶段的在线商城案例的持久层改为hibernate的实现,我们现在根本无法实现功能。究其原因是我们在线商城中表之间都是有关联关系的。
例如:商品和分类,用户和订单,订单和商品等等。
而通过第一天的Hibernate框架学习,我们知道hibernate实现了ORM的思想,可以让我们通过操作实体类就实现对数据库表的操作。
所以今天我们的学习重点是:掌握配置实体之间的关联关系。
要想实现多表映射,我们现阶段需要遵循的步骤:
第一步:首先确定两张表之间的关系。
如果关系确定错了,后面做的所有操作就都不可能正确。
第二步:在数据库中实现两张表的关系
第三步:在实体类中描述出两个实体的关系
第四步:配置出实体类和数据库表的关系映射
配置的方式支持注解和XML,我们以注解为重点—需要确认。
思考:表之间的关系到底有几种呢?
1.2.表之间的关系划分
Hibernate框架实现了ORM的思想,将关系数据库中表的数据映射成对象,使开发人员把对数据库的操作转化为对对象的操作,Hibernate的关联关系映射主要包括多表的映射配置、数据的增加、删除等。
数据库中多表之间存在着三种关系,也就是系统设计中的三种实体关系。如图所示。

从图可以看出,系统设计的三种实体关系分别为:多对多、一对多和一对一关系。
注意:
一对多关系可以看为两种: 即一对多,多对一。所以说四种更精确。
明确:
我们只涉及实际开发中常用的关联关系,一对多和多对多。而一对一的情况,在实际开发中几乎不用。
2.一对多关系映射
2.1.示例分析
我们采用的示例为CRM中的客户和联系人。
客户:通常情况下客户指的是一家公司。
联系人:一般都是指客户的员工。
在不考虑兼职的情况下,客户和联系人的关系即为一对多。
2.2.表关系建立
在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表。在数据库中建立一对多的关系,需要使用数据库的外键约束。
什么是外键?
指的是从表中有一列,取值参照主表的主键,这一列就是外键。
一对多数据库关系的建立,如下图所示:

2.3.实体类关系建立
客户实体类
/**

  • 客户实体类

  • @author kevin
    */
    public class Customer implements Serializable{

    private static final long serialVersionUID = 1L;
    private Long cust_id;
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_address;
    private String cust_phone;

    //一对多关系映射:一个客户对应多个联系人
    private Set linkMans = new HashSet();

    public Long getCust_id() {
    return cust_id;
    }
    public void setCust_id(Long cust_id) {
    this.cust_id = cust_id;
    }
    public String getCust_name() {
    return cust_name;
    }
    public void setCust_name(String cust_name) {
    this.cust_name = cust_name;
    }
    public String getCust_source() {
    return cust_source;
    }
    public void setCust_source(String cust_source) {
    this.cust_source = cust_source;
    }
    public String getCust_industry() {
    return cust_industry;
    }
    public void setCust_industry(String cust_industry) {
    this.cust_industry = cust_industry;
    }
    public String getCust_level() {
    return cust_level;
    }
    public void setCust_level(String cust_level) {
    this.cust_level = cust_level;
    }
    public String getCust_address() {
    return cust_address;
    }
    public void setCust_address(String cust_address) {
    this.cust_address = cust_address;
    }
    public String getCust_phone() {
    return cust_phone;
    }
    public void setCust_phone(String cust_phone) {
    this.cust_phone = cust_phone;
    }

    public Set getLinkMans() {
    return linkMans;
    }
    public void setLinkMans(Set linkMans) {
    this.linkMans = linkMans;
    }
    @Override
    public String toString() {
    return “Customer [cust_id=” + cust_id + “, cust_name=” + cust_name + “, cust_source=” + cust_source
    + “, cust_industry=” + cust_industry + “, cust_level=” + cust_level + “, cust_address=” + cust_address
    + “, cust_phone=” + cust_phone + “]”;
    }

}

联系人实体类
/**

  • 联系人实体类

  • @author kevin
    */
    public class LinkMan implements Serializable{

    private static final long serialVersionUID = 1L;

    private Long lkm_id;
    private String lkm_name;
    private String lkm_gender;
    private String lkm_phone;
    private String lkm_mobile;
    private String lkm_email;
    private String lkm_position;
    private String lkm_memo;

    //多对一关系映射:多个联系人对应一个客户
    private Customer customer;
    public Long getLkm_id() {
    return lkm_id;
    }
    public void setLkm_id(Long lkm_id) {
    this.lkm_id = lkm_id;
    }
    public String getLkm_name() {
    return lkm_name;
    }
    public void setLkm_name(String lkm_name) {
    this.lkm_name = lkm_name;
    }
    public String getLkm_gender() {
    return lkm_gender;
    }
    public void setLkm_gender(String lkm_gender) {
    this.lkm_gender = lkm_gender;
    }
    public String getLkm_phone() {
    return lkm_phone;
    }
    public void setLkm_phone(String lkm_phone) {
    this.lkm_phone = lkm_phone;
    }
    public String getLkm_mobile() {
    return lkm_mobile;
    }
    public void setLkm_mobile(String lkm_mobile) {
    this.lkm_mobile = lkm_mobile;
    }
    public String getLkm_email() {
    return lkm_email;
    }
    public void setLkm_email(String lkm_email) {
    this.lkm_email = lkm_email;
    }
    public String getLkm_position() {
    return lkm_position;
    }
    public void setLkm_position(String lkm_position) {
    this.lkm_position = lkm_position;
    }

    public String getLkm_memo() {
    return lkm_memo;
    }
    public void setLkm_memo(String lkm_memo) {
    this.lkm_memo = lkm_memo;
    }

    public Customer getCustomer() {
    return customer;
    }
    public void setCustomer(Customer customer) {
    this.customer = customer;
    }
    @Override
    public String toString() {
    return “LinkMan [lkm_id=” + lkm_id + “, lkm_name=” + lkm_name + “, lkm_gender=” + lkm_gender + “, lkm_phone=”
    + lkm_phone + “, lkm_mobile=” + lkm_mobile + “, lkm_email=” + lkm_email + “, lkm_position=”
    + lkm_position + “, lkm_memo=” + lkm_memo + “]”;
    }

}
2.4.客户配置文件

<?xml version="1.0" encoding="UTF-8"?>

2.5.联系人配置文件
?xml version=“1.0” encoding=“UTF-8”?>

3.多对多关系映射 3.1.示例分析 我们采用的示例为用户和角色。 用户:指的是咱们班的每一个同学。 角色:指的是咱们班同学的身份信息。 比如A同学,它是我的学生,其中有个身份就是学生,还是家里的孩子,那么他还有个身份是子女。 同时B同学,它也具有学生和子女的身份。 那么任何一个同学都可能具有多个身份。同时学生这个身份可以被多个同学所具有。 所以我们说,用户和角色之间的关系是多对多。

3.2.表关系建立
多对多的表关系建立靠的是中间表,其中用户表和中间表的关系是一对多,角色表和中间表的关系也是一对多,如下图所示:

3.3.实体类关系建立
一个用户可以具有多个角色,所以在用户实体类中应该包含多个角色的信息,代码如下:
/**

  • 用户实体类

  • @author kevin
    */
    public class SysUser implements Serializable{

    private static final long serialVersionUID = 1L;
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private String user_state;

    //多对多关系映射
    private Set roles = new HashSet();

    public Long getUser_id() {
    return user_id;
    }
    public void setUser_id(Long user_id) {
    this.user_id = user_id;
    }
    public String getUser_code() {
    return user_code;
    }
    public void setUser_code(String user_code) {
    this.user_code = user_code;
    }
    public String getUser_name() {
    return user_name;
    }
    public void setUser_name(String user_name) {
    this.user_name = user_name;
    }
    public String getUser_password() {
    return user_password;
    }
    public void setUser_password(String user_password) {
    this.user_password = user_password;
    }
    public String getUser_state() {
    return user_state;
    }
    public void setUser_state(String user_state) {
    this.user_state = user_state;
    }
    public Set getRoles() {
    return roles;
    }
    public void setRoles(Set roles) {
    this.roles = roles;
    }
    @Override
    public String toString() {
    return “SysUser [user_id=” + user_id + “, user_code=” + user_code + “, user_name=” + user_name
    + “, user_password=” + user_password + “, user_state=” + user_state + “, roles=” + roles + “]”;
    }

}
一个角色可以赋予多个用户,所以在角色实体类中应该包含多个用户的信息,代码如下:
/**

  • 角色实体类

  • @author kevin
    */
    public class SysRole implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long role_id;
    private String role_name;
    private String role_memo;

    //多对多关系映射
    private Set users = new HashSet();
    public Long getRole_id() {
    return role_id;
    }
    public void setRole_id(Long role_id) {
    this.role_id = role_id;
    }
    public String getRole_name() {
    return role_name;
    }
    public void setRole_name(String role_name) {
    this.role_name = role_name;
    }
    public String getRole_memo() {
    return role_memo;
    }
    public void setRole_memo(String role_memo) {
    this.role_memo = role_memo;
    }
    public Set getUsers() {
    return users;
    }
    public void setUsers(Set users) {
    this.users = users;
    }
    @Override
    public String toString() {
    return “SysRole [role_id=” + role_id + “, role_name=” + role_name + “, role_memo=” + role_memo + “, users=”
    + users + “]”;
    }

}
3.4.用户配置文件

<?xml version="1.0" encoding="UTF-8"?>

3.5.角色配置文件

<?xml version="1.0" encoding="UTF-8"?>

4.多表增删改操作
4.1.一对多关系操作
4.1.1.普通保存操作
原则:先保存主表数据,再保存从表数据
设置联系人属于哪个客户,同时也设置客户下有哪些联系人,先保存客户,再保存联系人。
/**
* 一对多的普通保存
* 设置联系人属于哪个客户,同时也设置客户下有哪些联系人
*/
@Test
public void test1(){
//创建客户对象
Customer customer = new Customer();
customer.setCust_name(“阿里巴巴”);

	//创建联系人对象
	LinkMan linkMan = new LinkMan();
	linkMan.setLkm_name("马云");
	
	//设置联系人属于哪个客户
	linkMan.setCustomer(customer);
	
	//设置客户下有哪些联系人
	customer.getLinkMans().add(linkMan);
	
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	//先保存客户
	session.save(customer);
	//再保存联系人
	session.save(linkMan);
	
	tx.commit();

}
4.1.2.级联保存
级联:操作一个对象的时候,是否操作其关联对象。
级联保存是有方向性的:
1、保存客户,级联保存联系人。
2、保存联系人,级联保存客户。
级联保存需要在其中一方配置cascade=save-update。

保存联系人级联保存客户,需要在联系人的映射文件LinkMan.hbm.xml的many-to-one标签中设置cascade=save-update,save-update的意思就是可以级联保存,也可以级联更新。
联系人方设置cascade=save-update

/**
* 一对多的级联保存
* 需求:保存联系人,级联保存客户
* 在LinkMan.hbm.xml的many-to-one标签中配置cascade=save-update
* 设置联系人属于哪个客户,同时设置客户下有哪些联系人
* 保存联系人级联保存客户
*
*/
@Test
public void test4(){
//创建客户对象
Customer customer = new Customer();
customer.setCust_name(“阿里巴巴”);
//创建联系人对象
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name(“马云”);

	//设置联系人属于哪个客户
	linkMan.setCustomer(customer);
	//设置客户下有哪些联系人
	customer.getLinkMans().add(linkMan);
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	//保存联系人级联保存客户
	session.save(linkMan);
	
	tx.commit();

}
 保存客户,级联保存联系人。需要在客户的映射文件Customer.hbm.xml的set标签中配置cascade=save-update
客户方设置



/**
* 一对多的级联保存
* 需求:保存客户,级联保存联系人
* 在Customer.hbm.xml的set标签中配置cascade=save-update
* 设置联系人属于哪个客户,同时设置客户下有哪些联系人
* 保存客户级联保存联系人
*
*/
@Test
public void test3(){
//创建客户对象
Customer customer = new Customer();
customer.setCust_name(“阿里巴巴11”);

	//创建联系人对象
	LinkMan linkMan = new LinkMan();
	linkMan.setLkm_name("马云11");
	
	//设置联系人属于哪个客户
	linkMan.setCustomer(customer);
	//设置客户下有哪些联系人(让客户知道联系人)
	customer.getLinkMans().add(linkMan);
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	//保存客户,级联保存联系人
	session.save(customer);
	
	tx.commit();

}
4.1.3.普通删除操作
直接删除联系人,客户不受影响
/**
* 直接删除联系人,客户不受影响
/
@Test
public void test1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询id为1的联系人
LinkMan linkMan = session.get(LinkMan.class, 1L);
//删除id为1的联系人
session.delete(linkMan);
tx.commit();
}
直接删除客户,发送一条update语句和一条delete语句,先把外键置为null,再删除客户
/
*
* 直接删除客户
* 结果:发送一条update语句和一条delete语句
* 先把外键置为null,再删除客户
*/
@Test
public void test2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询id为1的客户
Customer customer = session.get(Customer.class, 1L);
//删除id为1的客户
session.delete(customer);
tx.commit();
}
4.1.4.级联删除
级联删除也是有方向性的:
1、删除客户时,级联删除联系人。
2、删除联系人时,级联删除客户。
删除客户时,级联把客户下的联系人也删除,发送一条update语句和两条delete语句,先把外键置为null,再删除联系人,最后删除客户。
在客户方设置cascade=delete
细节:如果想同时设置级联保存和级联删除,可以这么写:cascade=save-update,delete



/**
* 删除客户时,级联把客户下的联系人也删除
* 在客户的映射文件set标签中设置cascade=delete
* 结果:发送一条update语句和两条delete语句
* 先把外键置为null,再删除联系人,最后删除客户
*/
@Test
public void test3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询id为1的客户
Customer customer = session.get(Customer.class, 1L);
//删除id为1的客户,
session.delete(customer);
tx.commit();
}

删除联系人,级联删除客户,发送一条update语句和两条delete语句,先把外键置为null,再删除联系人,最后删除客户。注意:一般不这么用。
/**
* 删除联系人,级联删除客户
* 在联系人的映射文件many-to-one标签中设置cascade=delete
* 结果:发送一条update语句和两条delete语句
* 先把外键置为null,再删除联系人,最后删除客户
*
* 注意:删除多方时,不需要级联
/
@Test
public void test4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询id为1的联系人
LinkMan linkMan = session.get(LinkMan.class, 1L);
//删除id为1的联系人,级联删除客户
session.delete(linkMan);
tx.commit();
}
4.1.5.修改操作
/
*
* 一对多的修改:把1号联系人移到2号客户下
*
*/
@Test
public void test6() {

	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();

	//再查询id为1的联系人
	LinkMan linkMan = session.get(LinkMan.class, 1L);
	//再先查询id为2的客户
	Customer customer2 = session.get(Customer.class, 2L);

	linkMan.setCustomer(customer2);
	customer2.getLinkMans().add(linkMan);

	tx.commit();

}

测试发现:能更新成功,但是多了一条更新外键的语句。如何解决?用inverse。

4.1.6. inverse的作用
作用:在一的一方(主表)设置inverse=true后,表示一的一方(主表)放弃维护外键的权利,由多的一方来维护。
默认情况下,一方,inverse的默认值为false,自己来维护外键。可以在一方设置invsese=true,放弃维护外键的权利。
注意:多方不能设置inverse。
那到底什么时候用inverse??
建立双向关系后,会产生多余的update语句,如果想解决的话,就要用inverse,让一方放弃外键的维护权。例如,4.1.5中就会出现多余的update语句。
如何解决:在一的一方(主表)的set标签中配置inverse=true.让一的一方放弃外键维护权。




4.2.多对多关系操作
4.2.1.普通保存操作
多对多保存,创建两个用户和三个角色,并设置用户拥有哪些角色以及角色下有哪些用户,分别保存两个用户和三个角色,会发送九条insert语句。
/**
* 多对多的保存
* 设置用户下有哪些角色以及角色下有哪些用户
* 测试结果:会报错,提示中间表中主键冲突
*/
@Test
public void test1(){
SysUser user1 = new SysUser();
user1.setUser_name(“用户1”);

	SysUser user2 = new SysUser();
	user2.setUser_name("用户2");
	
	SysRole role1 = new SysRole();
	role1.setRole_name("角色1");
	
	SysRole role2 = new SysRole();
	role2.setRole_name("角色2");
	
	SysRole role3 = new SysRole();
	role3.setRole_name("角色3");
	
	//一个用户有多个角色
	user1.getRoles().add(role1);
	user1.getRoles().add(role2);
	
	user2.getRoles().add(role2);
	user2.getRoles().add(role3);
	
	//一个角色下有多个用户
	role1.getUsers().add(user1);
	role2.getUsers().add(user1);
	role2.getUsers().add(user2);
	role3.getUsers().add(user2);
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	session.save(user1);
	session.save(user2);
	session.save(role1);
	session.save(role2);
	session.save(role3);
	
	tx.commit();

}

测试结果:报错,提示中间表主键冲突。原因:用户和角色都需要维护外键,都要向中间表插入数据,所以主键冲突。
解决:在任意一方的set标签中配置inverse=true,放弃外键维护权。
我们可以在角色方放弃外键维护:



4.2.2.级联保存
可以在用户方设置级联保存
/**
* 多对多的保存
* 设置用户下有哪些角色以及角色下有哪些用户
* 测试结果:会报错,提示中间表中主键冲突
*/
@Test
public void test1(){
SysUser user1 = new SysUser();
user1.setUser_name(“用户1”);

	SysUser user2 = new SysUser();
	user2.setUser_name("用户2");
	
	SysRole role1 = new SysRole();
	role1.setRole_name("角色1");
	
	SysRole role2 = new SysRole();
	role2.setRole_name("角色2");
	
	SysRole role3 = new SysRole();
	role3.setRole_name("角色3");
	
	//一个用户有多个角色
	user1.getRoles().add(role1);
	user1.getRoles().add(role2);
	
	user2.getRoles().add(role2);
	user2.getRoles().add(role3);
	
	//一个角色下有多个用户
	role1.getUsers().add(user1);
	role2.getUsers().add(user1);
	role2.getUsers().add(user2);
	role3.getUsers().add(user2);
	
	
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	session.save(user1);
	session.save(user2);

// session.save(role1);
// session.save(role2);
// session.save(role3);

	tx.commit();

}

在用户方设置级联保存

也可以在角色方设置级联
@Test
public void test1(){
SysUser user1 = new SysUser();
user1.setUser_name(“用户1”);

	SysUser user2 = new SysUser();
	user2.setUser_name("用户2");
	
	SysRole role1 = new SysRole();
	role1.setRole_name("角色1");
	
	SysRole role2 = new SysRole();
	role2.setRole_name("角色2");
	
	SysRole role3 = new SysRole();
	role3.setRole_name("角色3");
	
	//一个用户有多个角色
	user1.getRoles().add(role1);
	user1.getRoles().add(role2);
	
	user2.getRoles().add(role2);
	user2.getRoles().add(role3);
	
	//一个角色下有多个用户
	role1.getUsers().add(user1);
	role2.getUsers().add(user1);
	role2.getUsers().add(user2);
	role3.getUsers().add(user2);
	
	
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();

// session.save(user1);
// session.save(user2);
session.save(role1);
session.save(role2);
session.save(role3);

	tx.commit();
	
}

在角色的映射文件中配置cascade=save-update



4.2.3.删除操作
先查询出要删除的对象,再删除。也可以直接实例化出对象并设置id,再删除。
/**
* 多对多删除
* 先查询id为1的用户对象,再删除。
* 结果:会发两条delete语句,先发一条delete语句,删除中间表的数据,再发一条delete语句删除用户
*/
@Test
public void test9(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
SysUser user = session.get(SysUser.class, 1L);
session.delete(user);

	tx.commit();
}  

4.2.4.级联删除
多对多中最好不要设置级联删除。因为一旦设置级联删除后,用户级联角色,当删除用户时,就会删除把与之关联的其它角色删除,但是这些角色可能被其它用户用到。

在User.hbm.xml中设置cascase=”delete”



@Test
public void test9(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
SysUser user = session.get(SysUser.class, 1L);
session.delete(user);

	tx.commit();

}

测试发现,会报错,因为删除用户会级联删除角色,但角色放弃了外键维护,不会删除中间表中与角色关联的数据,所以整个删除操作失败。
解决办法:把角色方的inverse去掉。但是,也没必要,应为在多对多中没有表级联删除。
4.2.5.修改操作
/**
* 多对多修改操作
* 需求:修改id为1的用户,把其中的1号角色改为3号角色
*/
@Test
public void test1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

	//先查询id为1的用户
	SysUser user = session.get(SysUser.class, 1L);
	//再查询id为1和3的角色
	SysRole role1 = session.get(SysRole.class, 1L);
	SysRole role3 = session.get(SysRole.class, 3L);
	//再建立关系
	user.getRoles().remove(role1);
	user.getRoles().add(role3);
	tx.commit();
}

5.Hibernate中的多表查询
5.1.对象导航查询
5.1.1.概述
对象图导航检索方式是根据已经加载的对象,导航到他的关联对象。它利用类与类之间的关系来检索对象。
例如:我们通过OID查询方式查出一个客户,可以调用Customer类中的getLinkMans()方法来获取该客户的所有联系人。
对象导航查询的使用要求是:两个对象之间必须存在关联关系。
5.1.2.对象导航检索示例
5.1.2.1.查询一个客户,获取该客户下所有联系人
/**
* 需求:
* 查询id为1的客户有多少联系人
/
@Test
public void test1(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
Customer customer = session.get(Customer.class, 1L);
Set linkMans = customer.getLinkMans();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
tx.commit();
}
5.1.2.2.查询一个联系人,获取该联系人所对应的客户
/
*
* 需求:
* 查询一个联系人,获取该联系人所对应的客户
*/
@Test
public void test2(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
LinkMan linkMan = session.get(LinkMan.class, 1L);
System.out.println(linkMan.getCustomer().getCust_name());
tx.commit();
}
5.1.3.对象导航查询的问题分析
问题1:我们查询客户时,要不要把联系人查询出来?
分析:
如果我们不查的话,在用的时候还要自己写代码,调用方法去查询。
如果我们查出来的,不使用时又会白白的浪费了服务器内存。
解决:
采用延迟加载的思想。通过配置的方式来设定当我们在需要使用时,发起真正的查询。
配置的方式:
在Customer.hbm.xml配置文件中的set标签上使用lazy属性。取值为true(默认值)|fasle




问题2:我们查询联系人时,要不要把客户查询出来?
分析:
如果我们不查的话,在用的时候还要自己写代码,调用方法去查询。
如果我们查出来的话,一个对象不会消耗太多的内存。而且多数情况下我们都是要使用的。
例如:查询联系人详情时,肯定会看看该联系人的所属客户。
解决:
采用立即加载的思想。通过配置的方式来设定,只要查询从表实体,就把主表实体对象同时查出来。
配置的方式:
在LinkMan.hbm.xml配置文件中的many-to-one标签上使用lazy属性。取值为proxy|fasle
false:立即加载
proxy:看客户的映射文件class标签的lazy属性取值,如果客户的class标签lazy属性是true
那么proxy表示延迟加载,如果是false就表示立即加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值