主键关联的重点是关联的两个表共享一个主键值。本例中采用,一个单位在网上的一个系统中注册会员。

1,会员数据保存在会员表company中,每个会员的登录账号保存在表login中;

2,一个会员只有一个登录账号,一个登录账号只属于一个会员,两表是一对一的对应关系;

company表如下:

生成company表的sql语句如下:

CREATE TABLE `company` (
`ID`  int(4) NOT NULL AUTO_INCREMENT ,
`COMPANYNAME`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`LINKMAN`  char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`TELEPHONE`  char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`EMAIL`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY (`ID`)
)

login表如下:


生成login表的sql语句如下:

<pre name="code" class="sql">CREATE TABLE `login` (
`ID`  int(4) NOT NULL ,
`LOGINNAME`  char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`LOGINPWD`  char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY (`ID`)
)

外键关联的重点是:两个表各自有不同的主键,但是其中一个表有一个外键引用另一个表的主键。即非主键是别人的主键就是该表的外键。

这个例子中:

1,客户(Client)和客户地址(Address)是外键关联的一对一关系,分别对应client表换个address表。

2,Client类在映射文件中的client_address为外键引用Address类的对应表中的主键,咋一看书多对一关系,但是在Client类对应的映射文件设置多对一对应的属性client_address时,设置了unique的值为true,即这个外键是唯一的,即一对一关系。

client表如下:

生成client表的sql语言:

CREATE TABLE `client` (
`ID`  int(4) NOT NULL AUTO_INCREMENT ,
`CLIENTNAME`  char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`PHONE`  char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`EMAIL`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`CLIENTADDRESSID`  int(4) NULL DEFAULT NULL ,
PRIMARY KEY (`ID`),
FOREIGN KEY (`CLIENTADDRESSID`) REFERENCES `address` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `CLIENTADDRESSID` (`CLIENTADDRESSID`) USING BTREE
)

注意:这里的CLIENTADDRESSID是外键,client表也要设置外键

address表如下:

