Hibernate关联关系映射(双向篇)
2016-05-12 11:13
561 查看
Hibernate关联关系可分为单向关联和双向关联两大类。单向关联可以分为一对一、一对多、多对一和多对多4种关联方式,而多向关联可以分为一对一、一对多和多对多3种关联方式。
Hibernate连接管理类HibernateUtil.Java
1.双向的一对一关联
(1)通过主键关联
通过主键关联的双向一对一映射,在需要一方的配置文件中将主键生成策略配置成foreign,即表示需要根据另一方的主键来生成自己的主键,而该实体本身不具有自己的主键生成策略。
示例:
实体类:
User.java
Address.java
表结构:
User表
Address表
配置文件:
Use.hbm.xml
Address.hbm.xml
测试类Test.java
测试结果:
(2)通过外键关联
通过外键关联的双向一对一映射,外键可以放在任意一方。在存放外键一方的映射文件中,需要添加many-to-one元素,并为该元素添加unique=“true”属性。而另一方的配置文件中要添加one-to-one元素,并使用其name属性来指定关联属性名。此时,存放外键的一方对应的数据表为从表,而另一方对应的数据表变为主表。
实体类与通过主键关联相同。
表结构:
user表
address表
配置文件:
User.hbm.xml
Address.hbm.xml
测试类与通过主键关联一样
测试结果:
2.双向的一对多关联(与双向多对一完全相同)
双向的一对多关联在“多”的一方要增加新属性以引用关联实体,在“一”的一方则增加集合属性,该集合中包含“多”的一方的关联实体。
实体类:
User.java
Address.java
表结构:
user表
address表
配置文件
User.hbm.xml
Address.hbm.xml
测试类Test.java
测试结果:
3.双向的多对多关联
在双向的多对多关联中,两端都要添加Set集合属性。要实现双向的多对多关联,必须使用中间表来实现两个实体间的关联关系。
示例:
实体类
User.java
Address.java
表结构:
user表
address表
user_address表
配置文件
User.hbm.xml:
Address.hbm.xml
测试类Test.java
测试结果:
Hibernate连接管理类HibernateUtil.Java
public class HibernateUtil { private static SessionFactory sessionFactory; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); static{ try{ Configuration cfg = new Configuration().configure(); sessionFactory = cfg.buildSessionFactory(); }catch(Throwable ex){ throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory(){ return sessionFactory; } public static Session getSession() throws HibernateException{ Session session = (Session)threadLocal.get(); if(session == null || !session.isOpen()){ session = (sessionFactory != null)?sessionFactory.openSession():null; threadLocal.set(session); } return session; } public static void closeSession() throws HibernateException{ Session session = (Session)threadLocal.get(); threadLocal.set(null); if(session != null){ session.close(); } } public static void shutdown(){ getSessionFactory().close(); } }
1.双向的一对一关联
(1)通过主键关联
通过主键关联的双向一对一映射,在需要一方的配置文件中将主键生成策略配置成foreign,即表示需要根据另一方的主键来生成自己的主键,而该实体本身不具有自己的主键生成策略。
示例:
实体类:
User.java
public class User { private int userid; private String name; private String password; private Address address; public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
Address.java
public class Address { private int addressid; private String addressinfo; private User user; public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
表结构:
User表
Address表
配置文件:
Use.hbm.xml
<hibernate-mapping> <class name="com.entity.User" table="user"> <id name="userid" type="java.lang.Integer" column="userid"> <generator class="identity"/> </id> <property name="name" type="java.lang.String" column="name"> </property> <property name="password" type="java.lang.String" column="password"> </property> <one-to-one name="address" class="com.entity.Address" cascade="all"/> </class> </hibernate-mapping>
Address.hbm.xml
<hibernate-mapping> <class name="com.entity.Address" table="address"<span>> <id name="addressid" type="java.lang.Integer" column="addressid"> <generator class="foreign"> <param name="property">user</param> </generator> </id> <property name="addressinfo" type="java.lang.String" column="addressinfo"> </property> <one-to-one name="user" class="com.entity.User" constrained="true"/> </class> </hibernate-mapping>
测试类Test.java
public class Test { public static void main(String[] args){ Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); User u = new User(); u.setName("sbw"); u.setPassword("123"); Address a = new Address(); a.setAddressinfo("heu"); a.setUser(u); u.setAddress(a); session.save(u); session.save(a); tx.commit(); HibernateUtil.closeSession(); } }
测试结果:
(2)通过外键关联
通过外键关联的双向一对一映射,外键可以放在任意一方。在存放外键一方的映射文件中,需要添加many-to-one元素,并为该元素添加unique=“true”属性。而另一方的配置文件中要添加one-to-one元素,并使用其name属性来指定关联属性名。此时,存放外键的一方对应的数据表为从表,而另一方对应的数据表变为主表。
实体类与通过主键关联相同。
表结构:
user表
address表
配置文件:
User.hbm.xml
<hibernate-mapping> <class name="com.entity.User" table="user"> <id name="userid" type="java.lang.Integer" column="userid"> <generator class="identity"/> </id> <property name="name" type="java.lang.String" column="name"> </property> <property name="password" type="java.lang.String" column="password"> </property> <one-to-one name="address" cascade="all"/> </class> </hibernate-mapping>
Address.hbm.xml
<hibernate-mapping> <class name="com.entity.Address" table="address"> <id name="addressid" type="java.lang.Integer" column="addressid"> <generator class="identity"> </generator> </id> <property name="addressinfo" type="java.lang.String" column="addressinfo"> </property> <many-to-one name="user" class="com.entity.User" unique="true"> <column name="userid"/> </many-to-one> </class> </hibernate-mapping>
测试类与通过主键关联一样
测试结果:
2.双向的一对多关联(与双向多对一完全相同)
双向的一对多关联在“多”的一方要增加新属性以引用关联实体,在“一”的一方则增加集合属性,该集合中包含“多”的一方的关联实体。
实体类:
User.java
public class User { private int userid; private String name; private String password; private Set<Address> address = new HashSet<Address>(); public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Address> getAddress() { return address; } public void setAddress(Set<Address> address) { this.address = address; } }
Address.java
public class Address { private int addressid; private String addressinfo; private User user; public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
表结构:
user表
address表
配置文件
User.hbm.xml
<hibernate-mapping> <class name="com.entity.User" table="user"> <id name="userid" type="java.lang.Integer" column="userid"> <generator class="identity"/> </id> <property name="name" type="java.lang.String" column="name"> </property> <property name="password" type="java.lang.String" column="password"> </property> <set name="address" table="address" inverse="true" lazy="true"> <key> <column name="userid"/> </key> <one-to-many class="com.entity.Address"/> </set> </class> </hibernate-mapping>
Address.hbm.xml
<hibernate-mapping> <class name="com.entity.Address" table="address"> <id name="addressid" type="java.lang.Integer" column="addressid"> <generator class="identity"> </generator> </id> <property name="addressinfo" type="java.lang.String" column="addressinfo"> </property> <many-to-one name="user" class="com.entity.User" unique="true"> <column name="userid"/> </many-to-one> </class> </hibernate-mapping>
测试类Test.java
public class Test { public static void main(String[] args){ Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); User u = new User(); u.setName("sbw"); u.setPassword("123"); Address a = new Address(); a.setAddressinfo("heu"); Address a1 = new Address(); a.setAddressinfo("hrb"); a.setUser(u); a1.setUser(u); u.getAddress().add(a); u.getAddress().add(a1); session.save(a); session.save(a1); session.save(u); tx.commit(); HibernateUtil.closeSession(); } }
测试结果:
3.双向的多对多关联
在双向的多对多关联中,两端都要添加Set集合属性。要实现双向的多对多关联,必须使用中间表来实现两个实体间的关联关系。
示例:
实体类
User.java
public class User { private int userid; private String name; private String password; private Set<Address> address = new HashSet<Address>(); public int getUserid() { return userid; } public void setUserid(int userid) { this.userid = userid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Address> getAddress() { return address; } public void setAddress(Set<Address> address) { this.address = address; } }
Address.java
public class Address { private int addressid; private String addressinfo; private Set<User> user = new HashSet<User>(); public int getAddressid() { return addressid; } public void setAddressid(int addressid) { this.addressid = addressid; } public String getAddressinfo() { return addressinfo; } public void setAddressinfo(String addressinfo) { this.addressinfo = addressinfo; } public Set<User> getUser() { return user; } public void setUser(Set<User> user) { this.user = user; } }
表结构:
user表
address表
user_address表
配置文件
User.hbm.xml:
<hibernate-mapping> <class name="com.entity.User" table="user"> <id name="userid" type="java.lang.Integer" column="userid"> <generator class="identity"/> </id> <property name="name" type="java.lang.String" column="name"> </property> <property name="password" type="java.lang.String" column="password"> </property> <set name="address" table="user_address" inverse="true"> <key> <column name="userid"/> </key> <many-to-many class="com.entity.Address" column="addressid"/> </set> </class> </hibernate-mapping>
Address.hbm.xml
<hibernate-mapping> <class name="com.entity.Address" table="address"> <id name="addressid" type="java.lang.Integer" column="addressid"> <generator class="identity"> </generator> </id> <property name="addressinfo" type="java.lang.String" column="addressinfo"> </property> <set name="user" table="user_address"> <key> <column name="addressid"/> </key> <many-to-many class="com.entity.User" column="userid"/> </set> </class> </hibernate-mapping>
测试类Test.java
public class Test { public static void main(String[] args){ Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); User u = new User(); u.setName("sbw"); u.setPassword("123"); User u1 = new User(); u1.setName("gaoya"); u1.setPassword("456"); Address a = new Address(); a.setAddressinfo("heu"); Address a1 = new Address(); a1.setAddressinfo("hrb"); a.getUser().add(u); a.getUser().add(u1); a1.getUser().add(u); a1.getUser().add(u1); u.getAddress().add(a); u.getAddress().add(a1); u1.getAddress().add(a); u1.getAddress().add(a1); session.save(a); session.save(a1); session.save(u); session.save(u1); tx.commit(); HibernateUtil.closeSession(); } }
测试结果:
相关文章推荐
- cocos2dx 内存管理
- MySql常用语句
- 图像处理-cvCopy与cvCloneImage的区别
- sql 统计 关于学生成绩
- http 错误代码表
- 自定义浏览器滚动条的样式,打造属于你的滚动条风格——兼容IE和webkit(ff不支持)
- 针对GROUP BY 设置限制条件,则不能使用Where 子句,必须使用HAVING 子句来设置。
- Could not create the Java Virtual Machine
- Home > IOS安全–使用class-dump-z导出IOS应用类信息 IOS安全–使用class-dump-z导出IOS应用类信息
- iphone开发数组排序(数组中包括字典)
- 《JVM故障诊断指南》之4 —— Java 8:从持久代到metaspace
- 安卓xml绘图
- vs2013更新了代码,但是运行没效果
- 程序猿必备-分布式与集群
- win7x64下的redis安装与使用
- php格式化json函数示例代码
- iOS跳过依赖检查的pod命令
- php面向对象中static静态属性和静态方法的调用
- STL之list排序
- linux ps command useful examples