Hibernate笔记2--映射对象之间的关系
来源:互联网 发布:知乎专栏怎么写文章 编辑:程序博客网 时间:2024/04/30 21:22
今天心情好。。建了一个比笔记1那篇更简单的表来演示Foo程序:)
一。数据库格式
user表
address表
address表持有user_id外键,由此应该可以看出两张表表示的关系为: “1个用户可以拥有多个地址”
二。双向关联
下面生成POJO对象:
- package model;
- /**
- * Address entity.
- *
- * @author MyEclipse Persistence Tools
- */
- public class Address implements java.io.Serializable {
- // Fields
- private Integer addressId;
- private User user;
- private String addressDetail;
- // Constructors
- /** default constructor */
- public Address() {
- }
- /** minimal constructor */
- public Address(User user) {
- this.user = user;
- }
- /** full constructor */
- public Address(User user, String addressDetail) {
- this.user = user;
- this.addressDetail = addressDetail;
- }
- // Property accessors
- public Integer getAddressId() {
- return this.addressId;
- }
- public void setAddressId(Integer addressId) {
- this.addressId = addressId;
- }
- public User getUser() {
- return this.user;
- }
- public void setUser(User user) {
- this.user = user;
- }
- public String getAddressDetail() {
- return this.addressDetail;
- }
- public void setAddressDetail(String addressDetail) {
- this.addressDetail = addressDetail;
- }
- }
- package model;
- import java.util.HashSet;
- import java.util.Set;
- /**
- * User entity.
- *
- * @author MyEclipse Persistence Tools
- */
- public class User implements java.io.Serializable {
- // Fields
- private Integer userId;
- private String userName;
- private Set addresses = new HashSet(0);
- // Constructors
- /** default constructor */
- public User() {
- }
- /** minimal constructor */
- public User(String userName) {
- this.userName = userName;
- }
- /** full constructor */
- public User(String userName, Set addresses) {
- this.userName = userName;
- this.addresses = addresses;
- }
- // Property accessors
- public Integer getUserId() {
- return this.userId;
- }
- public void setUserId(Integer userId) {
- this.userId = userId;
- }
- public String getUserName() {
- return this.userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public Set getAddresses() {
- return this.addresses;
- }
- public void setAddresses(Set addresses) {
- this.addresses = addresses;
- }
- }
由于是双向关联,因此生成的2个POJO对象都会持有对方对象。并且1对N中,1方持有N方Set集合,N方持有1方单个对象。
下面是生成的映射配置:
- <?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">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping>
- <class name="model.Address" table="address" catalog="email">
- <id name="addressId" type="java.lang.Integer">
- <column name="address_id" />
- <generator class="identity" />
- </id>
- <many-to-one name="user" class="model.User" fetch="select">
- <column name="user_id" not-null="true" />
- </many-to-one>
- <property name="addressDetail" type="java.lang.String">
- <column name="address_detail" length="45" />
- </property>
- </class>
- </hibernate-mapping>
- <?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">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping>
- <class name="model.User" table="user" catalog="email">
- <id name="userId" type="java.lang.Integer">
- <column name="user_id" />
- <generator class="identity" />
- </id>
- <property name="userName" type="java.lang.String">
- <column name="user_name" length="45" not-null="true" />
- </property>
- <set name="addresses" inverse="true">
- <key>
- <column name="user_id" not-null="true" />
- </key>
- <one-to-many class="model.Address" />
- </set>
- </class>
- </hibernate-mapping>
双向1:N关系基本配置很容易套格式,要注意的是在1方配置inverse="true",意思就是将控制方向交给N方会比较高效一点:)。具体后面解释inverse的概念。
下面是一个简单的TestCase,演示保存操作:)
- import java.util.HashSet;
- import java.util.Set;
- import model.Address;
- import model.User;
- import org.hibernate.HibernateException;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- import org.junit.Before;
- import org.junit.Test;
- public class TestCase2 {
- Session session = null;
- @Before
- // 读取classpath下的配置文件hibernate.cfg.xml
- // current_session_context_class=thread,show_sql=true
- public void getSession() {
- try {
- Configuration cfg = new Configuration().configure();
- SessionFactory sf = cfg.buildSessionFactory();
- session = sf.getCurrentSession();
- } catch (HibernateException e) {
- e.printStackTrace();
- }
- }
- @Test
- public void BothSide() {
- session.beginTransaction();
- User u = new User();
- u.setUserName("hello");
- //new Address
- Address add = new Address();
- add.setAddressDetail("luoyu road 1037#");
- u.getAddresses().add(add);
- session.save(u);
- session.getTransaction().commit();
- }
- }
BothSide()方法中创建了一个User,一个Address,然后save,run一下用例,查看到Hibernate执行了下面的操作:
insert into user (user_name) values (?)
只保存了user,如果目的就是象方法所写 save(u),那么就是对的。但是更新了User的同时也想保存这个Address怎么办?
想同时保存User和Address,需要做如下两处修改:
1.在User.hbm.xml 17行写上cascade="all"(对User的所有操作均级联到Address表上)
2.在BothSide() 39-40行中添加 add.setUser(u); (由于address的user_id外键字段不需为空,不给它赋值就会报错)
具体见下:
- <?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">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping>
- <class name="model.User" table="user" catalog="email">
- <id name="userId" type="java.lang.Integer">
- <column name="user_id" />
- <generator class="identity" />
- </id>
- <property name="userName" type="java.lang.String">
- <column name="user_name" length="45" not-null="true" />
- </property>
- <set name="addresses" inverse="true" cascade="all">
- <key>
- <column name="user_id" not-null="true" />
- </key>
- <one-to-many class="model.Address" />
- </set>
- </class>
- </hibernate-mapping
- @Test
- public void BothSide() {
- session.beginTransaction();
- User u = new User();
- u.setUserName("hello");
- //new Address
- Address add = new Address();
- add.setAddressDetail("luoyu road 1037#");
- add.setUser(u);
- //add Address to user
- u.getAddresses().add(add);
- session.save(u);
- session.getTransaction().commit();
- }
上面这段代码之所以需要添加add.setUser(u),最根本的原因就是上面提到的:我在在User方配置了inverse=true.意思就是“双方的关系交给Address你来管理,User我不负责维护关系”,因此User也不会主动去填充Address方的user_id.
然而,在维护关系的Address一方,我们访问每一个Address对象的时候,都可以获取到User对象.
- Hibernate笔记2--映射对象之间的关系
- Hibernate映射对象之间的多种关系
- Hibernate的对象关系映射(2)
- hibernate 对象的映射关系
- Hibernate 学习笔记05 --对象关系映射
- hibernate数据类型之间的映射关系
- hibernate 对象 - 关系映射
- hibernate对象关系映射
- hibernate对象关系映射
- Hibernate对象-关系映射
- hibernate对象关系映射
- Hibernate对象关系映射
- 对象-关系数据库之间的映射
- 对象-关系数据库之间的映射
- 对象-关系数据库之间的映射
- 使用Hibernate进行对象的关系映射(2)
- 使用Hibernate进行对象的关系映射(2)
- 使用Hibernate进行对象的关系映射
- SqlDependency 的数据库配置步骤
- ORACLE用户管理
- PL/SQL高级应用的学习1
- Spring事务学习
- BeanFactory和ApplicationContext学习
- Hibernate笔记2--映射对象之间的关系
- 原创:自己写代码实现遥感影像自动配准
- PHP串行化与JSON
- 开源GIS系统现状分析
- clistctrl单行多行选中问题
- asp.net电子商务开发实战 视频 适合初学者。
- 不能因为它是WOW就不叫传销
- asp.net电子商务开发实战 视频 第一讲
- JAVA泛型的小学习