CREATE TABLE `address` (
`ID`  int(4) NOT NULL AUTO_INCREMENT ,
`PROVINCE`  varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`CITY`  varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`STREET`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`ZIPCODE`  char(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY (`ID`)
)

hibernate.cfg.xml配置文件:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration><session-factory><property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property><property name="connection.url">jdbc:mysql://localhost:3306/onetoone</property><property name="connection.username">root</property><property name="connection.password">123456</property><property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 显示sql语句 --><property name="hibernate.show_sql">true </property>  <property name="format_sql">true</property><!-- 让输出的sql语句格式化 --><mapping resource="com/hust/javabeans/Address.hbm.xml" /><mapping resource="com/hust/javabeans/Client.hbm.xml"  /><mapping resource="com/hust/javabeans/Company.hbm.xml" /><mapping resource="com/hust/javabeans/Login.hbm.xml"    /></session-factory></hibernate-configuration>

一对一主键双向关联:

Company.java

package com.hust.javabeans;
import java.io.Serializable;
public class Company implements Serializable {/*** */private Integer id;private String companyname;private String linkman;private String telephone;private String email;private Login login;       //关联另外一个类,即保证Company对象中有Login对象的信息,体现一对一关联public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getCompanyname() {return companyname;}public void setCompanyname(String companyname) {this.companyname = companyname;}public String getLinkman() {return linkman;}public void setLinkman(String linkman) {this.linkman = linkman;}public String getTelephone() {return telephone;}public void setTelephone(String telephone) {this.telephone = telephone;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Login getLogin() {return login;}public void setLogin(Login login) {this.login = login;}}

Login.java

package com.hust.javabeans;
import java.io.Serializable;
public class Login implements Serializable {/*** */private static final long serialVersionUID = 1L;private Integer id;private String loginname;private String loginpwd;private Company company;   //关联另外一个类,即保证Login对象中有Company对象的信息,体现一对一关联public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getLoginname() {return loginname;}public void setLoginname(String loginname) {this.loginname = loginname;}public String getLoginpwd() {return loginpwd;}public void setLoginpwd(String loginpwd) {this.loginpwd = loginpwd;}public Company getCompany() {return company;}public void setCompany(Company company) {this.company = company;}}

Company.hbm.xml

<?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.hust.javabeans.Company" table="company"><id column="ID" name="id" type="integer"><generator class="identity"></generator></id><property name="companyname" column="COMPANYNAME" type="string"></property><property name="linkman"     column="LINKMAN" type="string"></property><property name="telephone"   column="TELEPHONE" type="string"></property><property name="email"       column="EMAIL" type="string"></property><!-- 映射Company与Login的一对一主键关联 --><one-to-one name="login" class="com.hust.javabeans.Login" cascade="all" lazy="false" fetch="join" outer-join="true"></one-to-one></class>
</hibernate-mapping>

Login.hbm.xml

<?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.hust.javabeans.Login" table="login"><!-- 使用外键生成机制(foreign),引用表company的主键作为login表的主键值 ,定义了外键的生成策略,这样可以在级联插入时保持company的主键和login的外键(也是主键)相同。--><id name="id" column="ID" type="integer"><generator class="foreign"><param name="property">company</param></generator></id><property name="loginname" column="LOGINNAME" type="string"></property><property name="loginpwd" column="LOGINPWD" type="string"></property><!-- 映射Company与Login的一对一主键关联 --> <one-to-one name="company" class="com.hust.javabeans.Company" constrained="true"></one-to-one><!-- constrained="true"表示Login引用了company的主键作为外键 --></class>
</hibernate-mapping>

一对一外键双向关联:

Client.java

package com.hust.javabeans;import java.io.Serializable;public class Client implements Serializable {private Integer id;private String clientname;private String phone;private String email;private Address client_address;  //关联另一个类public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getClientname() {return clientname;}public void setClientname(String clientname) {this.clientname = clientname;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Address getClient_address() {return client_address;}public void setClient_address(Address client_address) {this.client_address = client_address;}}

Address.java

package com.hust.javabeans;
import java.io.Serializable;
public class Address implements Serializable {private Integer id;private String province;private String city;private String street;private String zipcode;private Client address_client;//关联另外一个类public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getStreet() {return street;}public void setStreet(String street) {this.street = street;}public String getZipcode() {return zipcode;}public void setZipcode(String zipcode) {this.zipcode = zipcode;}public Client getAddress_client() {return address_client;
}public void setAddress_client(Client address_client) {this.address_client = address_client;
}}

Client.hbm.xml

<?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.hust.javabeans.Client" table="client"><id name="id" column="ID"  type="integer"><generator class="identity"></generator></id><property name="clientname" column="CLIENTNAME" type="string"></property><property name="phone" column="PHONE" type="string"></property><property name="email" column="EMAIL" type="string"></property><!-- 映射Client和Address的一对一外键关联,唯一多对一,实际上时一对一关系,这里的name是Client的属性,column是client表的外键--><many-to-one name="client_address" class="com.hust.javabeans.Address" column="CLIENTADDRESSID" cascade="all" lazy="false" unique="true"></many-to-one></class>
</hibernate-mapping>

<many-to-one unique="true"> 标签在这里表示一对一,many-to-one应该写在有外键的那个表对应的映射文件中

Address.hbm.xml

<?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.hust.javabeans.Address" table="address"><id column="ID" name="id" type="integer"><generator class="identity"/></id><property name="province" column="PROVINCE"  type="string"/><property name="city"     column="CITY"    type="string"/><property name="street"   column="STREET"  type="string"/><property name="zipcode"  column="ZIPCODE" type="string"/><!-- 映射Client和Address的一对一外键关联,name是Address的属性,property-ref是Client中的属性<span style="font-family:Arial, Helvetica, sans-serif;">client_address--></span><one-to-one name="address_client" class="com.hust.javabeans.Client"  property-ref="client_address"/> </class>
</hibernate-mapping>

访问数据库文件OneOneDao.java

package com.hust.dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hust.javabeans.Client;
import com.hust.javabeans.Company;
import SessionFactory.HibernateSessionFactory;public class OneOneDao {//添加会员 的方法,只操作主控方public  void addCompany(Company company){Session session=HibernateSessionFactory.getSession();Transaction ts=null;try{ts=session.beginTransaction();System.out.println("oneonedao的addCompany方法执行,执行的sql:");session.save(company);System.out.println("oneonedao的addCompany方法完成");ts.commit();           }catch(Exception ex){ts.rollback();System.out.println("[系统错误]oneonedao的addCompany方法中出错");ex.printStackTrace();            }finally{HibernateSessionFactory.closeSession();}       }//获取会员信息public Company loadCompany(Integer id){Session session=HibernateSessionFactory.getSession();Transaction ts=null;Company company=null;try{ts=session.beginTransaction();System.out.println("oneonedao的loadCompany方法执行,执行的sql:");company=(Company)session.get(Company.class, id);System.out.println("oneonedao的loadCompany方法完成");ts.commit();            }catch(Exception ex){ts.rollback();System.out.println("[系统错误]早oneonedao的loadCompany方法中出错");ex.printStackTrace();          }finally{HibernateSessionFactory.closeSession();}return company;}//添加客户信息,<span style="font-family: Arial, Helvetica, sans-serif;">只操作主控方</span>public void addClient(Client client){Session session=HibernateSessionFactory.getSession();Transaction ts=null;try{ts=session.beginTransaction();System.out.println("oneonedao的addclient方法执行,执行的sql:");session.save(client);       System.out.println("oneonedao的addclient方法完成");ts.commit();            }catch(Exception ex){ts.rollback();System.out.println("[系统错误]oneonedao的addClient方法中出错");ex.printStackTrace();         }finally{HibernateSessionFactory.closeSession();}   }//获取客户信息public Client loadClient(Integer id){Session session=HibernateSessionFactory.getSession();Transaction ts=null;Client client=null;try{ts=session.beginTransaction();System.out.println("oneonedao的loadclient方法执行,执行的sql:");client=(Client)session.get(Client.class, id);System.out.println("oneonedao的loadclient方法完成");ts.commit();         }catch(Exception ex){ts.rollback();System.out.println("[系统错误]oneonedao的loadclient方法中出错");ex.printStackTrace();            }finally{HibernateSessionFactory.closeSession();}return client;}
}

TestBean.java

package com.hust.test;import com.hust.dao.OneOneDao;
import com.hust.javabeans.Address;
import com.hust.javabeans.Client;
import com.hust.javabeans.Company;
import com.hust.javabeans.Login;public class TestBean {OneOneDao oneonedao=new OneOneDao();//获取会员信息public void addCompany(){Company company=new Company();Login login=new Login();login.setLoginname("tuke");login.setLoginpwd("123456");company.setCompanyname("呵呵哒的微笑");company.setLinkman("张珊");company.setTelephone("010-12345678");company.setEmail("beijing@163.com");//PO对象之间互相设置关联关系login.setCompany(company);company.setLogin(login);System.out.println("testbean的addcompany方法执行开始");//添加会员信息,保存到数据库,company保存到数据库,同时login也保存到数据库,只操作主控方oneonedao.addCompany(company);System.out.println("testbean的addcompany方法执行完成");}//获取会员信息public Company loadCompany(Integer id){//从数据库获得company的同时也获得了login表的记录System.out.println("testbean的loadcompany方法执行开始");return oneonedao.loadCompany(id);}//添加客户信息public void addClient(){Client client=new Client();Address address=new Address();address.setProvince("湖北省");address.setCity("武汉市");address.setStreet("临江大道");address.setZipcode("100083");client.setClientname("李想");client.setPhone("027-76866876");client.setEmail("lixiang@126.com");//PO对象之间互相设置关联关系address.setAddress_client(client);client.setClient_address(address);System.out.println("testbean的addclient方法执行开始");//添加客户信息,保存到数据库,client保存到数据库,同时address也保存到数据库,只操作主控方oneonedao.addClient(client);System.out.println("testbean的addclient方法执行完成");}//获得客户信息public Client loadClient(Integer id){System.out.println("testbean的loadclient方法执行开始");return oneonedao.loadClient(id);}}

结果显示为:


控制台打印的sql是:

testbean的addcompany方法执行开始
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
oneonedao的addCompany方法执行,执行的sql:
Hibernate: insert intocompany(COMPANYNAME, LINKMAN, TELEPHONE, EMAIL) values(?, ?, ?, ?)
oneonedao的addCompany方法完成
Hibernate: insert intologin(LOGINNAME, LOGINPWD, ID) values(?, ?, ?)
testbean的addcompany方法执行完成       //主键关联时,两个insert语句不是连续完成的
testbean的addclient方法执行开始
oneonedao的addclient方法执行,执行的sql:
Hibernate: insert intoaddress(PROVINCE, CITY, STREET, ZIPCODE) values(?, ?, ?, ?)
Hibernate: insert intoclient(CLIENTNAME, PHONE, EMAIL, CLIENTADDRESSID) values(?, ?, ?, ?)
oneonedao的addclient方法完成
testbean的addclient方法执行完成       //外键关联时,连续执行两个insert语句
testbean的loadcompany方法执行开始
oneonedao的loadCompany方法执行,执行的sql:
Hibernate: selectcompany0_.ID as ID2_1_,company0_.COMPANYNAME as COMPANYN2_2_1_,company0_.LINKMAN as LINKMAN2_1_,company0_.TELEPHONE as TELEPHONE2_1_,company0_.EMAIL as EMAIL2_1_,login1_.ID as ID3_0_,login1_.LOGINNAME as LOGINNAME3_0_,login1_.LOGINPWD as LOGINPWD3_0_ fromcompany company0_ left outer joinlogin login1_ on company0_.ID=login1_.ID wherecompany0_.ID=?
oneonedao的loadCompany方法完成
testbean的loadclient方法执行开始
oneonedao的loadclient方法执行,执行的sql:
Hibernate: selectclient0_.ID as ID1_0_,client0_.CLIENTNAME as CLIENTNAME1_0_,client0_.PHONE as PHONE1_0_,client0_.EMAIL as EMAIL1_0_,client0_.CLIENTADDRESSID as CLIENTAD5_1_0_ fromclient client0_ whereclient0_.ID=?
Hibernate: selectaddress0_.ID as ID0_1_,address0_.PROVINCE as PROVINCE0_1_,address0_.CITY as CITY0_1_,address0_.STREET as STREET0_1_,address0_.ZIPCODE as ZIPCODE0_1_,client1_.ID as ID1_0_,client1_.CLIENTNAME as CLIENTNAME1_0_,client1_.PHONE as PHONE1_0_,client1_.EMAIL as EMAIL1_0_,client1_.CLIENTADDRESSID as CLIENTAD5_1_0_ fromaddress address0_ left outer joinclient client1_ on address0_.ID=client1_.CLIENTADDRESSID whereaddress0_.ID=?
Hibernate: selectclient0_.ID as ID1_0_,client0_.CLIENTNAME as CLIENTNAME1_0_,client0_.PHONE as PHONE1_0_,client0_.EMAIL as EMAIL1_0_,client0_.CLIENTADDRESSID as CLIENTAD5_1_0_ fromclient client0_ whereclient0_.CLIENTADDRESSID=?
oneonedao的loadclient方法完成

hibernate的一对一主键双向映射关系和外键双向映射关系(一)相关推荐

  1. MySQL中的主键、唯一键、外键对比

    一.主键 主键:每张表中只能有一个字段(复合主键可以有多个字段)使用此属性,用来唯一约束该字段中的数据,不能重复 1.增加主键: 在创建表的时候,直接在字段后,添加primary key关键字 CRE ...

  2. 主键、唯一键、外键、

    类型 保证唯一性 是否允许空 一个表中可以有多少个 是否允许组合 主键(primary key) 是 否 至多一个,可以为0 允许(不推荐,因为不稳定) 唯一(unique) 是 是 可以有多个 允许 ...

  3. mysql 引擎 外键_mysql的事物,外键,与常用引擎

    ### part1 时间类型 date YYYY-MM-DD 年月日 (出现日期) time HH:MM:SS 时分秒 (竞赛时间) year YYYY 年份值 (红酒年份 82年矿泉水) datet ...

  4. mysql另外加外键约束怎么写_mysql外键约束怎么写

    mysql外键约束的写法:[[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1].外键约束是表的一个特殊字段,经常与主键约束一起使用. 在 CREATE TAB ...

  5. SQL 语句:不得使用外键与级联,一切外键概念必须在应用层解决

    阿里Java规范 [强制]不得使用外键与级联,一切外键概念必须在应用层解决. 说明:以学生和成绩的关系为例,学生表中的 student_id是主键,那么成绩表中的 student_id则为外键.如果更 ...

  6. 关于阿里巴巴开发手册不得使用外键与级联,一切外键概念必须在应用层解决的疑惑

    原文地址:http://www.codes51.com/itwd/4517194.html 问题: 关于阿里巴巴开发手册"不得使用外键与级联,一切外键概念必须在应用层解决"的疑惑 ...

  7. Mysql中外键作用以及Navicat建立外键失败总结

    本文摘自参考三篇文章,从这篇文章中将了解到外键作用以及navicat建立外键常见错误解决,帮助读者更加深刻了解外键. 文章目录 一.外键的作用 二. 不设置外键行不行? 三.那到底使不使用外键? 四. ...

  8. mysql 外键有啥用途_外键

    如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键.由此可见,外键表示了两个关系之间的相关联系.以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表. ...

  9. mysql外键约束怎么写_mysql外键约束怎么写

    mysql外键约束的写法:[[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1].外键约束是表的一个特殊字段,经常与主键约束一起使用. 在 CREATE TAB ...

最新文章

  1. Objective C 链式调用
  2. Android 异步加载图片分析
  3. 模拟客户端浏览器-1
  4. python和java一样吗-Python和Java的区别
  5. Django之session
  6. web页面事件无响应,元素点击不到
  7. LeetCode-链表-206. 反转链表
  8. select选择框变得可以输入、编辑
  9. Docker Toolbox:Docker Toolbox的简介、安装、使用方法之详细攻略
  10. yii2史上最简单式安装教程,没有之一
  11. Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式
  12. php禁用eval,zp blog
  13. Namomo Spring Camp Div2 Week1 - 第二次打卡
  14. PCIe的事务传输层的处理(TLP)
  15. 年龄是计数还是计量_电子皮带秤是静态称重还是动态称重?
  16. NERDTree 快捷键辑录
  17. FreeSWITCH之默认端口
  18. Win7下eclipse提交Job到hadoop集群
  19. linux修改显示日期格式,centos面板日期格式调整
  20. python做马尔科夫模型预测法_python实现隐马尔科夫模型HMM

热门文章

  1. JTAG之IO口作为普通IO口使用时注意事项
  2. STM32_DMA 标准初始化设置解释
  3. svn update一直卡哪里_电脑开机一直停在LOGO那里这是为什么呢?
  4. (chap9 基于HTTP的功能追加协议) Web 服务器管理文件的 WebDAV
  5. 基于区块链的健康链系统设计与实现(3)系统设计
  6. 2021第六届数维杯大学生数学建模竞赛赛题_A 外卖骑手的送餐危机
  7. 椭圆曲线加密算法ECC
  8. [How TO]-git/gerrit配置方法
  9. 2021-09-25
  10. redis的五种数据类型及常见操作