Hibernate@OneToOne懒加载实现解决方案(二)

2014-11-24 17:05:02 · 作者: · 浏览: 4
e(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "STUDENT_ID") public Student getStudent() { return student; } // ... 略 }

优点:不改变Student与Card在代码中的对应关系(一对一)

缺点:需要同时维护Student和Card的两个外键。

方案二

改为主键关联。

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `ID` int(11) NOT NULL,
  `NAME` varchar(50) NOT NULL,
  PRIMARY KEY (`ID`),
  CONSTRAINT `PK_CARD_ID` FOREIGN KEY (`ID`) REFERENCES `card` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public class Student {

	// ... 略

	@Id
	@GenericGenerator(name = "PK_Card", strategy = "foreign", parameters = @Parameter(name = "property", value = "card"))
	@GeneratedValue(generator = "PK_Card")
	@Column(name = "ID", unique = true, nullable = false)
	public int getId() {
		return id;
	}

	// ... 略

	@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
	@PrimaryKeyJoinColumn
	public Card getCard() {
		return card;
	}

	// ... 略
}
public class Card {

	// ... 略

	@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "card", optional = false)
	public Student getStudent() {
		return student;
	}

	// ... 略
}

除了改变student表的主键、外键结构外,Student类和Card类也要做相应修改,尤其注意“optional”,要设置为false,否则无法实现懒加载。

优点:不改变Student与Card在代码中的对应关系(一对一)

缺点:改动较大,且使用主键关联具有局限性。

PS:主键关联的局限性

使用主键关联会影响数据存储结构,主键关联是一种强耦合,以上述为例:Card存在时,Student才能存在,Card消亡时,Student也随之消失。这是因为Student的主键依赖于Card主键,Student无法独立存在(就是说必须先有学生卡,才能有学生)。

方案三

将Card类中的OneToOne改为OneToMany(一对多)。

public class Card {

	private Set
  
    students;

	// ... 略

	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "card")
	public Set getStudents() {
		return students;
	}

	public void setStudents(Set
   
     students) { this.students = students; } // ... 略 }
   
  

优点:数据库不用修改

缺点:需要修改Student与Card在代码中的对应关系

方案四

放弃用注解的方式,改为Xml方式来实现hibernate模型设计,并在Card Xml的OneToOne标签中添加constrained属性,靠注解解决的办法已经没有了(instrument增强就算了吧,很麻烦)。

最后,我们来评估下以上方案的可行性。

方案一:从可读性来讲,是最容易理解的,但需要维护两个外键,如果程序控制不好的话,容易出问题,即关联错误。

方案二:主键关联虽然有些约束,但也取决于业务需求,比如订单和订单详情,采用主键关联也挺合适的,只是不适合相对灵活的对象关系。

方案三:改动在我看来是最小的了,牺牲了一定的可读性(关系从Card角度看变为了一对多),我个人比较喜欢该种方案,因此推荐。

方案四:如果不采用注解,而采用Xml的话,我是很推荐这种方案的,注解虽然优点多,也趋于主流,但最传统的Xml,功能还是最强大的。但如果你仅为了解决该问题,而将注解和Xml混合使用的话,我建议你还是放弃吧。