Hibernate one-to-one 两方双向连接表关联
Hibernate中对于持久化实体间的关联关系有三种分类,第一个是一对一,第二个是一对多,第三个是多对多,对于多对一的关联关系认定为是一对多的反向,所以从实质上看这两者是一样的。而对于关联关系的设置,通常的做法是,对于一对一,将关联关系可以放在两方中的任何一方,而对于一对多,将关联关系放置在多方,由多方来控制一对多的关联关系,而对于多对多,需要将关联关系同时放置在两方,即由两方共同来控制多对多的关联关系,不过由于这样的做法带来很大的数据冗余,及其它不合理之处,所以这时会开辟第三张表用来映射多对多的关联关系。那么对于一对多或一对一的关联关系,我想将它们的关联关系用第三张表来表示,应该如何做呢?这就引出来了Hibernate的join的用法,它为我们提供了将一对一或多对多关联关系以第三张表的方式来表示,而不是由关联关系的两方的其中一方去控制。
?
一。Husband
?
?
package com.dream.model.couple;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午3:53 */public class Husband { private Integer id; private String name; private Wife wife; public Husband(String name) { this.name = name; } public Husband() { } public Husband(String name, Wife wife) { this.name = name; this.wife = wife; } public Wife wife() { return this.wife; }}?
?
<?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 default-access="field"> <class name="com.dream.model.couple.Husband" table="husband" dynamic-insert="true" dynamic-update="true"> <id name="id" column="id" type="java.lang.Integer"> <generator column="name" type="java.lang.String"/> <join table="couple"> <key column="husbandid"/> <many-to-one name="wife" lazy="false" column="wifeid" unique="true" cascade="save-update"/> </join> </class></hibernate-mapping>
?
二。Wife
?
?
package com.dream.model.couple;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午3:52 */public class Wife { private Integer id; private String name; private Husband husband; public Wife(String name) { this.name = name; } public Wife() { } public String name() { return this.name; }}??
<?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 default-access="field"> <class name="com.dream.model.couple.Wife" table="wife" dynamic-insert="true" dynamic-update="true"> <id name="id" column="id" type="java.lang.Integer"> <generator column="name" type="java.lang.String"/> <one-to-one name="husband" name="code">package com.dream.dao.standard;import com.dream.model.couple.Husband;import java.util.List;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午4:24 */public interface CoupleDao { void saveOrUpdateHusband(Husband husband); List<Husband> findHusbandsByName(String name);}?
?
package com.dream.dao;import com.dream.dao.standard.CoupleDao;import com.dream.model.couple.Husband;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import java.util.List;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午4:24 */public class CoupleDaoImpl extends HibernateDaoSupport implements CoupleDao { @Override public void saveOrUpdateHusband(Husband husband) { getHibernateTemplate().saveOrUpdate(husband); } @Override public List<Husband> findHusbandsByName(String name) { return getHibernateTemplate().find("from Husband husband where husband.name=?", name); }}?
四。CoupleService
?
?
package com.dream.service.standard;import com.dream.model.couple.Husband;import java.util.List;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午4:23 */public interface CoupleService { void saveOrUpdateHusband(Husband husband); List<Husband> loadHusbandsByName(String name);}?
?
package com.dream.service;import com.dream.dao.standard.CoupleDao;import com.dream.model.couple.Husband;import com.dream.service.standard.CoupleService;import java.util.List;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午4:23 */public class CoupleServiceImpl implements CoupleService { private CoupleDao coupleDao; @Override public void saveOrUpdateHusband(Husband husband) { coupleDao.saveOrUpdateHusband(husband); } @Override public List<Husband> loadHusbandsByName(String name) { return coupleDao.findHusbandsByName(name); } public void setCoupleDao(CoupleDao coupleDao) { this.coupleDao = coupleDao; }}?
五。testDB
?
?
db.url=jdbc:mysql://localhost:3306/couple?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8db.driver=com.mysql.jdbc.Driverdb.username=rootdb.password=roothibernate.dialect=org.hibernate.dialect.MySQL5Dialecthibernate.show_sql=truehibernate.hbm2ddl.auto=updatehibernate.jdbc.batch_size=100
?
六。testDataSource
?
?
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" default-autowire="byName"> <context:property-placeholder location="classpath:testDB.properties"/> <bean id="dataSource" value="${db.driver}"/> <property name="url" value="${db.url}"/> <property name="username" value="${db.username}"/> <property name="password" value="${db.password}"/> </bean> <bean id="sessionFactory" ref="dataSource"/> <property name="mappingLocations"> <list> <value>classpath:/hibernate_mappings/Husband.hbm.xml</value> <value>classpath:/hibernate_mappings/Wife.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop> </props> </property> </bean> <bean id="transactionManager" ref="sessionFactory"/> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="service" expression="execution(* com.dream.service..*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="service"/> </aop:config> <bean id="coupleDao" ref="sessionFactory"/> </bean> <bean id="coupleService" ref="coupleDao"/> </bean></beans>?
? 七。Test
?
?
package com.dream.couple;import com.dream.model.couple.Husband;import com.dream.model.couple.Wife;import com.dream.service.standard.CoupleService;import junit.framework.TestCase;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;/** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-10-15 * Time: 下午4:10 */public class HibernateJoinTest extends TestCase { private CoupleService coupleService; @Override public void setUp() throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:testDataSource.xml"); coupleService = (CoupleService) context.getBean("coupleService"); } public void testOneToOneJoin() throws Exception { Wife wife = new Wife("wife"); Husband husband = new Husband("husband", wife); coupleService.saveOrUpdateHusband(husband); } public void testFindHusband() throws Exception { List<Husband> husbands = coupleService.loadHusbandsByName("husband"); assertEquals(1, husbands.size()); Husband husband = husbands.get(0); Wife wife = husband.wife(); assertEquals("wife", wife.name()); }}?
跑完第一个测试,发出的sql语句
?

?
? 跑完第二个测试,发出的sql语句
?
Hibernate: select husband0_.id as id0_, husband0_.name as name0_, husband0_1_.wifeid as wifeid1_ from husband husband0_ inner join couple husband0_1_ on husband0_.id=husband0_1_.husbandid where husband0_.name=?Hibernate: select wife0_.id as id2_1_, wife0_.name as name2_1_, husband1_.id as id0_0_, husband1_.name as name0_0_, husband1_1_.wifeid as wifeid1_0_ from wife wife0_ left outer join husband husband1_ on wife0_.id=husband1_.id left outer join couple husband1_1_ on husband1_.id=husband1_1_.husbandid where wife0_.id=?Hibernate: select wife0_.id as id2_1_, wife0_.name as name2_1_, husband1_.id as id0_0_, husband1_.name as name0_0_, husband1_1_.wifeid as wifeid1_0_ from wife wife0_ left outer join husband husband1_ on wife0_.id=husband1_.id left outer join couple husband1_1_ on husband1_.id=husband1_1_.husbandid where wife0_.id=??
?
来看看跑完测试后,数据库中相关的数据表:
?
