TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
上篇讲了1:1,那么这次继续讲1:n和n:1。 这次用到的例子是Father和child之间的关系。一个father可以有n个child,但是1个child只有一个father。这里只说生父。至于其他的继父、养父、干爹等等,不再范围之内。 好吧。还是同前面的一样。现建立实体模型如下: 根据模型创建数据库。sql脚本如下:
根据模型创建数据库。sql脚本如下:
use HibernateQuickUse;
drop table if exists Child;
drop table if exists Father;
create table Father (
id varchar(32) primary key,
name varchar(32) not null
);
create table Child (
id varchar(32) primary key,
name varchar(128) not null,
father_id varchar(32) not null,
foreign key(father_id) references Father(id)
);
[/code]
根据模型创建java对象。
Father.java:
package org.py.hib.relation.one2many;
import java.util.HashSet;
import java.util.Set;
/**
* Father entity.
*/
@SuppressWarnings("serial")
public class Father implements java.io.Serializable
{
private String id;
private String name;
private Set<Child> children = new HashSet<Child>(0);
public Father()
{
}
public String getId()
{
return this.id;
}
public void setId(String id)
{
this.id = id;
}
public String getName()
{
return this.name;
}
public void setName(String name)
{
this.name = name;
}
public Set<Child> getChildren()
{
return children;
}
public void setChildren(Set<Child> children)
{
this.children = children;
}
}[/code]
Child.java:
package org.py.hib.relation.one2many;
/**
* Child entity.
* @author MyEclipse Persistence Tools
*/
@SuppressWarnings("serial")
public class Child implements java.io.Serializable
{
private String id;
private String name;
private Father father;
public Child()
{
}
public String getId()
{
return this.id;
}
public void setId(String id)
{
this.id = id;
}
public Father getFather()
{
return this.father;
}
public void setFather(Father father)
{
this.father = father;
}
public String getName()
{
return this.name;
}
public void setName(String name)
{
this.name = name;
}
}[/code]
映射文件如下:
Father.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.one2many.Father" table="father">
<id name="id" type="java.lang.String" column="id" length="32">
<generator class="uuid" />
</id>
<property name="name" type="java.lang.String" column="name" length="32" not-null="true"/>
<set name="children" table="child" cascade="all" inverse="true">
<key column="father_id" />
<one-to-many class="org.py.hib.relation.one2many.Child" />
</set>
</class>
</hibernate-mapping>
[/code]
这里要说说 "set" 这个标签里面的内容。
"name"是Father里面的属性的名字。"table"表示它对应的是数据库中的哪个表。
cascade="all" 表示所有的操作都级联操作。
"inverse"表示关系的维护由谁来执行。true表示不由自己执行,而有对应的另外一方执行。false则相反,表示由自己维护关系。这里设置成 true 是由原因的。如果说把它设置成为false,那么就由他来维护关系了。
这里得说一下inverse属性的问题。在one-to-many中,如果关系由one来维护,那么会很麻烦,性能也会很低。每次对many一方的一条记录进行增、删、改 时都会多一次update操作。原因很简单,因为关系的维护设置在了one这一方,所以对many的每一次操作,one这一方都要维护一次双方的关系。
这个就好像皇帝和老百姓的关系。试问,是来一个老百姓,皇帝就宣布他是我的子民,还是由老百姓直接选择做那个皇帝的子民更加有效率呢?呵呵。不知道这个例子大家有没有明白。关于inverse的更具体的说明,在javaeye上搜一下,就会发现有很多。这里推荐一篇,我认为讲得很明白的:主题:inverse。
"key" 中的 "column" 表示在table(这里的table是child)中, 跟Father关联的字段名称。这里是"father_id"。可以看看开始的sql脚本。
one-to-many 表示father和children的关系。class则表示是同哪个类是这种关系。
Child.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.one2many.Child" table="child">
<id name="id" type="java.lang.String" column="id" length="32" >
<generator class="uuid" />
</id>
<property name="name" type="java.lang.String" column="name" length="128" not-null="true"/>
<many-to-one name="father" class="org.py.hib.relation.one2many.Father" column="father_id" />
</class>
</hibernate-mapping>
[/code]
这个里面主要就是多了一个many-to-one,表示child 和 father 的关系是"many-to-one"
测试代码如下:
One2ManyTest.java
package org.py.hib.relation.one2many;
import java.util.Set;
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 One2ManyTest extends TestCase
{
private SessionFactory factory;
private static final String[] childname = new String[] { "child_1", "child_2", "child_3" };
private static final String[] newchildname = new String[] { "new_child_1", "new_child_2", "new_child_3" };
@Before
public void setUp() throws Exception
{
Configuration conf = new Configuration().configure();
factory = conf.buildSessionFactory();
}
/**
* 测试添加
* @throws Exception
*/
public void testSave() throws Exception
{
System.out.println("
=== test save ===");
Father father = new Father();
father.setName("Father_1");
Child child1 = new Child();
child1.setName(childname[0]);
Child child2 = new Child();
child2.setName(childname[1]);
Child child3 = new Child();
child3.setName(childname[2]);
father.getChildren().add(child1);
father.getChildren().add(child2);
father.getChildren().add(child3);
child1.setFather(father);
child2.setFather(father);
child3.setFather(father);
Session session = null;
Transaction tran = null;
try
{
session = factory.openSession();
tran = session.beginTransaction();
session.save(father);
tran.commit();
Assert.assertNotNull(father.getId());
Assert.assertNotNull(child1.getId());
Assert.assertNotNull(child2.getId());
Assert.assertNotNull(child3.getId());
} 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;
}
}
}
}
private boolean isChildrenName(String name)
{
for (String n : childname)
{
if (n.equals(name))
return true;
}
return false;
}
private boolean isNewChildrenName(String name)
{
for (String n : newchildname)
{
if (n.equals(name))
return true;
}
return false;
}
/**
* 测试查询
* @throws Exception
*/
public void testFind() throws Exception
{
System.out.println("
=== test find ===");
Session session = null;
try
{
session = factory.openSession();
Father father = (Father) session.createQuery("from Father").list().get(0);
Assert.assertNotNull(father.getId());
Assert.assertEquals("Father_1", father.getName());
Set<Child> children = father.getChildren();
for (Child child : children)
{
Assert.assertEquals(child.getFather(), father);
Assert.assertNotNull(child.getId());
Assert.assertTrue(isChildrenName(child.getName()));
}
} 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("
=== test modify ===");
Session session = null;
Transaction tran = null;
try
{
session = factory.openSession();
tran = session.beginTransaction();
Father father = (Father) session.createQuery("from Father").list().get(0);
father.setName("Father_2"); // 修改用户名 = m_name2.(原来用户名= m_name)
Set<Child> children = father.getChildren();
int i = 0;
for (Child child : children)
{
child.setName(newchildname[i++]);
}
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("
=== test find after modify ===");
try
{
session = factory.openSession();
Father father = (Father) session.createQuery("from Father").list().get(0);
Assert.assertNotNull(father.getId());
Assert.assertEquals("Father_2", father.getName());
Set<Child> children = father.getChildren();
for (Child child : children)
{
Assert.assertEquals(child.getFather(), father);
Assert.assertNotNull(child.getId());
Assert.assertTrue(isNewChildrenName(child.getName()));
}
} 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("
=== test delete ===");
Session session = null;
Transaction tran = null;
try
{
session = factory.openSession();
tran = session.beginTransaction();
Father father = (Father) session.createQuery("from Father").list().get(0);
session.delete(father);
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("
=== test find after delete ===");
try
{
session = factory.openSession();
Integer num = (Integer) session.createQuery("from Father").list().size();
Assert.assertEquals(0, num.intValue());
num = (Integer) session.createQuery("from Child").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();
}
}
[/code]
源码下载:http://file.javaxxz.com/2014/11/3/000003984.zip |
|