该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-05
最后修改:2008-11-12
接上篇 hibernate入门使用系列 1-- 说明篇+试用篇 现在起主要讲 hibernate中的关系映射。对应的关系主要有 1:1, n:1, n:n。今天主要写1:1。 关系映射篇(上)—— 之1:1 1对1的关系在现实中很常见。比方说:人和身份证。1个身份证对应着一个身份证,一个身份证对应着一个人。那么,我们就以此为原型。进行代码编写。 建立实体模型如右:
根据模型,创建数据库: use HibernateQuickUse; drop table if exists Person; drop table if exists Card; create table Card ( id varchar(32) primary key, cardDesc varchar(128) not null ); create table Person ( id varchar(32) primary key, name varchar(32) not null, card_id varchar(32) not null, foreign key(card_id) references Card(id) ); java代码如下: Person类 package org.py.hib.relation.one2one; /** * Person entity. */ @SuppressWarnings("serial") public class Person implements java.io.Serializable { private String id; private String name; private Card card; public Person() { } public String getId() { return this.id; } public void setId(String id) { this.id = id; } public Card getCard() { return this.card; } public void setCard(Card card) { this.card = card; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } }
Card类: package org.py.hib.relation.one2one; /** * Card entity. */ @SuppressWarnings("serial") public class Card implements java.io.Serializable { private String id; private String cardDesc; public Card() { } public String getId() { return this.id; } public void setId(String id) { this.id = id; } public String getCardDesc() { return cardDesc; } public void setCardDesc(String cardDesc) { this.cardDesc = cardDesc; } }
xml映射文件如下: Person.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="org.py.hib.relation.one2one.Person" table="person"> <id name="id" type="java.lang.String" column="id" length="32"> <generator class="uuid" /> </id> <property name="name" type="java.lang.String"> <column name="name" length="32" /> </property> <many-to-one name="card" class="org.py.hib.relation.one2one.Card" unique="true" cascade="all" column="card_id" /> </class> </hibernate-mapping> 今天讲的是one-to-one配置。但是,此处用的是many-to-one,这个是什么原因呢?其实,one-to-one就是特殊的many-to-one。 Card.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"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="org.py.hib.relation.one2one.Card" table="card"> <id name="id" type="java.lang.String" column="id" length="32"> <generator class="uuid" /> </id> <property name="cardDesc" type="java.lang.String" column="cardDesc" length="128" not-null="true"/> </class> </hibernate-mapping>
测试代码如下: One2OneTest.java package org.py.hib.relation.one2one; import junit.framework.Assert; import junit.framework.TestCase; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.After; import org.junit.Before; public class One2OneTest extends TestCase { private SessionFactory factory; private String m_name = "ryanpoy"; private String m_name2 = "ryanpoy2"; private String m_cardDesc1 = "desc_1"; private String m_cardDesc2 = "desc_2"; @Before public void setUp() throws Exception { Configuration conf = new Configuration().configure(); factory = conf.buildSessionFactory(); } /** * 测试添加 * @throws Exception */ public void testSave() throws Exception { System.out.println("\n=== test save ==="); Card card = new Card(); card.setCardDesc(m_cardDesc1); Person person = new Person(); person.setName(m_name); // 设置用户名 = m_name person.setCard(card); Session session = null; Transaction tran = null; try { session = factory.openSession(); tran = session.beginTransaction(); session.save(person); tran.commit(); Assert.assertEquals(person.getId() != null, true); Assert.assertEquals(card.getId() != null, true); } catch (Exception ex) { tran.rollback(); throw ex; } finally { if (session != null) { try { session.close(); } catch (Exception ex) { // nothing to do } finally { if (session != null) session = null; } } } } /** * 测试查询 * @throws Exception */ public void testFind() throws Exception { System.out.println("\n=== test find ==="); Session session = null; try { session = factory.openSession(); Person person = (Person) session.createQuery("from Person").list().get(0); Assert.assertEquals(true, person.getId() != null); Assert.assertEquals(m_name, person.getName()); Assert.assertEquals(true, person.getCard().getId() != null); Assert.assertEquals(m_cardDesc1, person.getCard().getCardDesc()); } catch (Exception ex) { throw ex; } finally { if (session != null) { try { session.close(); } catch (Exception ex) { // nothing to do } finally { if (session != null) session = null; } } } } /** * 测试修改 * @throws Exception */ public void testModify() throws Exception { System.out.println("\n=== test modify ==="); Session session = null; Transaction tran = null; try { session = factory.openSession(); tran = session.beginTransaction(); Person person = (Person) session.createQuery("from Person").list().get(0); person.setName(m_name2); // 修改用户名 = m_name2.(原来用户名= m_name) person.getCard().setCardDesc(m_cardDesc2); // 修改cardDesc 为 m_cardDesc2 (原来是:m_cardDesc1) tran.commit(); } catch (Exception ex) { throw ex; } finally { if (session != null) { try { session.close(); } catch (Exception ex) { // nothing to do } finally { if (session != null) session = null; } } } /* * 修改后再查询 */ System.out.println("\n=== test find after modify ==="); try { session = factory.openSession(); Person person = (Person) session.createQuery("from Person").list().get(0); Assert.assertEquals(true, person.getId() != null); Assert.assertEquals(m_name2, person.getName()); Assert.assertEquals(true, person.getCard().getId() != null); Assert.assertEquals(m_cardDesc2, person.getCard().getCardDesc()); } catch (Exception ex) { throw ex; } finally { if (session != null) { try { session.close(); } catch (Exception ex) { // nothing to do } finally { if (session != null) session = null; } } } } /** * 测试删除 * @throws Exception */ public void testDelete() throws Exception { System.out.println("\n=== test delete ==="); Session session = null; Transaction tran = null; try { session = factory.openSession(); tran = session.beginTransaction(); Person person = (Person) session.createQuery("from Person").list().get(0); session.delete(person); tran.commit(); } catch (Exception ex) { throw ex; } finally { if (session != null) { try { session.close(); } catch (Exception ex) { // nothing to do } finally { if (session != null) session = null; } } } /* * 删除后再查询 */ System.out.println("\n=== test find after delete ==="); try { session = factory.openSession(); Integer num = (Integer) session.createQuery("from Person").list().size(); Assert.assertEquals(0, num.intValue()); num = (Integer) session.createQuery("from Card").list().size(); Assert.assertEquals(0, num.intValue()); } catch (Exception ex) { throw ex; } finally { if (session != null) { try { session.close(); } catch (Exception ex) { // nothing to do } finally { if (session != null) session = null; } } } } /** * */ @After public void tearDown() throws Exception { factory.close(); } }
运行test,一路飚绿。呵呵。陶醉一番。不过,这也就是一个拿不出手的测试和一个拿不出手的例子。没有任何实际意义的例子。仅此一个demo而已。 在1:1中,其实还有一种方式,即:唯一主见关联。但是,我一直倾向于上面的这种形式,所以,唯一主见关联的旧部介绍了。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-05-07
这个只是单向关联one-to-one ,而且是不严格的,不准确的,你要指明many-to-one是表示一个“一对一”关系,至少要用上unique。
one-to-one ,有很多东西可以讨论。 1.单向关联或双向关联 2.使用cascade 3.使用中间表 |
|
返回顶楼 | |
发表时间:2008-05-07
hantsy 写道 这个只是单向关联one-to-one ,而且是不严格的,不准确的,你要指明many-to-one是表示一个“一对一”关系,至少要用上unique。 多谢指出。已经修改过了。源代码也已经修改了。 hantsy 写道 one-to-one ,有很多东西可以讨论。 1.单向关联或双向关联 确实有单项关联和双向关联这2种。且任何的关系(1:1, ... n:n)都有单项和双向之分。在这个例子中里面我只用了单项。 抽空补上双向。 hantsy 写道 2.使用cascade 这个我一直认为且只认为代表级联操作,我觉得与1:1, ... , n:n都没有关系。 hantsy 写道 3.使用中间表 这个在n:n中,倒是用过。不知道你说的1:1中,采用中间表是什么意思。 是指临时表么? |
|
返回顶楼 | |
发表时间:2008-05-31
弱弱的问一下 删除person的时候为什么会把card也干掉啊 他们不是对于数据库两张表么 具体需要怎么设置
|
|
返回顶楼 | |
发表时间:2008-06-17
tjlvan 写道 弱弱的问一下 删除person的时候为什么会把card也干掉啊 他们不是对于数据库两张表么 具体需要怎么设置
参看Person.hbm.xml配置文件中16行有这样子的一句话: cascade="all" 这里的cascade设置成为了all,那么就出现了你说的这个现象。 其实cascade有很多中设置:create, merge, save-update, delete, lock, refresh, evict, replicate。。。 每一种都有其不同的含义。具体的请google一下。 如果要想删除person而不删除card,请修改为:delete-orphan |
|
返回顶楼 | |
发表时间:2008-06-17
楼主的id好象不是递增的啊,要加个递增怎么弄啊。
|
|
返回顶楼 | |
发表时间:2008-06-22
wxb_love 写道 楼主的id好象不是递增的啊,要加个递增怎么弄啊。
1.修改数据库的主键为auto_increment 2.修改pojo的主键为integer 3.修改hbm.xml中的id的generator ,把uuid改成为native |
|
返回顶楼 | |
发表时间:2008-10-23
谢谢文章写的不错。太感谢了
|
|
返回顶楼 | |
发表时间:2008-10-24
能不能用SSH框架写一个出来看一下呢!
还是感受很深! |
|
返回顶楼 | |
发表时间:2008-12-29
one-to-one就是特殊的many-to-one
能否解释下? |
|
返回顶楼 | |