本文以Group和User(一對多、多對一)雙向關聯為例,介紹關聯關系的CRUD
下面先介紹兩個屬性
cascade:只影響CRUD中的CUD,即存儲(save)、更新(update)、刪除(delete)fetch:只影響CRUD中的R,即讀取(get、load)
cascade(級聯):此屬性僅僅幫助我們簡化編程,不是必選項如果A和B為單向關聯,則在主導方設置cascade屬性如果A和B為雙向關聯,則在雙方都要設置cascade屬性
如果兩個對象之間有關聯關系,比如User和Group多對一關聯如果想要保存User的時候自動保存Group,可在User類的@ManyToOne注解中設置cascade(級聯)屬性反過來,如果想要保存Group的時候自動保存User,可在Group類的@OneToMany注解中設置cascade(級聯)屬性
對于User(多方)和Group(一方)執行如下語句 User u = (User) session.get(User.class, 1);在取出多方對象u的同時也會把一方對象對應屬性取出來,這是@ManyToOne的默認設置.相當于設置@ManyToOne(fetch=FetchType.EAGER)反過來,取一方對象的時候,則不會把多方對象取出若想要在取出一方對象g的同時取出多方對象,則應在Group類的@OneToMany注解中設置fetch屬性
@OneToMany注解中fetch的默認值為FetchType.LAZY, 相當于設置@OneToMany(fetch=FetchType.LAZY) fetch的取值有兩個fetch=FetchType.EAGER :執行語句就取出fetch=FetchType.LAZY :用的時候才取出兩者的區別類似于get和load的區別 注意:對于雙向關聯,不要兩邊都設EAGER(會有多余的查詢語句發出),可以都設LAZY一般是多對一設置EAGER,一對多設置LAZY
建Group實體類和User實體類,以及Junit測試類
@Entity@Table(name="_group")public class Group {PRivate int id;private String name;private Set<User> users = new HashSet<User>();@Id@GeneratedValuepublic 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(mappedBy="group")public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;}}
@Entity@Table(name="_user")public class User {private int id;private String name;private Group group;@Id@GeneratedValuepublic 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;}@ManyToOnepublic Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}}
public class ORMappingTest {private static SessionFactory sf = null;@BeforeClasspublic static void beforeClass(){sf = new Configuration().configure().buildSessionFactory();}@AfterClasspublic static void afterClass(){sf.close();}@Testpublic void test() {//下面將會完善此test()方法}}
接下來開始CRUD的練習
首先在Group類和User類的@OneToMany和@ManyToOne注解中添加cascade屬性
//Group類 此處fetch屬性中,LAZY為默認值,故也可不寫@OneToMany(mappedBy="group",cascade={CascadeType.ALL},fetch=FetchType.LAZY)public Set<User> getUsers() { return users;}
//User類 此處fetch屬性中,EAGER為默認值,故也可不寫@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)public Group getGroup() { return group;}
然后,完善Junit測試類的test()方法
CRUD----C 增 session.save()
1.保存User對象的同時自動保存Group對象
@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();Group g = new Group();g.setName("lisi");User u = new User();u.setName("user1");u.setGroup(g);session.save(u); //因為在User類的@ManyToOne注解中設置了cascade(級聯)屬性,故只需保存User對象即可,Group對象會自動保存session.getTransaction().commit();}2.保存Group對象的同時自動保存User對象
@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();User u1 = new User();User u2 = new User();Group g = new Group();u1.setName("user1");u1.setGroup(g);u2.setName("user2");u2.setGroup(g);g.setName("group1");g.getUsers().add(u1);g.getUsers().add(u2);session.save(g); //因為在Group類的@OneToMany注解中設置了cascade(級聯)屬性,故只需保存Group對象即可,User對象會自動保存session.getTransaction().commit();}
CRUD----R 查 session.get()和session.load()
1.取出User對象的同時取出Group對象
@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();User u = (User) session.get(User.class, 1); //在取出多方對象u的同時也會把一方對象對應屬性取出來,這是@ManyToOne的默認設置System.out.println(u.getGroup().getName()); //打印輸出_group表中對應的name值session.getTransaction().commit();}2.取出Group對象的同時取出User對象
@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();Group g = (Group) session.get(Group.class, 2); //在取出一方對象g的同時取出多方對象,此時應在Group類的@OneToMany注解中設置fetch屬性for(User u : g.getUsers()){System.out.println(u.getId()+","+u.getName()); //打印輸出_user表中的相關數據}session.getTransaction().commit();}CRUD----U 改 session.update()
通過取出的User對象,既可以更改User對象中的屬性名字,也可以更改與其級聯的Group對象中的屬性名字
@Testpublic void test {Session session = sf.getCurrentSession();session.beginTransaction();User u = (User) session.get(User.class, 3); //在取出多方對象u的同時也會把一方對象對應屬性取出來,這是@ManyToOne的默認設置u.setName("name"); //更改User對象中的屬性名字u.getGroup().setName("Groupname"); //也可以更改與其級聯的Group對象中的屬性名字session.update(u);session.getTransaction().commit();}CRUD----D 刪 session.delete()
刪除User表中的某一條記錄
兩種方式,如下:
@Testpublic void testDelete() {Session session = sf.getCurrentSession();session.beginTransaction();//刪除User表中id值為1的記錄User u = (User) session.get(User.class, 1); //在取出多方對象u的同時也會把一方對象對應屬性取出來,這是@ManyToOne的默認設置u.setGroup(null); //應該先消除關聯關系,再刪除對應記錄session.delete(u); //如果直接刪除,由于設置了cascade屬性,則會刪除Group和User中相關的所有數據 //刪除User表中id值為2的記錄session.createQuery("delete from User u where u.id=2").executeUpdate();session.getTransaction().commit();}新聞熱點
疑難解答