Hibernate学习笔记(十一)

hibernate树形结构(重点)

树形结构:也就是目录结构,有父目录、子目录、文件等信息,而在程序中树形结构只是称为节点。

一棵树有一个根节点,而根节点也有一个或多个子节点,而一个子节点有且仅有一个父节点(当前除根节点外),而且也存在一个或多个子节点。

也就是说树形结构,重点就是节点,也就是我们需要关心的节点对象。

节点:一个节点有一个ID、一个名称、它所属的父节点(根节点无父节点或为null),有一个或多的子节点等其它信息。

Hibernate将节点抽取出成实体类,节点相对于父节点是“多对一”映射关系,节点相对于子节点是“一对多”映射关系。

一、 annotation注解

因为树型节点所有的数据,在数据库中只是存储在一个表中,而对于实体类来说,节点对子节点来说是一对多的关系,而对于父节点来说是多对一的关系。因此可以在一个实体类中注解。如下

@Entity
public class Org {
	private int id;
	private String name;
	private Set<Org> children = new HashSet<Org>();
	private Org parent;
	
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@OneToMany(cascade=CascadeType.ALL,mappedBy="parent",fetch=FetchType.EAGER)
	public Set<Org> getChildren() {
		return children;
	}
	public void setChildren(Set<Org> children) {
		this.children = children;
	}
	
	@ManyToOne
	@JoinColumn(name="parent_id")
	public Org getParent() {
		return parent;
	}
	public void setParent(Org parent) {
		this.parent = parent;
	}
}

二、 xml方式:映射文件:

<class name="csy.model.Org">
		<id name="id" column="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
	<!— 一对多:加入一个外键,参照当前表org主键,	而属性parent类型为Org,也就是当前类,则会在同一个表中加入这个字段,参照这个表的主键-->
		<many-to-one name="parent" column="parent_id"/>
	<!-- <set>标签是映射一对多的方式,加入一个外键,参照主键。-->
		<set name="children" lazy="extra" inverse="true">
			<key column="parent_id"/>
			<one-to-many class="csy.model.Org"/>
		</set>		
	</class>

三、 测试代码:

@Test
 public void testLoad(){
	 testSave();
	 Session session = sessionFactory.openSession();
	 session.beginTransaction();
	 Org o = (Org)session.load(Org.class, 1);
	 print(o,0);
	 session.getTransaction().commit();
	 session.close();
 }
 private void print(Org o,int level){
	 String preStr = "";
	 for(int i=0;i<level;i++){
		 preStr +="----";
	 }
	 System.out.println(preStr+o.getName());
	 for(Org child:o.getChildren()){
		 print(child,level+1);
	 }
 }

学生、课程、分数的映射关系

一、 设计

1、 实体类()

2、 导航(编程方便)

a) 通过学生 取出 学生所先的课程

b) 但是通过课程 取出 学该课程的 学生不好。学的学生太多

c) 确定编程的方式

3、 可以利用联合主键映射可以,

a) 学生生成一个表

b) 课程生成一个表

c) 再生成一个表,主键是联合主键(学生ID、课程ID) + 学生共生成一个表

4、 也可以利用一对多,多对多 都可以(推荐)

a) 学生生成一个表

b) 课程生成一个表

c) 分数生成一个表,并且有两个外键,分别指向学生、课程表

课程代码:

@Entity
public class Course {
	private int id;
	private String name;
	@Id
	@GeneratedValue
	public int getId() {return id;}
	public void setId(int id) {	this.id = id;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}}

分数代码:

@Entity
@Table(name = "score")
public class Score {
	private int id;
	private int score;
	private Student student;
	private Course course;
	@Id
	@GeneratedValue
	public int getId() {return id;}
	@ManyToOne
	@JoinColumn(name = "student_id")
	public Student getStudent() {return student;}
	@ManyToOne
	@JoinColumn(name = "score_id")
	public Course getCourse() {	return course;}
	public int getScore() {	return score;}
	public void setScore(int score) {this.score = score;}
	public void setStudent(Student student) {this.student = student;}
	public void setCourse(Course course) {this.course = course;}
	public void setId(int id) {	this.id = id;}}

学生通过课程可以导航到分数

@Entity
public class Student {
	private int id;
	private String name;
	private Set<Course> courses = new HashSet<Course>();
	@Id
	@GeneratedValue
	public int getId() {return id;}
	@ManyToMany
	@JoinTable(name = "score", //此表就是Score实体类在数据库生成的表叫score
			joinColumns = @JoinColumn(name = "student_id"), 
			inverseJoinColumns = @JoinColumn(name = "course_id")
		)
	public Set<Course> getCourses() {return courses;}
	public void setCourses(Set<Course> courses) {this.courses = courses;}
	public void setId(int id) {	this.id = id;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}}

三、 注意

Student实体类中的使用的第三方表使用了两个字段,而hibernate会使这两个字段生成联合主键,这并不是我们需要的结果,因此我们需要手动到数据库中修改。这样才可以存储数据,否则数据存储不进去。







 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值