hibernate 关系映射
one-to-one主要有三种实现方式
1.通过外键方式实现
以学生和电脑为例(Student-Computer)
建表sql语句:
Java代码
CREATE DATABASE `onetoone` CHARACTER SET
'utf8'; USE `onetoone`; DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id`
int(
11) NOT NULL auto_increment, `name` varchar(
255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `computer`; CREATE TABLE `computer` ( `id`
int(
11) NOT NULL auto_increment, `name` varchar(
255) NOT NULL, `student_id`
int(
11) , foreign key (`student_id`) references student(`id`), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[java]
view plain
copy
CREATE DATABASE `onetoone` CHARACTER SET
'utf8'; USE `onetoone`; DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id`
int(
11) NOT NULL auto_increment, `name` varchar(
255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `computer`; CREATE TABLE `computer` ( `id`
int(
11) NOT NULL auto_increment, `name` varchar(
255) NOT NULL, `student_id`
int(
11) , foreign key (`student_id`) references student(`id`), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Student.java:
Java代码
package com.domain;
public class Student
implements java.io.Serializable {
private Integer id;
private String name;
private Computer computer;
public Student() { }
public Student(String name) {
this.name = name; }
public Integer getId() {
return this.id; }
public void setId(Integer id) {
this.id = id; }
public String getName() {
return this.name; }
public void setName(String name) {
this.name = name; }
public Computer getComputer() {
return computer; }
public void setComputer(Computer computer) {
this.computer = computer; } }
[java]
view plain
copy
package com.domain;
public class Student
implements java.io.Serializable {
private Integer id;
private String name;
private Computer computer;
public Student() { }
public Student(String name) {
this.name = name; }
public Integer getId() {
return this.id; }
public void setId(Integer id) {
this.id = id; }
public String getName() {
return this.name; }
public void setName(String name) {
this.name = name; }
public Computer getComputer() {
return computer; }
public void setComputer(Computer computer) {
this.computer = computer; } }
Computer.java:
Java代码
package com.domain;
public class Computer
implements java.io.Serializable {
private Integer id;
private Student student;
private String name;
public Computer() { }
public Computer(String name) {
this.name = name; }
public Computer(Student student, String name) {
this.student = student;
this.name = name; }
public Integer getId() {
return this.id; }
public void setId(Integer id) {
this.id = id; }
public Student getStudent() {
return this.student; }
public void setStudent(Student student) {
this.student = student; }
public String getName() {
return this.name; }
public void setName(String name) {
this.name = name; } }
[java]
view plain
copy
package com.domain;
public class Computer
implements java.io.Serializable {
private Integer id;
private Student student;
private String name;
public Computer() { }
public Computer(String name) {
this.name = name; }
public Computer(Student student, String name) {
this.student = student;
this.name = name; }
public Integer getId() {
return this.id; }
public void setId(Integer id) {
this.id = id; }
public Student getStudent() {
return this.student; }
public void setStudent(Student student) {
this.student = student; }
public String getName() {
return this.name; }
public void setName(String name) {
this.name = name; } }
Student.hbm.xml:
Java代码
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE
hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <
hibernate-mapping> <
class name=
"com.domain.Student" table=
"student" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <generator
class=
"native" /> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!--
class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 --> <
one-to-one cascade=
"delete,save-update" name=
"computer" class=
"com.domain.Computer" property-ref=
"student"></
one-to-one> </
class> </
hibernate-mapping>
[java]
view plain
copy
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE <span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC
"-//<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span>/<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span> Mapping DTD 3.0//EN" "http://<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>.sourceforge.net/<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>-mapping-3.0.dtd"> <<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping> <
class name=
"com.domain.Student" table=
"student" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <generator
class=
"native" /> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!--
class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 --> <<span
class=
"hilite2"><span style=
"background-color: #55ff55;">one-to-one</span></span> cascade=
"delete,save-update" name=
"computer" class=
"com.domain.Computer" property-ref=
"student"></<span
class=
"hilite2"><span style=
"background-color: #55ff55;">one-to-one</span></span>> </
class> </<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping>
Computer.hbm.xml:
Java代码
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE
hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <
hibernate-mapping> <
class name=
"com.domain.Computer" table=
"computer" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <generator
class=
"native" /> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!-- many开头的是代表该表持有外键 --> <many-to-one name=
"student" class=
"com.domain.Student" unique=
"true"> <column name=
"student_id" /> </many-to-one> </
class> </
hibernate-mapping>
[java]
view plain
copy
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE <span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC
"-//<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span>/<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span> Mapping DTD 3.0//EN" "http://<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>.sourceforge.net/<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>-mapping-3.0.dtd"> <<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping> <
class name=
"com.domain.Computer" table=
"computer" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <generator
class=
"native" /> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!-- many开头的是代表该表持有外键 --> <many-to-one name=
"student" class=
"com.domain.Student" unique=
"true"> <column name=
"student_id" /> </many-to-one> </
class> </<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping>
测试类:
Java代码
package com.domain;
import org.
hibernate.Query;
import org.
hibernate.Session;
import com.util.HibernateSessionFactory;
public class Test {
public static void main(String[] args){ Session session = HibernateSessionFactory.getSession(); Student student =
new Student(); student.setName(
"student9"); Computer computer =
new Computer(); computer.setName(
"Intel 9"); computer.setStudent(student); student.setComputer(computer); session.save(student); session.beginTransaction().commit(); session.close(); } }
[java]
view plain
copy
package com.domain;
import org.<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>.Query;
import org.<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>.Session;
import com.util.HibernateSessionFactory;
public class Test {
public static void main(String[] args){ Session session = HibernateSessionFactory.getSession(); Student student =
new Student(); student.setName(
"student9"); Computer computer =
new Computer(); computer.setName(
"Intel 9"); computer.setStudent(student); student.setComputer(computer); session.save(student); session.beginTransaction().commit(); session.close(); } }
2.通过主键方式实现(一个表的主键由另一个表的主键决定),在这里Computer的主键由Student的主键决定。
Student.hbm.xml:
Java代码
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE
hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <
hibernate-mapping> <
class name=
"com.domain.Student" table=
"student" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <generator
class=
"native" /> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!--
class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 <
one-to-one cascade=
"delete,save-update" name=
"computer" class=
"com.domain.Computer" property-ref=
"student"></
one-to-one> --> <
one-to-one name=
"computer"/> </
class> </
hibernate-mapping>
[java]
view plain
copy
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE <span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC
"-//<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span>/<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span> Mapping DTD 3.0//EN" "http://<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>.sourceforge.net/<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>-mapping-3.0.dtd"> <<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping> <
class name=
"com.domain.Student" table=
"student" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <generator
class=
"native" /> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!--
class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 <<span
class=
"hilite2"><span style=
"background-color: #55ff55;">one-to-one</span></span> cascade=
"delete,save-update" name=
"computer" class=
"com.domain.Computer" property-ref=
"student"></<span
class=
"hilite2"><span style=
"background-color: #55ff55;">one-to-one</span></span>> --> <<span
class=
"hilite2"><span style=
"background-color: #55ff55;">one-to-one</span></span> name=
"computer"/> </
class> </<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping>
Comuter.hbm.xml:
Java代码
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE
hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <
hibernate-mapping> <
class name=
"com.domain.Computer" table=
"computer" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <!--generator
class=
"native" /--> <!--Computer的主键由Student的主键决定,可以看成是外键--> <generator
class=
"foreign"> <param name=
"property">student</param> </generator> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!-- many开头的是代表该表持有外键 <many-to-one name=
"student" class=
"com.domain.Student" unique=
"true"> <column name=
"student_id" /> </many-to-one> --> <
one-to-one name=
"student"/> </
class> </
hibernate-mapping>
[java]
view plain
copy
<?xml version=
"1.0" encoding=
"utf-8"?> <!DOCTYPE <span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC
"-//<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span>/<span class="hilite1
"><span style="background-color: #ffff00;
">Hibernate</span></span> Mapping DTD 3.0//EN" "http://<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>.sourceforge.net/<span class="hilite1
"><span style="background-color: #ffff00;
">hibernate</span></span>-mapping-3.0.dtd"> <<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping> <
class name=
"com.domain.Computer" table=
"computer" catalog=
"onetoone"> <id name=
"id" type=
"java.lang.Integer"> <column name=
"id" /> <!--generator
class=
"native" /--> <!--Computer的主键由Student的主键决定,可以看成是外键--> <generator
class=
"foreign"> <param name=
"property">student</param> </generator> </id> <property name=
"name" type=
"java.lang.String"> <column name=
"name" not-
null=
"true" /> </property> <!-- many开头的是代表该表持有外键 <many-to-one name=
"student" class=
"com.domain.Student" unique=
"true"> <column name=
"student_id" /> </many-to-one> --> <<span
class=
"hilite2"><span style=
"background-color: #55ff55;">one-to-one</span></span> name=
"student"/> </
class> </<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>-mapping>
TestMainKey.java:
Java代码
package com.domain;
import org.
hibernate.Session;
import com.util.HibernateSessionFactory;
public class TestMainKey {
public static void main(String[] args){ Session session = HibernateSessionFactory.getSession(); Student student =
new Student(); student.setName(
"student15"); Computer computer =
new Computer(); computer.setName(
"Intel 15"); computer.setStudent(student); session.save(student); session.save(computer); session.beginTransaction().commit(); session.close(); } }
[java]
view plain
copy
package com.domain;
import org.<span
class=
"hilite1"><span style=
"background-color: #ffff00;">hibernate</span></span>.Session;
import com.util.HibernateSessionFactory;
public class TestMainKey {
public static void main(String[] args){ Session session = HibernateSessionFactory.getSession(); Student student =
new Student(); student.setName(
"student15"); Computer computer =
new Computer(); computer.setName(
"Intel 15"); computer.setStudent(student); session.save(student); session.save(computer); session.beginTransaction().commit(); session.close(); } }
3.通过关系表实现:
Java代码
DROP TABLE IF EXISTS `st`; create table stu_com( stu_id
int not
null, com_id
int not
null )ENGINE=InnoDB DEFAULT CHARSET=utf8;
[java]
view plain
copy
DROP TABLE IF EXISTS `st`; create table stu_com( stu_id
int not
null, com_id
int not
null )ENGINE=InnoDB DEFAULT CHARSET=utf8;
Java代码
<!--optional=
"true"的意思是只有当stu_id 和 com_id 都不为空时才在关系表里插入。这样也会插入
2遍,所以需要inverse=
"true"把一方设置为虚的。即不让插入到关系表中--> <join table=
"stu-com" optional=
"true" inverse=
"true"> <key column=
"com_id"/> <many-to-one name=
"student" column=
"stu_id" unique=
"true"/> </join>
[java]
view plain
copy
<!--optional=
"true"的意思是只有当stu_id 和 com_id 都不为空时才在关系表里插入。这样也会插入
2遍,所以需要inverse=
"true"把一方设置为虚的。即不让插入到关系表中--> <join table=
"stu-com" optional=
"true" inverse=
"true"> <key column=
"com_id"/> <many-to-one name=
"student" column=
"stu_id" unique=
"true"/> </join>