一、树状结构设计
Organization.java
1 package org.xiong.hibernate.model; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Entity; 8 import javax.persistence.FetchType; 9 import javax.persistence.GeneratedValue; 10 import javax.persistence.Id; 11 import javax.persistence.JoinColumn; 12 import javax.persistence.ManyToOne; 13 import javax.persistence.OneToMany; 14 15 @Entity 16 public class Organization 17 { 18 private int id; 19 private String designation; 20 private String location; 21 22 private Set<Organization> children = new HashSet<Organization>(); 23 private Organization parent; 24 25 @ManyToOne 26 @JoinColumn(name = "parentID") 27 public Organization getParent() 28 { 29 return parent; 30 } 31 32 public void setParent(Organization parent) 33 { 34 this.parent = parent; 35 } 36 37 @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 38 public Set<Organization> getChildren() 39 { 40 return children; 41 } 42 43 public void setChildren(Set<Organization> children) 44 { 45 this.children = children; 46 } 47 48 @Id 49 @GeneratedValue 50 public int getId() 51 { 52 return id; 53 } 54 55 public void setId(int id) 56 { 57 this.id = id; 58 } 59 60 public String getDesignation() 61 { 62 return designation; 63 } 64 65 public void setDesignation(String designation) 66 { 67 this.designation = designation; 68 } 69 70 public String getLocation() 71 { 72 return location; 73 } 74 75 public void setLocation(String location) 76 { 77 this.location = location; 78 } 79 80 }
生成的SQL:
1 17:24:27,828 INFO SchemaExport:226 - Running hbm2ddl schema export 2 17:24:27,828 DEBUG SchemaExport:242 - import file not found: /import.sql 3 17:24:27,828 INFO SchemaExport:251 - exporting generated schema to database 4 17:24:27,984 DEBUG SchemaExport:377 - 5 drop table Organization cascade constraints 6 17:24:28,000 DEBUG SchemaExport:377 - 7 drop sequence hibernate_sequence 8 17:24:28,031 DEBUG SchemaExport:377 - 9 create table Organization ( 10 id number(10,0) not null, 11 designation varchar2(255 char), 12 location varchar2(255 char), 13 parentID number(10,0), 14 primary key (id) 15 ) 16 17:24:28,109 DEBUG SchemaExport:377 - 17 alter table Organization 18 add constraint FK501041537D7CF25A 19 foreign key (parentID) 20 references Organization 21 17:24:28,109 DEBUG SchemaExport:377 - 22 create sequence hibernate_sequence 23 17:24:28,125 INFO SchemaExport:268 - schema export complete
生成的表结构:
插入测试数据:
1 @Test 2 public void testOrganizationAdd() 3 { 4 Transaction transaction = null; 5 try 6 { 7 Session session = sessionFactory.getCurrentSession(); 8 transaction = session.beginTransaction(); 9 Organization o = new Organization(); 10 o.setDesignation("总公司"); 11 Organization o1 = new Organization(); 12 o1.setDesignation("分公司1"); 13 Organization o2 = new Organization(); 14 o2.setDesignation("分公司2"); 15 Organization o11 = new Organization(); 16 o11.setDesignation("分公司1--部门1"); 17 Organization o21 = new Organization(); 18 o21.setDesignation("分公司2--部门1"); 19 20 o.getChildren().add(o1); 21 o.getChildren().add(o2); 22 o1.getChildren().add(o11); 23 o2.getChildren().add(o21); 24 o11.setParent(o1); 25 o21.setParent(o2); 26 o1.setParent(o); 27 o2.setParent(o); 28 29 session.save(o); 30 transaction.commit(); 31 } 32 catch (Exception e) 33 { 34 e.printStackTrace(); 35 transaction.rollback(); 36 } 37 }
读取树状结构数据:(如果树非常大的话,最好用FetchType.LAZY)
1 @Test 2 public void testOrganizationLoad() 3 { 4 Transaction transaction = null; 5 try 6 { 7 Session session = sessionFactory.getCurrentSession(); 8 transaction = session.beginTransaction(); 9 Organization o=(Organization)session.load(Organization.class, 1); 10 printOrganization(o,0); 11 12 transaction.commit(); 13 } 14 catch (Exception e) 15 { 16 e.printStackTrace(); 17 transaction.rollback(); 18 } 19 } 20 21 private void printOrganization(Organization o, int level) 22 { 23 String preStr=""; 24 for(int i=0;i<level;i++) 25 { 26 preStr+=" |-"; 27 } 28 System.out.println(preStr+o.getDesignation()); 29 for(Organization child:o.getChildren()) 30 { 31 printOrganization(child,level+1); 32 } 33 }
二、学生(Student),课程(Course),分数(Score)的设计
Course.java
1 package org.xiong.hibernate.model; 2 3 import javax.persistence.Entity; 4 import javax.persistence.GeneratedValue; 5 import javax.persistence.Id; 6 7 @Entity 8 public class Course 9 { 10 private int id; 11 private String name; 12 13 public Course() 14 { 15 16 } 17 18 public Course(String name) 19 { 20 super(); 21 this.name = name; 22 } 23 24 @Id 25 @GeneratedValue 26 public int getId() 27 { 28 return id; 29 } 30 31 public void setId(int id) 32 { 33 this.id = id; 34 } 35 36 public String getName() 37 { 38 return name; 39 } 40 41 public void setName(String name) 42 { 43 this.name = name; 44 } 45 46 }
Student.java
1 package org.xiong.hibernate.model; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Entity; 8 import javax.persistence.GeneratedValue; 9 import javax.persistence.Id; 10 import javax.persistence.JoinColumn; 11 import javax.persistence.JoinTable; 12 import javax.persistence.ManyToMany; 13 14 import org.hibernate.annotations.BatchSize; 15 16 @Entity 17 @BatchSize(size=100) 18 public class Student 19 { 20 private int id; 21 private String name; 22 23 private Set<Course> choiceOfCourse =new HashSet<Course>(); 24 25 @ManyToMany(cascade=CascadeType.ALL) 26 @JoinTable(name = "Score", joinColumns = { @JoinColumn(name = "studentId") }, inverseJoinColumns = { @JoinColumn(name = "courseId") }) 27 public Set<Course> getChoiceOfCourse() 28 { 29 return choiceOfCourse; 30 } 31 32 public void setChoiceOfCourse(Set<Course> choiceOfCourse) 33 { 34 this.choiceOfCourse = choiceOfCourse; 35 } 36 37 @Id 38 @GeneratedValue 39 public int getId() 40 { 41 return id; 42 } 43 44 public void setId(int id) 45 { 46 this.id = id; 47 } 48 49 public String getName() 50 { 51 return name; 52 } 53 54 public void setName(String name) 55 { 56 this.name = name; 57 } 58 59 }
Score.java
1 package org.xiong.hibernate.model; 2 3 import javax.persistence.CascadeType; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.Id; 7 import javax.persistence.JoinColumn; 8 import javax.persistence.ManyToOne; 9 10 @Entity 11 public class Score 12 { 13 private int id; 14 private float score; 15 16 private Student student = new Student(); 17 private Course course = new Course(); 18 19 @Id 20 @GeneratedValue 21 public int getId() 22 { 23 return id; 24 } 25 26 public void setId(int id) 27 { 28 this.id = id; 29 } 30 31 @ManyToOne(cascade=CascadeType.ALL) 32 @JoinColumn(name = "courseId") 33 public Course getCourse() 34 { 35 return course; 36 } 37 38 public float getScore() 39 { 40 return score; 41 } 42 43 @ManyToOne(cascade=CascadeType.ALL) 44 @JoinColumn(name = "studentId") 45 public Student getStudent() 46 { 47 return student; 48 } 49 50 public void setCourse(Course course) 51 { 52 this.course = course; 53 } 54 55 public void setScore(float score) 56 { 57 this.score = score; 58 } 59 60 public void setStudent(Student student) 61 { 62 this.student = student; 63 } 64 65 }
生成的SQL:
1 19:12:59,015 INFO SchemaExport:226 - Running hbm2ddl schema export 2 19:12:59,031 DEBUG SchemaExport:242 - import file not found: /import.sql 3 19:12:59,031 INFO SchemaExport:251 - exporting generated schema to database 4 19:12:59,171 DEBUG SchemaExport:377 - 5 drop table Course cascade constraints 6 19:12:59,203 DEBUG SchemaExport:377 - 7 drop table Score cascade constraints 8 19:12:59,218 DEBUG SchemaExport:377 - 9 drop table Student cascade constraints 10 19:12:59,234 DEBUG SchemaExport:377 - 11 drop sequence hibernate_sequence 12 19:12:59,234 DEBUG SchemaExport:377 - 13 create table Course ( 14 id number(10,0) not null, 15 name varchar2(255 char), 16 primary key (id) 17 ) 18 19:12:59,312 DEBUG SchemaExport:377 - 19 create table Score ( 20 id number(10,0) not null, 21 score float not null, 22 courseId number(10,0), 23 studentId number(10,0), 24 primary key (studentId, courseId) 25 ) 26 19:12:59,343 DEBUG SchemaExport:377 - 27 create table Student ( 28 id number(10,0) not null, 29 name varchar2(255 char), 30 primary key (id) 31 ) 32 19:12:59,390 DEBUG SchemaExport:377 - 33 alter table Score 34 add constraint FK4C04E7239A635F3 35 foreign key (courseId) 36 references Course 37 19:12:59,390 DEBUG SchemaExport:377 - 38 alter table Score 39 add constraint FK4C04E72850DD7AF 40 foreign key (studentId) 41 references Student 42 19:12:59,390 DEBUG SchemaExport:377 - 43 create sequence hibernate_sequence 44 19:12:59,406 INFO SchemaExport:268 - schema export complete
生成的表结构:
三、数据库事务和锁
作为单个逻辑单元执行的一系列操作叫做数据库事务(DatabaseTransaction),除非事务单元内的所有操作都成功完成,否则不会永久更新数据库的资源。数据库事务(DatabaseTransaction)具有A(原子性)、C(一致性)、I(隔离性)、D(持久性)的特性。
数据库事务(DatabaseTransaction)的并发可能出现的问题有脏读(Dirty Read)、不可重复读(non-repeatable Read)、幻读(phantom Read)。为了解决数据库事务并发可能产生的问题,通过数据库的隔离级别来解决。数据库的隔离级别分为Read-uncommitted(1)、Read-committed(2)、repeatable read(4)、serializable(8)。MYSQL默认的数据库隔离级别是repeatable read(4),Oracle默认的数据库隔离级别是Read-committed(2)。数据库级越高越安全,但同时性能上可能就要差一些,所以一般为了提高数据库访问数据的性能,采用Read-committed(2)级别,但此级别的容易产生不可重复读(non-repeatable Read)的问题和幻读(Phantom Read)的问题,可以通过锁来解决不可重复读(non-repeatable Read)的问题。悲观锁和乐观锁的使用有个前提就是数据库为了提高并发性能将数据库隔离级别设置成了Read-committed(2),为了解决不可重复读(non-repeatable read)的问题才使用锁。悲观锁指的是,一个事务悲观的认为在执行过程中,别的事务肯定会来执行。乐观锁指的是,一个事务乐观的认为,在执行的过程中不一定会有别的事务执行。