从hibernate 2.5开始就可以使用annotation实现实体关系的映射了,减少了配置hbm文件的繁琐,而且annotation也是一种趋势,现在的SSH2的整合都是完全可以用annotation来实现。在以前实现一对多关联的关联式都是使用hbm文件,今天我们来使用annotation试试,同样也能实现其功能。
1.数据库:oracle数据库,有person和address二张表,一对多的关系。数据库:
[java] view plain copy
create table person
(
id number(4) not null,
uname varchar (20)
);
create table address
(
id number(4) not null,
address varchar(20) not null,
personId number(4) not null
)
alter table person
add constraint primary_id parmary key(id)
deferrable initially deferred;
2.Person实体类:[java] view plain copy
<span style="font-size:14px;">package com.zengguo.po;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@SuppressWarnings(“serial”)
@Entity
@Table(name = “person”)
public class Person implements Serializable {
//oracle 序列
@Id
@GenericGenerator(name = “personGenericGenerator”, strategy = “sequence”,
parameters = { @Parameter(value = “hibernate_seq”, name = “sequence”) })
@GeneratedValue(generator=”personGenericGenerator”)
private long id;
@Column(name=”uname”)
private String uname;
@OneToMany(targetEntity=Address.class,cascade=CascadeType.ALL)
@Fetch(FetchMode.JOIN)
//updatable=false很关键,如果没有它,在级联删除的时候就会报错(反转的问题)
@JoinColumn(name=”personId”,updatable=false)
private Set<Address> sets = new HashSet<Address>();
public Set<Address> getSets() {
return sets;
}
public void setSets(Set<Address> sets) {
this.sets = sets;
}
public Person() {
super();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}</span>
3.Address实体类[java] view plain copy
<span style="font-size:14px;">package com.zengguo.po;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@SuppressWarnings(“serial”)
@Entity
@Table(name = “address”)
public class Address implements java.io.Serializable {
//使用序列生成主键
@Id
@GenericGenerator(name = “addressGenericGenerator”, strategy = “sequence”,
parameters = { @Parameter(value = “hibernate_seq”, name = “sequence”) })
@GeneratedValue(generator = “addressGenericGenerator”)
private long id;
@Column(name = “address”)
private String address;
//多对一,@JoinColumn与@column类似,指定映射的数据库字段
@ManyToOne(targetEntity = Person.class)
@JoinColumn(name=”personId”,updatable=false)
private Person person;
public Address() {
super();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}</span>
hibernate一对多mappedBy的用法:(班级classes和学生student,一对多的关系)
[java] view plain copy
<span style="font-size:14px;">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();
}
}
}
</span>
|