1.23 存在关联关系(多对一等等)表的存储

例如,user与group之间的多对一关系的存储。

1.user类

@Entity
@Table(name="t_user")
public class User {
private int id;
private String name;
private Group group;
@ManyToOne(cascade={CascadeType.ALL})
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@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;
}
}

2.group类

@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
private Set<User> users = new HashSet<User>();
@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(mappedBy="group",
cascade={CascadeType.ALL}
)

public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}


3.测试。

public class HibernateORMappingTest {
private static SessionFactory sessionFactory;

@BeforeClass
public static void beforeClass() {
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}
@AfterClass
public static void afterClass() {
sessionFactory.close();
}

第一次测试
@Test
public void testSaveUser() {
User u = new User();
u.setName("u1");
Group g = new Group();
g.setName("g1");
u.setGroup(g);
Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
//s.save(g);
s.save(u);
s.getTransaction().commit();
}

以上在没有设定@manytoone的级联属性情况下,没有保存group实例的情况下,保存user的同时,不会保存group的。

第二次测试:在user的@manytoone处,加@ManyToOne(cascade={CascadeType.ALL}),表示级联更新。此时在测试上述保存代码,在没有保存group的情况下,保存user将会成功。

第三次测试:保存group,而不保存user

@Test
public void testSaveGroup() {
User u1 = new User();
u1.setName("u1");
User u2 = new User();
u2.setName("u2");
Group g = new Group();
g.setName("g1");
g.getUsers().add(u1);
g.getUsers().add(u2);
u1.setGroup(g);
u2.setGroup(g);

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
//s.save(g);
s.save(g);
s.getTransaction().commit();
}

在group类的@OneToMany(mappedBy="group",cascade={CascadeType.ALL})后,保存group的同时,会保存user。如果u1,u2没有设置group属性,保存的u1和u2的groupid是空。因为只设置了group到user的导航,而没设置user到group的导航。所以多对一关系中,从一方操作简单,而从多方操作麻烦。


一个规律:双向关联,再写程序时,一定要设好双向的级联关系。

第三次测试:利用get从数据库中拿数据。

@Test
public void testGetUser() {

testSaveGroup();

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
User u = (User)s.get(User.class, 1);

s.getTransaction().commit();
System.out.println(u.getGroup().getName());
}
在取出user的同时,将group也取出来了。因为设置了从user到group的级联。

规律:从“多”得一方取数据时,级联关系会将“一”的一方数据同时取出来;如果从“一”的一方取数据时,级联关系不会将“多”的一方数据取出来,如下列实例,这是因为cashcade只管增删改,fetch管读。

第四次测试:

@Test
public void testGetGroup() {

testSaveGroup();

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
Group g = (Group)s.get(Group.class, 1);
s.getTransaction().commit();

}此时不会将group对应的user取出来。如果此时在group类的@manytoone处加入(fetch=FetchType.eager),


第五次测试

在user(多)与group(一)方的测试中

在user到group的导航@manytoone(fetch=FetchType.lazy)

在测试代码中,

User u=(user)session.load(user.class,1);

system.out.print(u.getgroup().getname());

sql输出为:     先查询user,再找group


(2)在user到group的导航@manytoone(fetch=FetchType.eager),当然默认的多对一关系中,多方的fetchtype即为eager。

输出为:  先关联,再取user


上述取出user和group之后,又取了一次user,是因为group的fetchtype设为eager,它会马上再取一遍user。

结论:双向关系用的比较少,在双向关系上不要两边都取eager。hibernate在多对一取得eager,在一对多方取得lazy。

在xml文件里设置fetch模式,是在set的属性inverse=true,即翻转导航,反过来查询。


第六次测试:

public void testUpdateUser() {

testSaveGroup();

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
User u = (User)s.get(User.class, 1);

s.getTransaction().commit();

u.setName("user");
u.getGroup().setName("group");

Session s2 = sessionFactory.getCurrentSession();
s2.beginTransaction();
s2.update(u);

s2.getTransaction().commit();
}

第七次测试

@Test
public void testDeleteUser() {

testSaveGroup();

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
//User u = (User)s.load(User.class, 1);
//u.setGroup(null);
//s.delete(u);
s.createQuery("delete from User u where u.id = 1").executeUpdate();
s.getTransaction().commit();

}

@Test
public void testDeleteGroup() {

testSaveGroup();

Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
//User u = (User)s.load(User.class, 1);
//u.setGroup(null);
//s.delete(u);
Group g = (Group)s.load(Group.class, 1);
s.delete(g);
//s.createQuery("delete from User u where u.id = 1").executeUpdate();
s.getTransaction().commit();

}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值