1.单向 N:1 无中间表
例如:一个地方有多个人住.
每个同学记住老师,比老师记住每个同学简单.
(在 n 的一端进行配置效率高)
N 1
Person : Address
Student : Teacher
注意:这样在Person中会多一列 对address_id 的外键引用列
Pesron
Address
//test
注意:cascade="all"
会出现异常:
例如:一个地方有多个人住.
每个同学记住老师,比老师记住每个同学简单.
(在 n 的一端进行配置效率高)
N 1
Person : Address
Student : Teacher
注意:这样在Person中会多一列 对address_id 的外键引用列
Pesron

Address

public class Address {
private Integer aid;
private String addressDetail;
//set get ...
}
public class Person {
private Integer pid;
private String name;
private int age;
private Address address; //单向(N:1) 反过来(1:1)
//set get...
}
#主表
DROP TABLE IF EXISTS mytest.address;
CREATE TABLE mytest.address
(
aid INTEGER NOT NULL,
addressdesc VARCHAR (400),
PRIMARY KEY (aid)
);
#子表
DROP TABLE IF EXISTS mytest.person;
CREATE TABLE mytest.person
(
pid INTEGER NOT NULL,
name VARCHAR (50) NOT NULL,
age TINYINT NOT NULL DEFAULT 0,
address_id INTEGER,
PRIMARY KEY (pid),
KEY address_id (address_id),
CONSTRAINT person_ibfk_1 FOREIGN KEY (address_id) REFERENCES address (aid)
);
<!--person--> <hibernate-mapping package="com.sh.study.model"> <class name="Person" table="PERSON"> <id name="pid" type="java.lang.Integer" column="PID"> <generator class="increment"/> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="age" type="int"> <column name="AGE" /> </property> <!--name就是 Person中 的那个 address cascade="all" --> <many-to-one name="address" cascade="all" class="Address" column="address_id"> </many-to-one> </class> </hibernate-mapping> <!--address--> <hibernate-mapping package="com.sh.study.model"> <class name="Address" table="ADDRESS"> <id name="aid" type="java.lang.Integer" column="AID"> <generator class="increment"/> </id> <property name="addressdesc" type="java.lang.String"> <column name="ADDRESSDESC" /> </property> </class> </hibernate-mapping>
//test
public class TestHibernate {
private ApplicationContext act;
private SessionFactory factory;
@Before
public void init(){
act = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
factory= act.getBean("sessionFactory",SessionFactory.class);
}
//测试 无 中间表的 N:1 关系
@Test
public void test1() {
Session session=factory.getCurrentSession();
Transaction tx=session.beginTransaction();
Person p=new Person();
p.setAge(12);
p.setName("Yeeku");
Address address=new Address();
address.setAddressdesc("北京海淀区");
p.setAddress(address);
//持久化对象
session.persist(p);
session.flush();
tx.commit();
//如果不是使用的SessionFactory.getSession()来获得Session。
//而是使用SessionFactory.getCurrentSession()方法来获得Session时,
//当事务结束的时候,不管是提交还是回滚事务,hibernate会自动关闭Session的,
//session.close();
}
//测试 无 中间表的 N:1 关系
@Test
public void test2() {
Session session=factory.getCurrentSession();
Transaction tx=session.beginTransaction();
Person p=new Person();
p.setAge(12);
p.setName("Yeeku");
Address address=new Address();
address.setAddressdesc("北京海淀区");
p.setAddress(address);
//持久化对象
session.persist(p);
//修改 Person的 地址
Address address1=new Address();
address1.setAddressdesc("上海虹口");
p.setAddress(address1);
tx.commit();
}
}
注意:cascade="all"
<!--如果Person配置--> <hibernate-mapping package="com.sh.study.model"> <class name="Person" table="PERSON"> <id name="pid" type="java.lang.Integer" column="PID"> <generator class="increment"/> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="age" type="int"> <column name="AGE" /> </property> <!--如果少了 下面这个 cascade="all" --> <many-to-one name="address" class="Address" column="address_id"> </many-to-one> </class> </hibernate-mapping>
会出现异常:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.sh.study.model.Address
