hibernate的一对一主键双向映射关系和外键双向映射关系(一)
2015-11-12 23:07
447 查看
主键关联的重点是关联的两个表共享一个主键值。本例中采用,一个单位在网上的一个系统中注册会员。
1,会员数据保存在会员表company中,每个会员的登录账号保存在表login中;
2,一个会员只有一个登录账号,一个登录账号只属于一个会员,两表是一对一的对应关系;
company表如下:
![](https://img-blog.csdn.net/20151112193207290?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
生成company表的sql语句如下:
login表如下:
![](https://img-blog.csdn.net/20151112193439239?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
生成login表的sql语句如下:
外键关联的重点是:两个表各自有不同的主键,但是其中一个表有一个外键引用另一个表的主键。即非主键是别人的主键就是该表的外键。
这个例子中:
1,客户(Client)和客户地址(Address)是外键关联的一对一关系,分别对应client表换个address表。
2,Client类在映射文件中的client_address为外键引用Address类的对应表中的主键,咋一看书多对一关系,但是在Client类对应的映射文件设置多对一对应的属性client_address时,设置了unique的值为true,即这个外键是唯一的,即一对一关系。
client表如下:
![](https://img-blog.csdn.net/20151112195649433?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
生成client表的sql语言:
![](https://img-blog.csdn.net/20151112195922437?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
address表如下:
![](https://img-blog.csdn.net/20151112195958475?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
hibernate.cfg.xml配置文件:
一对一主键双向关联:
Company.java
一对一外键双向关联:
Client.java
<many-to-one unique="true"> 标签在这里表示一对一,many-to-one应该写在有外键的那个表对应的映射文件中
Address.hbm.xml
访问数据库文件OneOneDao.java
![](https://img-blog.csdn.net/20151112201241912?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20151112201522644)
![](https://img-blog.csdn.net/20151112201542432)
![](https://img-blog.csdn.net/20151112201601625)
![](https://img-blog.csdn.net/20151112201702485)
控制台打印的sql是:
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 into company (COMPANYNAME, LINKMAN, TELEPHONE, EMAIL) values (?, ?, ?, ?) oneonedao的addCompany方法完成 Hibernate: insert into login (LOGINNAME, LOGINPWD, ID) values (?, ?, ?) testbean的addcompany方法执行完成 //主键关联时,两个insert语句不是连续完成的 testbean的addclient方法执行开始 oneonedao的addclient方法执行,执行的sql: Hibernate: insert into address (PROVINCE, CITY, STREET, ZIPCODE) values (?, ?, ?, ?) Hibernate: insert into client (CLIENTNAME, PHONE, EMAIL, CLIENTADDRESSID) values (?, ?, ?, ?) oneonedao的addclient方法完成 testbean的addclient方法执行完成 //外键关联时,连续执行两个insert语句 testbean的loadcompany方法执行开始 oneonedao的loadCompany方法执行,执行的sql: Hibernate: select company0_.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_ from company company0_ left outer join login login1_ on company0_.ID=login1_.ID where company0_.ID=? oneonedao的loadCompany方法完成 testbean的loadclient方法执行开始 oneonedao的loadclient方法执行,执行的sql: Hibernate: select client0_.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_ from client client0_ where client0_.ID=? Hibernate: select address0_.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_ from address address0_ left outer join client client1_ on address0_.ID=client1_.CLIENTADDRESSID where address0_.ID=? Hibernate: select client0_.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_ from client client0_ where client0_.CLIENTADDRESSID=? oneonedao的loadclient方法完成
相关文章推荐
- batis配置多表关联(一对一、一对多、多对多)
- Hibernate关联关系配置(一对多、一对一和多对多)
- iptables命令详解
- 数据库设计的14个技巧(转)
- MyBatis 一对一、一对多的
- hibernate关联关系
- hibernate学习:映射之主键
- socket.io一对一通信的实现
- hibernate中的对象映射配置文件
- MyBatis结果集映射(ResultMap)
- Hibernate 一对一关联映射(主键关联VS唯一外键关联)
- Hibernate基于外键一对一映射操作实例
- Hibernate基于主键一对一映射操作实例
- hbernate学习(三)一对一双向关联
- 第九章 关系映射 一对一关系 共享主键方式实现一对一
- 第九章 关系映射 一对一关系 唯一外键方式实现一对一
- 第十章 基于Annotation的关系映射 一对一
- django 一对一查询
- hiberante 一对一
- 圆满结束【一对一私人定制,我和马哥有个约会】