public class ProjectVO {
private Integer projectId;
private Set projectChjs = new HashSet();
public Integer getProjectId() {
return projectId;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public Set getProjectChjs() {
return projectChjs;
}
public void setProjectChjs(Set projectChjs) {
this.projectChjs = projectChjs;
}
public boolean addProjectChjVO(ProjectChjVO projectChjVO) {
if (this.projectChjs.add(projectChjVO)) {
projectChjVO.setProjectVO(this);
return true;
}
return false;
}
}
public class ProjectChjVO {
private Integer projectChj;
private ProjectVO projectVO;
public Integer getProjectChj() {
return projectChj;
}
public void setProjectChj(Integer projectChj) {
this.projectChj = projectChj;
}
public ProjectVO getProjectVO() {
return projectVO;
}
public void setProjectVO(ProjectVO projectVO) {
this.projectVO = projectVO;
}
}
<?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="vo">
<class name="ProjectVO" table="project" lazy="false">
<id name="projectId" type="java.lang.Integer">
<column name="PROJECT_ID" precision="5" scale="0" />
<generator class="native" />
</id>
<set name="projectChjs" inverse="true" lazy="true" outer-join="true" cascade="save-update">
<!-- lazy="true"表示延迟加载,out-join="true" 表示当select时会外连接集合-->
<key>
<column name="PROJECT_ID" /> <!-- PROJECT_ID为projectchj表的外键,如果命为其他名也
行.-->
</key>
<one-to-many class="ProjectChjVO" />
</set>
</class>
</hibernate-mapping>
set节点有以下属性(摘自Hibernate文档):
(1) name 集合属性的名称
(2) table (可选——默认为属性的名称)这个集合表的名称(不能在一对多的关联关系中使用)
(3) schema (可选) 表的schema的名称, 他将覆盖在根元素中定义的schema
(4) lazy (可选——默认为false) lazy(可选--默认为false) 允许延迟加载(lazy initialization )(不能在数
组中使用)
(5) inverse (可选——默认为false) 标记这个集合作为双向关联关系中的方向一端。
(6) cascade (可选——默认为none) 让操作级联到子实体
(7) sort(可选)指定集合的排序顺序, 其可以为自然的(natural)或者给定一个用来比较的类。
(8) order-by (可选, 仅用于jdk1.4) 指定表的字段(一个或几个)再加上asc或者desc(可选), 定义Map,Set和Bag
的迭代顺序
(9) where (可选) 指定任意的SQL where条件, 该条件将在重新载入或者删除这个集合时使用(当集合中的数据仅
仅是所有可用数据的一个子集时这个条件非常有用)
(10) outer-join(可选)指定这个集合,只要可能,应该通过外连接(outer join)取得。在每一个SQL语句中, 只能有
一个集合可以被通过外连接抓取(译者注: 这里提到的SQL语句是取得集合所属类的数据的Select语句)
(11) batch-size (可选, 默认为1) 指定通过延迟加载取得集合实例的批处理块大小("batch size")。
(12) access(可选-默认为属性property):Hibernate取得属性值时使用的策略
由于在建立外键的时候就声明了ON DELETE CASCADE,所以在xml的配置文件中cascade声明为save-update。
如果声明为all,那么在删除Province表的数据时,会无谓的多出一条删除City的delete语句出来,这将会影响程序
的性能。
<?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="vo">
<class name="ProjectChjVO" table="projectchj" lazy="true">
<id name="projectChj" type="java.lang.Integer">
<column name="PROJECTCHJ_ID" precision="5" scale="0" />
<generator class="native">
</generator>
</id>
<many-to-one name="projectVO" class="ProjectVO" update="true" insert="true">
<column name="PROJECT_ID" /> <!-- PROJECT_ID为projectchj表的外键,如果命为其他名也行.通
过数据库表中定义的外键,与project表的主键关联-->
</many-to-one>
</class>
</hibernate-mapping>
many-to-one节点有以下属性(摘自Hibernate文档):
(1) name: 属性名。
(2) column (可选): 字段名。
(3) class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。
(4) cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。
(5) outer-join(外连接) (可选 - 默认为 自动): 当设置hibernate.use_outer_join的时候,对这个关联允许
外连接抓取。
(6) update, insert (可选 - defaults to true) 指定对应的字段是否在用于UPDATE 和/或 INSERT的SQL语句中
包含。如果二者都是false,则这是一个纯粹的“外源性(derived)”关联,它的值是通过映射到同一个(或多个)
字段的某些其他属性得到的,或者通过trigger(除法器),或者是其他程序。
(7) property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方
关联类的主键。
(8) access (可选 - 默认是 property): Hibernate用来访问属性的策略。
cascade 属性允许下列值: all, save-update, delete, none。设置除了none以外的其它值会传播特定的操作到关
联的(子)对象中。参见后面的“Lifecycle Objects(自动管理生命周期的对象)”。
outer-join参数允许下列三个不同值:
auto (默认) 使用外连接抓取关联(对象),如果被关联的对象没有代理(proxy)
true 一直使用外连接来抓取关联
false 永远不使用外连接来抓取关联
public class UserDAO extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(UserDAO.class);
public void saveProjectVO(ProjectVO transientInstance) {
log.debug("saving User instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
public void saveProjectChjVO(ProjectChjVO transientInstance) {
log.debug("saving User instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
public void saveProjectChjVO(ProjectChjVO transientInstance,Integer projectId) {
log.debug("saving User instance");
try {
ProjectVO projectVO =findProjectVOById(projectId);
projectVO.addProjectChjVO(transientInstance);
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-
beans.dtd">
<beans>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://127.0.0.1:3306/sample?
useUnicode=true&characterEncoding=gb2312</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>vo/ProjectVO.hbm.xml</value>
<value>vo/ProjectChjVO.hbm.xml</value></list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean
class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="UserDAO" class="dao.UserDAO">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="service"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="transactionManager"/></property>
<property name="target"><ref local="serviceTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
</beans>
package test;
import java.util.HashSet;
import java.util.Set;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import vo.ProjectChjVO;
import vo.ProjectVO;
import dao.UserDAO;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/applicationContext.xml");
UserDAO dao = UserDAO.getFromApplicationContext(context);
ProjectVO aa=new ProjectVO();
// aa.setProjectNo("111");
// dao.saveProjectVO(aa);
ProjectChjVO bb=new ProjectChjVO();
bb.setProjectVO(aa);
aa.setProjectChjs(new HashSet());
aa.getProjectChjs().add(bb);
dao.saveProjectVO(aa);
Set list=((ProjectVO)dao.findProjectVOById(new Integer(9))).getProjectChjs();
for(int i=0;i<list.size();i++)
System.out.println(list.iterator().next());
dao.saveProjectChjVO(new ProjectChjVO(),new Integer(9));
}
}
sql:
CREATE TABLE `project` (
`PROJECT_ID` int(11) NOT NULL auto_increment,
PRIMARY KEY (`PROJECT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
CREATE TABLE `projectchj` (
`PROJECTCHJ_ID` int(11) NOT NULL auto_increment,
`PROJECT_ID` int(11) default NULL,
PRIMARY KEY (`PROJECTCHJ_ID`),
KEY `PROJECT_ID` (`PROJECT_ID`),
CONSTRAINT `projectchj_fk` FOREIGN KEY (`PROJECT_ID`) REFERENCES `project` (`PROJECT_ID`) ON DELETE
CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=gbk;