您的位置:首页 > 移动开发

Hibernate 一对多注解 mappedby 作用

2016-08-10 00:00 211 查看
只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;

mappedBy标签一定是定义在被拥有方的,他指向拥有方即(定义在不维护关系的那一方);

mappedBy的含义,应该理解为,拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以做到的;

mappedBy跟joinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy这方定义JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表。

双向一对一例子:

人跟身份证双向一对一的关联

在Person里面定义的注解:

在person里面定义的注释代码

@OneToOne(cascade = CascadeTye.ALL,optional = true)

public IDCard getIdCard(){

return idCard;

}

在idcard里面定义的注释代码

/*身份证不负责维护关系,所以mappedBy定义在idcard类中,值为Person类中idCard的属性名*/

/*它表示当前所在表和Person的关系是定义在Person里面的idCard这个成员上面的,他表示此表是一对一关系中的从表,也就是关系是在person表中维护的,这是最重要的.*/

@OneToOne(cascade = CascadeType.ALL,mappedBy = "idCard",optional = false)

public Person getPerson(){

return person;

}

package oneToMany;
import java.util.Set;
import javax.persistence.*;
/*
注意导入时,是导入:import javax.persistence.*;
非导入org.hibernate的相关类:import org.hibernate.annotations.Entity;
*/
@Entity
@Table(name="classes")
public class Classes implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;

@OneToMany(cascade=CascadeType.ALL,mappedBy="classes")
private Set<Student> students;
//getter,setter省略
}

package oneToMany;
import javax.persistence.*;
@Entity
@Table(name="student")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int sid;

private String sname;

//若有多个cascade,可以是:{CascadeType.PERSIST,CascadeType.MERGE}
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="classid") //student类中对应外键的属性:classid
private Classes classes;
//getter,setter省略
}

public class TestOneToMany {
/*
CREATE TABLE student ( --要定义外键!!!!!!!
`sid` double NOT NULL auto_increment,
`classid` double NULL,
`sname` varchar(255) NOT NULL,
PRIMARY KEY (sid),
INDEX par_ind (classid),
FOREIGN KEY (classid) REFERENCES classes(id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
*/
public static void main(String[] args) throws SQLException
{
try
{
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();

/*

因为mappedBy是定义在classes中,即classes类不负责维护级联关系.即维护者是student.所以,

1.要将clsses的数据,赋给student,即用student的setClasses()方法去捆定class数据;

2.在进行数据插入/更新session.save()/session.update()时,最后操作的是student.

*/
Classes classes=new Classes();
classes.setName("access");

Student st1=new Student();
st1.setSname("jason");

//用主动维护关系的一方来插入数据
st1.setClasses(classes);
session.save(st1);

Student st2=new Student();
st2.setSname("hwj");
st2.setClasses(classes);
session.save(st2);
tx.commit();

/*

输出如下:

Hibernate: insert into classes (name) values (?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)

*/

/*

因为一端维护关系另一端不维护关系的原因,我们必须注意避免在应用中用不维护关系的类(class)建立关系,因为这样建立的关系是不会在数据库中存储的。

如上的代码倒过来,则插入时,student的外键值为空.如下:

*/

// Student st1=new Student();
// st1.setSname("jason");
// session.save(st1);
//
// Student st2=new Student();
// st2.setSname("hwj");
// session.save(st2);
//
// Set<Student> students=new HashSet<Student>();
// students.add(st1);
// students.add(st2);
//
// Classes classes=new Classes();
// classes.setName("access");
// classes.setStudents(students);
// session.save(classes);

/*

输出如下:
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)

Hibernate: insert into classes (name) values (?)

*/
}
catch(HibernateException e)
{
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: