hibernate单向关系共4种(N对1、1对N、1对1、多对多 )。
1.N对1(many-to-one)
多对一关联映射原理:在多的一端加入一个外键,指向一的一端
例如:部门(Dept)和员工(User)对应关系。 多个员工属于一个部门,一个部门拥有多个员工。
多对一,多的一端(User)加入一个外键(dept属性),指向一的一端(Dept)
开发步骤:
- 在多的一端(User)加入一个外键(dept属性)。
- 一的一端(Dept)无特殊属性。
- 多的一端hbm.xml中外键属性设置many-to-one标签。
- 一的一端hbm.xml无特殊设置。
public class User {
private Integer id;
private String username;
private Dept dept;
public class Dept {
private Integer id;
private String name;
User.hbm.xml
<hibernate-mapping>
<class name="com.zm.dan.User" table="tb_user">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="username" type="java.lang.String">
<column name="USERNAME" />
</property>
<many-to-one name="dept" class="com.zm.dan.Dept">
<column name="deptid" />
</many-to-one>
</class>
</hibernate-mapping>
Dept.hbm.xml 没有什么特殊
<hibernate-mapping>
<class name="com.zm.dan.Dept" table="tb_dept">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
5.查看数据库表结构
CREATE TABLE `tb_user` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`USERNAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`deptid` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `FKh8px1rylx3cr6u2u54dffo6n1` (`dept2`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
CREATE TABLE `tb_dept` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
2. 1对N(one-to-many)
一对多关联映射和多对一关联映射原理相同:都是在多的一端加入一个外键,指向一的一端
例如:部门(Dept)和员工(User)对应关系。一个部门拥有多个员工, 多个员工属于一个部门。
开发步骤
- 在一的一端(Dept)加入一个Set集合。
- 多的一端(User)无特殊属性。
- 在一的一端hbm.xml中外键属性设置one-to-many标签。
- 多的一端hbm.xml无特殊设置。
public class Dept1 {
private Integer id;
private String name;
private Set<User> user = new HashSet<User>();
public class User {
private Integer id;
private String username;
Dept.hbm.xml
<hibernate-mapping>
<class name="com.zm.dan.Dept" table="tb_dept">
<id name="id" type="integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<set name="user" table="tb_user">
<key>
<column name="user_ID" />
</key>
<one-to-many class="com.zm.dan.User" />
</set>
</class>
</hibernate-mapping>
User.hbm.xml 无特殊处理
<hibernate-mapping>
<class name="com.zm.dan.User" table="tb_user">
<id name="id" type="integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="username" type="java.lang.String">
<column name="USERNAME" />
</property>
</class>
</hibernate-mapping>
5.查看数据库表结构
CREATE TABLE `tb_dept` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
CREATE TABLE `tb_user` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`USERNAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`user_ID` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `FK9gvhnmegmprw358834phc1ns7` (`user_ID`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
6.N对1和1对N的对比:
表结构基本相同
3. 1对1
一对一的关联映射有两种策略:
*主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。
*唯一外键关联:外键关联,本来是用于多对一的配置,但是加上唯一的限制之后(采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一),也可以用来表示一对一关联关系,其实它就是多对一的特殊情况。
因为一对一的主键关联映射扩展性不好,当我们的需要发生改变想要将其变为一对多的时候变无法操作了,所以我们遇到一对一关联的时候经常会采用唯一外键关联来解决问题,而很少使用一对一主键关联。
本次实例只讲唯一外键关联。
例如:Person(人)-Card(身份证)
开发步骤
- Person端加上card属性
- Card端无特殊属性。
- Person.hbm.xml中设置many-to-one标签。
- Card.hbm.xml无特殊设置。
public class Card {
private Integer id;
private String name;
public class Person {
private Integer id;
private String address;
private Card card;
Person.hbm.xml
<hibernate-mapping>
<class name="com.zm.dan.Person" table="tb_person">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
<many-to-one name="card" class="com.zm.dan.Card" fetch="join">
<column name="card_id" />
</many-to-one>
</class>
</hibernate-mapping>
Card.hbm.xml
<hibernate-mapping>
<class name="com.zm.dan.Card" table="tb_card">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
5.查看数据库表结构
CREATE TABLE `tb_card` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
CREATE TABLE `tb_person` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ADDRESS` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`card_id` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `FK12ytkg5bhmufatt6smjuig7ym` (`card_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
4. 多对多
例如 User和Role关系。一个用户有多个角色,一个角色属于多个用户。
需要额外创建一张中间表。中间表保存2张表的主键对应关系。
其中user_role表中的
开发步骤
- User 端加上Set集合roles
- Role 端无特殊属性。
- User.hbm.xml中设置many-to-many标签。
- Role.hbm.xml无特殊设置。
public class User {
private Integer id;
private String name;
private Set<Role> roles = new HashSet<Role>();
public class Role {
private Integer id;
private String roleName;
User.hbm.xml
<hibernate-mapping>
<class name="com.zm.dan.User" table="tb_USER">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<set name="roles" table="user_role">
<key>
<column name="userid" />
</key>
<many-to-many class="com.zm.dan.Role" column="roleid" />
</set>
</class>
</hibernate-mapping>
Role.hbm.xml
<hibernate-mapping>
<class name="com.zm.dan.Role" table="tb_role">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="roleName" type="java.lang.String">
<column name="ROLENAME" />
</property>
</class>
</hibernate-mapping>
5.查看数据库表结构
CREATE TABLE `tb_user` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
CREATE TABLE `tb_role` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ROLENAME` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
CREATE TABLE `user_role` (
`userid` int(11) NOT NULL,
`roleid` int(11) NOT NULL,
PRIMARY KEY (`userid`,`roleid`),
KEY `FKbndaluoh2g1028qhffdjaxt0j` (`roleid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
6.总结。
创建了3张表,tb_user、tb_role、user_role。