- 浏览: 23935 次
最近访客 更多访客>>
最新评论
-
linginfanta:
没有翻完。
转贴 java 泛型,辛苦译者了 -
阳光晒晒:
等四五小时再看,如果内存下来了
一般是由于数据库连接没关闭.
...
J2EE 系统 outofmemory问题 -
anxin587:
今天一直用jprofiler来跟踪,发现一个奇怪的问题,当to ...
J2EE 系统 outofmemory问题
在域模型中,类之间最普遍的关系是关联关系,关联是有方向的,分为单向关联和双向关联,在关系数据库中,为了避免冗余,只存在many 方参照one方,所以关系数据库实际上面是多对一,一对一的单向关联,
在类和类之间各种关系中,多对一的单向关联和关系数据库的外键参照关系最匹配,下面一个简单例子来说明这些
两个实体,分别为Customer和orders,同时一个customer可以拥有0个或者多个orders,他们的DDL如下所示
CREATE TABLE CUSTOMERS (ID INT AUTO_INCREMENT PRIMARY KEY,NAME VARCHAR(20))
CREATE TABLE ORDERS
(
ID INT AUTO_INCREMENT PRIMARY KEY,
CUSTOMER_ID INT,
ORDERNUMBER INT,
CONSTRAINT FK FOREIGN KEY(CUSTOMER_ID) REFERENCES CUSTOMERS(ID)
)
Customer类如下
package entity;
import java.util.*;
public class Customer
{
private Long id;
private String name;
private Set orders=new HashSet();
private void setId(Long id)
{
this.id=id;
}
public Long getId()
{
return this.id;
}
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
public void setOrders(Set orders)
{
this.orders=orders;
}
public Set getOrders()
{
return this.orders;
}
}
orders类如下
package entity;
public class Order
{
private Long id;
private Customer customer;
private int ordernumber;
private void setId(Long id)
{
this.id=id;
}
public Long getId()
{
return this.id;
}
public void setCustomer(Customer customer)
{
this.customer=customer;
}
public Customer getCustomer()
{
return this.customer;
}
public void setOrdernumber(int ordernumber)
{
this.ordernumber=ordernumber;
}
public int getOrdernumber()
{
return this.ordernumber;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
<class name="Order" table="ORDERS">
<id name="id" column="ID">
<generator class="increment"/>
</id>
<property name="ordernumber" column="ORDERNUMBER"/>
<many-to-one name="customer" column="CUSTOMER_ID" class="Customer" cascade="save-update"/>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
<class name="Customer" table="CUSTOMERS">
<id name="id" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME"/>
<set name="orders" cascade="delete">
<key column="CUSTOMER_ID"/>
<one-to-many class="Order"/>
</set>
</class>
package service;
import util.*;
import entity.*;
import org.hibernate.*;
import java.util.*;
public class Test
{
public static void saveCustomerAndOrder()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=new Customer();
customer.setName("andy");
session.save(customer);
Order order=new Order();
Order order1=new Order();
order.setOrdernumber(1);
order.setCustomer(customer);
order1.setOrdernumber(2);
order1.setCustomer(customer);
session.save(order);
session.save(order1);
session.getTransaction().commit();
}
public static void saveCustomerAndOrderWithCascade()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=new Customer();
customer.setName("cao");
//session.save(customer);
Order order=new Order();
Order order1=new Order();
order.setOrdernumber(1);
order.setCustomer(customer);
order1.setOrdernumber(2);
order1.setCustomer(customer);
session.save(order);
session.save(order1);
session.getTransaction().commit();
}
public static Customer getCustomerThOrder()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=((Order)session.load(Order.class,new Long(1))).getCustomer();
session.getTransaction().commit();
if(customer!=null)
return customer;
return null;
}
public static Set getOrderThCustomer()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Set orders=((Customer)session.load(Customer.class,new Long(1))).getOrders();
session.getTransaction().commit();
if(orders.size()>0)
return orders;
return null;
}
public static void updateCustomerAndOrders()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
Order order = (Order)session.load(Order.class,new Long(3));
order.setCustomer(customer);
customer.getOrders().add(order);
session.getTransaction().commit();
}
public static void delCustomer()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
session.delete(customer);
session.getTransaction().commit();
}
public static void main(String[] args)
{
Test.delCustomer();
//Customer cst=Test.getCustomerThOrder();
//System.out.println(cst.getName());
//Test.updateCustomerAndOrders();
/*
Set orders=Test.getOrderThCustomer();
Iterator it=null;
for(it=orders.iterator();it.hasNext();)
{
Order order=(Order)it.next();
System.out.println(order.getId()+" || "+order.getOrdernumber()+" || "+order.getCustomer().getName());
}
//*/
//Test.saveCustomerAndOrderWithCascade();
//System.out.println( HibernateUtil.getSessionFactory());
}
}
</hibernate-mapping>
建立多对一的单向关联,也就是在order类里面建立到customer的关联,即在order类里面增加customer属性,这样通过order类即可以获得与之对应的customer信息,同时配置文件里面增加
<many-to-one name="customer" // 为order类里面增加的属性的名称
column=‘customer id’这个是外键的列的名称
class =“mypack。customer” 这个是外键所关联的那一个类 >
name:设定待映射的持久化类的属性名 column:设定和持久化类的属性对应的表的外键, class 设定持久化类的属性类型
这样建立的单向关联就可以进行单向的访问,
public static void saveCustomerAndOrder()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=new Customer();
customer.setName("andy");
session.save(customer);
Order order=new Order();
Order order1=new Order();
order.setOrdernumber(1);
order.setCustomer(customer);
order1.setOrdernumber(2);
order1.setCustomer(customer);
session.save(order);
session.save(order1);
session.getTransaction().commit();
}
上面的方法就是先保存customer然后在保存orders,其中order多属于customer的,如果我们仅仅是定义了customer对象不对它进行持久化,而我们又象对order进行持久化这样就会违背数据库的参照完整性,所以hibernate会抛出相应的异常,
org.hibernate.PropertyValueException : not-null property references a null or transientvalue 也就是告诉我们说order类的customer属性是不允许为空的 ,我们可以设定级联保存和更新来解决这个问题,
<many-to-one name="customer" column="CUSTOMER_ID" class="Customer" cascade="save-update"/>
在hibernate持久化一个临时对象(transient object)对象时,它不会自动持久化所关联的其他临时对象,这样就会抛出我们上面的那个异常,我们设定cascade为save-update,默认是none,这样保存orders的同时会先保存customer。
通过多对一的单向关联,我们可以通过order很容易的获得customer信息,但是如果反过来,现在我们需要根据customer信息来获得order信息,所以这样的时候,我们需要建立一对多的双向关联在customer类里面增加Set orders并且给出对应的get set方法,然后在hbmxml里面增加
<set name="orders">//这个是customer类里面的属性的名称
<key column="customer_id"/> 元素设定与所关联的持久化类对应的表的外键
<one-to -many class="order"/> 设定所关联的持久化类,此处为orders
</set>
通过这些我们就可以根据customer来获得自己的orders信息了,上面配置注意点:不要巴一个单元故意用enter来分成多行显示,否则会出现error
set元素的inverse
public static void updateCustomerAndOrders()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
Order order = (Order)session.load(Order.class,new Long(3));
order.setCustomer(customer);
customer.getOrders().add(order);
session.getTransaction().commit();
}
上面这个update方法在hibernate中实际上面是执行了两句sql语句update orders set ordernumber='aaaa' customerid='2' where customerid='2' , update orders set customerid=2 where id=2,
因为hibernate是根据内存中持久化对象的状态变化来决定需要执行那些sql语句的。inverse=true加上以后则表明customer端的关联只是order端关联的镜像,这样的话,就只会执行一条sql语句
<set name="orders" cascade="delete" inverse="true">
<key column="CUSTOMER_ID"/>
<one-to-many class="Order"/>
</set>
public static void updateCustomerAndOrders()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
Order order = (Order)session.load(Order.class,new Long(3));
??order.setCustomer(customer); 如果保留这一句会去更新database
//customer.getOrders().add(order); 如果只保留这句的话数据库并不会被更新
session.getTransaction().commit();
}
所以这就要求我们最好在写代码的时候写好双向关联的代码,提高程序的健壮性,而不去依赖底层的数据库或者hibernate来解决这些问题,一般情况下many端的inverse设成true,在上面的应用中也就是customer端,好像这里说many端会有些迷惑,向这set端就对了
映射一对多自身双向关联,上一个项目中就有这样的情况,一个公司 公司有0个或1个自己的母公司,当然一个公司也就可能容有0个或n个子公司,这样数据库设计一般为
create table company( id int auto_increment primary key,name varchar(20), Company_id int
constraint fk company_id references company(id));
也就是公司表里面有一个属性关联着自己的主键,自身关联
package entity;
import java.util.*;
public class Company
{
private Long id;
private String name;
private Company company;
private Set companys=new HashSet();
private void setId(Long id)
{
this.id=id;
}
public Long getId()
{
return this.id;
}
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
public void setCompany(Company company)
{
this.company=company;
}
public Company getCompany()
{
return this.company;
}
public void setCompanys(Set companys)
{
this.companys=companys;
}
public Set getCompanys()
{
return this.companys;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
<class name="Company" table="COMPANY">
<id name="id" column="ID">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string"/>
<many-to-one name="company" column="COMPANY_ID" class="Company" cascade="save-update"/>
<set name="companys">
<key column="COMPANY_ID"/>
<one-to-many class="Company"/>
</set>
</class>
</hibernate-mapping>
public static void saveCompany()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Company company=new Company();
company.setName("anxin_2");
company.setCompany((Company)session.load(Company.class,new Long(1)));
session.save(company);
session.getTransaction().commit();
}
public static String findVdrCompany()
{
Session session=HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Company company=(Company)session.load(Company.class,new Long(2));
String r=company.getCompany().getName();
session.getTransaction().commit();
return r;
}
上面就是自身关联相关的代码,但是有一个注意就是不要给里面的那个外键设定notnull,要不永远也加不进去数据了,呵呵
发表评论
-
hibernate初级 映射复合自然主键
2007-09-13 22:53 1479现在根据customer和orders ... -
hibernate初级 对象-映射组成关系
2007-09-09 22:21 1180域对象中,类之间存在四种关系,1关联,也就是类之间的引用关系, ... -
hibernate初级 hibernate中对象的状态及其相互关系
2007-09-09 15:27 1445在java中应用程序通过new创建一个java对象时,jvm会 ... -
hibernate初级 映射对象标识符
2007-09-05 23:35 1879Hibernate使用对象标识符来建立内存中的对象和数据库表中 ... -
hibernate初级 对象-关系映射基础
2007-09-04 22:45 1306学习精通Hibernate java对象持久化第4章联系如下: ...
相关推荐
### Hibernate初级教程图解知识点详解 #### 一、概述 Hibernate是一个开源的对象关系映射(Object-Relational Mapping,简称ORM)框架,它为Java应用程序提供了面向对象的方式来进行数据库操作。通过Hibernate,...
2. 关联映射:包括一对一、一对多、多对一、多对多关系的映射,以及懒加载和立即加载策略。 3. 集合映射:集合类型如List、Set、Map等在Hibernate中的映射方法和注意事项。 4. 动态模型和动态更新:允许程序在运行...
Hibernate支持一对一、一对多、多对一、多对多等多种关联关系映射,以及懒加载和立即加载策略。 九、性能优化 1. 批量操作:使用批处理来提高插入、更新和删除的效率。 2. 缓存策略:合理配置缓存,降低数据库访问...
基于标注的映射,如 `@Entity`(实体类型)、`@Table`(实体对应的表)、`@Id`(主键)、`@Basic`(普通属性)、`@Column`(映射列)、`@OneToOne`(一对一)、`@ManyToOne`(多对一)、`@OneToMany`(一对多)、`@...
### Hibernate初级学习知识点详解 #### 一、Hibernate简介与ORM概念 - **ORM技术定义**:对象关系映射(Object/Relational Mapping, ORM)是一种编程技术,用于将对象模型与关系型数据库模型进行桥接。它使得开发...
11. **多对一、一对多、多对多关系映射**:Hibernate可以方便地处理数据库中的这些关联关系,通过配置文件或注解设定关系映射。 **学习路线** 1. 首先,理解Hibernate的基础概念和架构。 2. 掌握配置文件的编写,...
Hibernate支持多种关联关系映射,如一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多(ManyToMany)。正确配置关联关系,可以实现对象间的导航访问,简化数据操作。 九、缓存机制 Hibernate...
8. **关联映射**: 详细讲解一对一、一对多、多对一、多对多的关联映射实现。 9. **缓存机制**: Hibernate的一级缓存和二级缓存的概念,以及如何配置和使用。 10. **性能优化**: 提供一些优化Hibernate应用的建议,...
2. **对象关系映射(ORM)**: ORM是Hibernate的核心特性,它通过映射文件将Java对象和数据库表关联起来,使得开发者可以使用面向对象的方式来处理数据库操作,减少了直接操作SQL的复杂度。 3. **Hibernate配置**: ...
10. **关联映射**:涵盖一对一、一对多、多对一、多对多等关联映射的配置和操作。 11. **延迟加载与立即加载**:理解懒加载和Eager加载的概念,以及它们在性能优化中的应用。 12. **事件监听器**:解释Hibernate的...
6. **一对多和多对一关系映射**:理解如何配置和使用实体间的一对多和多对一关系,例如在一个用户类中关联多个订单类,或者在一个订单类中引用一个用户类。 7. **级联操作**:级联属性允许我们在操作一个实体时自动...
在Hibernate中,通过配置文件可以定义实体间的一对多、一对一、多对多等关系。例如,一个用户可以有多个订单,一个订单对应多本书。在处理这些关联时,Hibernate会自动处理相关的关联查询和数据更新。 在实际项目中...
Hibernate则是一个对象关系映射(ORM)框架,允许开发者使用面向对象的编程方式来处理数据库操作。通过Hibernate,开发者可以将Java类与数据库表关联起来,减少了直接编写SQL语句的工作量,提高了开发效率和代码的可...
1. 一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)、多对多(ManyToMany)关联映射的配置与使用。 2. 联合主键(Composite Key)和自增主键(GeneratedValue)的设置。 3. 集合映射的性能优化策略,...
【描述】"第二次做关于struts的开发 受益良多~ 做的很基础 适合" 提示我们这是一个初级或进阶学习的项目,开发者在使用Struts进行第二次开发时,获得了深入的理解和实践经验。Struts是一个开源的MVC(Model-View-...
4. **ORM框架**:Hibernate和MyBatis是常用的ORM框架,熟悉它们的核心API,理解关联映射、继承映射、缓存机制和事务管理,可以帮助优化数据访问性能。 5. **Web前端开发**:HTML、CSS和JavaScript是基础,jQuery和...