package com.darren.relation.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="t_group")
public class Group {
private int id;
private Stringname;
private Set<User>users = newHashSet<User>();
// feteh对读有效
//cascade 对增,删,改有效
@OneToMany(mappedBy="group", cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
public Set<User> getUsers() {
returnusers;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Id
@GeneratedValue
public int getId() {
returnid;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name = name;
}
}
package com.darren.relation.model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="t_user")
public class User {
private int id;
private Stringname;
private Groupgroup;
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="group_id_id")
public Group getGroup() {
returngroup;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getId() {
returnid;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name = name;
}
}
package com.darren.relation.model;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class ManyToOneTest {
private static SessionFactory sessionFactory;
@BeforeClass
public static void beforeClass() {
new SchemaExport(newAnnotationConfiguration().configure()).create(false,true);
sessionFactory =newAnnotationConfiguration().configure().buildSessionFactory();
}
@AfterClass
public static void afterClass() {
sessionFactory.close();
}
@Test
public void test1() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = new User();
user.setName("darren");
Group group = new Group();
group.setName("zhang");
user.setGroup(group);
session.save(group);
session.save(user);
transaction.commit();
// 此时会把两张表全存进数据库,包括外键
}
@Test
public void test2() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = new User();
user.setName("darren");
Group group = new Group();
group.setName("zhang");
user.setGroup(group);
// session.save(group);
session.save(user);
transaction.commit();
// 此时会报错,因为group对象没有被保存到数据库,当然前提是没有设置cascade条件
}
@Test
public void test3() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = new User();
user.setName("darren");
Group group = new Group();
group.setName("zhang");
user.setGroup(group);
// session.save(group);
session.save(user);
transaction.commit();
// 此时不会报错,因为User中的@ManyToOne(cascade={CascadeType.ALL})设置了cascade级联条件
}
@Test
public void test4() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Set<User> users = newHashSet<User>();
User user = new User();
user.setName("darren");
// session.save(user);
users.add(user);
Group group = new Group();
group.setName("zhang");
group.setUsers(users);
session.save(group);
transaction.commit();
// 此时只存了group,因为没有Group里有设置cascade,不会级联更新
}
@Test
public void test5() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Set<User> users = newHashSet<User>();
User user = new User();
user.setName("darren");
// session.save(user);
users.add(user);
Group group = new Group();
group.setName("zhang");
group.setUsers(users);
session.save(group);
transaction.commit();
// 此时会存储User因为Group设置了 @OneToMany(mappedBy="group",cascade={CascadeType.ALL})
// 但是不会存外键,因为Group里的mappedBy指向的是group,group被存在User中才会自动维护外键关系
//而此时刚好相反,是Group里存了users,因此不会有外键
}
@Test
public void test6() {
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Set<User> users = newHashSet<User>();
User user = new User();
user.setName("darren");
// session.save(user);
users.add(user);
Group group = new Group();
group.setName("zhang");
group.setUsers(users);
user.setGroup(group);//此时存储了外键,因为use里存了group
session.save(group);
transaction.commit();
}
@Test
public void test7() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = (User)session.get(User.class, 1);
transaction.commit();
// 此时取User的时候会把group取出来,因为默认状态下,多方可以直接把一方取出来
}
@Test
public void test8() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Group group = (Group)session.get(Group.class, 1);
transaction.commit();
// 此时取group的时候不会把user取出来,因为默认状态下,一方不可以直接把多方取出来
}
@Test
public void test9() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Group group = (Group)session.get(Group.class, 1);
transaction.commit();
// 此时取group的时候会把user取出来,因为设置了@OneToMany(mappedBy="group", cascade={CascadeType.ALL},fetch=FetchType.EAGER)
//fetch=FetchType.EAGER 会直接取出与其关联的数据
// feteh 对读有效
//cascade 对增,删,改有效
}
@Test
public void test10() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = (User)session.get(User.class, 1);
transaction.commit();
// 如果在user断设置了fetch=FetchType.LAZY @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
// 那么就去不到group了
}
@Test
public void test11() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = (User) session.get(User.class, 1);
System.out.println(user.getGroup().getName());
transaction.commit();
// 如果在user断设置了fetch=FetchType.LAZY @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
// 那么就去不到group了
// 这样的话可以通过调用一下group里的一个属性,就可以取到group了
// user.getGroup().getName()
}
@Test
public void test12() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = (User) session.get(User.class, 1);
transaction.commit();
System.out.println(user.getGroup().getName());
// 如果在user断设置了fetch=FetchType.LAZY @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
// 那么就去不到group了
// 这样的话可以通过调用一下group里的一个属性,就可以取到group了
// user.getGroup().getName()
// 此时如果把System.out.println(user.getGroup().getName());放到了commit之后就会报错“懒加载”
// 因为此时的session已经关闭了
// 讲一下懒加载
// 在不是懒加载的时候取user的时候同时会把与之关联的group取出来放到内存里,这时不管session关闭与否,
// 都可以从内存中取出group
// 如果是懒加载取user的时候不会同时把与之关联的group取出来放到内存中,如果放到commit之后去取
// 先到内存中找,内存中没有,再到数据库中找,但是此时的session已经关闭了,和数据库没有关系了
// 所以就抛异常
// 如果是在commit之前去取,它又会把group取出来放到内存中,之后再在commit之后去用就不会报异常了
// 这就是解决懒加载的一种方法
}
@Test
public void test13() {
test6();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
User user = (User) session.load(User.class, 1);
System.out.println(user.getGroup().getName());
transaction.commit();
// 此时的load和test12中的get一样效果,不同的就是get方法是立即发sql语句,调用group的时候再发一条
// 而load不同,load执行之后不会立即发sql语句,等到调用group的时候才会发,并且此时一次发两条
}
}