码迷,mamicode.com
首页 > 其他好文 > 详细

EnityBean一对一关联关系

时间:2014-07-21 23:29:41      阅读:414      评论:0      收藏:0      [点我收藏+]

标签:des   blog   http   java   使用   os   

一、工程架构:

工程资源下载地址:http://download.csdn.net/detail/u012750578/7660633

bubuko.com,布布扣

二、beans.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- 基于注解方式 http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring 
	http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd -->
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring   
  		   http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.entity"></context:component-scan>
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl11g" />
		<property name="username" value="entity" />
		<property name="password" value="entity" />
		<!-- 连接池启动时的初始值 -->
		<property name="initialSize" value="1" />
		<!-- 连接池的最大值 -->
		<property name="maxActive" value="500" />
		<!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
		<property name="maxIdle" value="2" />
		<!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
		<property name="minIdle" value="1" />
	</bean>
	<!-- org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean 
		基于注解的sessionFactroy -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
		name="sessionFactory">
		<property name="dataSource" ref="dataSource" />

		<property name="hibernateProperties">
			<value>
				hibernate.dialect=org.hibernate.dialect.OracleDialect
				hibernate.hbm2ddl.auto=update
				hibernate.show_sql=true
				hibernate.format_sql=true
				hibernate.cache.use_second_level_cache=true
				hibernate.cache.use_query_cache=false
				hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
			</value>
		</property>
		<!-- annotatedClasses -->
		<property name="annotatedClasses">
			<list>
				<value>com.entity.one2one.bean.Customer</value>
				<value>com.entity.one2one.bean.Referee</value>
				<value>com.entity.one2one.bean.CustomerPrimary</value>
				<value>com.entity.one2one.bean.RefereePrimary</value>
			</list>
		</property>
	</bean>
	<bean id="txManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<tx:annotation-driven transaction-manager="txManager" />

</beans>


三、基于共享主键一对一多关系

1、EntityBean

      RefereePrimary:

@Entity
@Table(name="t_primary_referee")
public class RefereePrimary {
	private int id;
	private String name;
	private CustomerPrimary customer;
	@OneToOne
	@PrimaryKeyJoinColumn
	public CustomerPrimary getCustomer() {
		return customer;
	}
	public void setCustomer(CustomerPrimary customer) {
		this.customer = customer;
	}
	//采用基于主键的一对一映射时,要把主键生成策略改为foreign
	//属性对应customer
	@Id
	@GeneratedValue(generator="pkGenerator")
	@GenericGenerator(name="pkGenerator",strategy="foreign",
	parameters=@Parameter(name="property",value="customer"))
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

CustomerPrimary:

@Entity
@Table(name = "t_primary_customer")
public class CustomerPrimary {
	private int id;
	private String name;
	private RefereePrimary referee;

	@Id
	// 标注表示这个id属性是外键,并且依赖于customer属性相对应的实体bean的id属性值(主键值)
	@GenericGenerator(name = "GenericGenerator", strategy = "sequence", parameters = { @Parameter(value = "seq_primary_customer", name = "sequence") })
	@GeneratedValue(generator = "GenericGenerator")
	public int getId() {
		return id;
	}

	/**
	 * 注意: 由于t_referee表的id自增类型已经去掉而且该类依赖于t_customers表的id字段值
	 * ,因此就不能直接持久化referee对象了,而是持久化customer对象的同时,容器会自动将referee持久化的
	 * 
	 * @param id
	 */
	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	// 共享主键
	@OneToOne(cascade = CascadeType.ALL)
	@PrimaryKeyJoinColumn
	public RefereePrimary getReferee() {
		return referee;
	}

	public void setReferee(RefereePrimary referee) {
		this.referee = referee;
	}

}

2、Service

@Service("customerPrimaryService")
@Transactional
public class CustomerPrimaryService {
	@Resource
	private SessionFactory sessionFactory;
	//测试保存
	public void savePrimary() {
		CustomerPrimary customer = new CustomerPrimary();
		customer.setName("微软");

		RefereePrimary referee = new RefereePrimary();
		referee.setName("赵军");
		// 关联起来
		// 使用基于主键的一对一时:也是只有有外键方可以保存关联关系
		customer.setReferee(referee);
		referee.setCustomer(customer);
		// 先保存无外键方,先保存主键方
		sessionFactory.getCurrentSession().persist(customer);
		// 再保存有外键方,因为有外键方要引用无外键方的主键值
		sessionFactory.getCurrentSession().persist(referee);

	}
	//测试根据id获取
	public CustomerPrimary getCustomerPrimary(int id) {
		return (CustomerPrimary) sessionFactory.getCurrentSession().get(
				CustomerPrimary.class, 1);
	}
	//测试根据id获取
	public RefereePrimary getRefereePrimary(int id) {
		return (RefereePrimary) sessionFactory.getCurrentSession().get(
				RefereePrimary.class, 1);
	}

	// 移除关联关系
	// 使用基于主键的一对一时,双方都不可以移除关联关系
	public void RemoveRelationPrimary() {
		CustomerPrimary customer = (CustomerPrimary) sessionFactory
				.getCurrentSession().get(CustomerPrimary.class, 1);
		customer.setReferee(null);
		sessionFactory.getCurrentSession().persist(customer);
	}

	// 移除关联关系
	// 使用基于主键的一对一时,双方都不可以移除关联关系
	public void RemoveRelationNoPrimary() {
		RefereePrimary referee = (RefereePrimary) sessionFactory
				.getCurrentSession().get(RefereePrimary.class, 1);
		referee.setCustomer(null);
		sessionFactory.getCurrentSession().persist(referee);
	}

	// 因为RefereePrimary是无外键言,不可以维护关联关系,所以删除RefereePrimary时,如果有关联的Customer,就会抛异常
	// 因为CustomerPrimary的id有引用RefereePrimary的id
	public void DeleteNoForeign() {
		sessionFactory.getCurrentSession()
				.delete(sessionFactory.getCurrentSession().get(
						RefereePrimary.class, 1));
	}
	//删除就同时删除CustomerPrimary与RefereePrimary记录
	public void DeleteForeign() {
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession()
						.get(CustomerPrimary.class, 1));
	}
	//测试删除
	public void DeleteAll() {
		// 先删除有外键方
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession()
						.get(CustomerPrimary.class, 2));

	}
	//测试获取列表信息
	@SuppressWarnings("unchecked")
	public List<CustomerPrimary> getCustomerPrimarys(){
		return sessionFactory.getCurrentSession().createQuery("from CustomerPrimary").list();
	}
	//测试获取列表信息
	@SuppressWarnings("unchecked")
	public List<RefereePrimary> getRefereePrimarys(){
		return sessionFactory.getCurrentSession().createQuery("from RefereePrimary").list();
	}
	
}

3、Junit测试

public class CustomerPrimaryServiceTest {
	private static CustomerPrimaryService customerPrimaryService;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		try {
			ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
					"beans.xml");
			customerPrimaryService = (CustomerPrimaryService) applicationContext
					.getBean("customerPrimaryService");
		} catch (RuntimeException e) {
			e.printStackTrace();
		}
	}
	//测试保存
	@Test
	public void testSavePrimary() {
		customerPrimaryService.savePrimary();
	}
	//测试获取关联获取值
	@Test 
	public void testGetPrimaryCustomer(){
		CustomerPrimary customer=customerPrimaryService.getCustomerPrimary(1);
		System.out.println(customer.getReferee().getName());
	}
	//测试获取关联获取值
	@Test 
	public void testGetPrimaryReferee(){
		RefereePrimary referee=customerPrimaryService.getRefereePrimary(1);
		System.out.println(referee.getCustomer().getName());
	}
	//测试移除关系关系
	@Test
	public void testRemoveRelationPrimary(){
		customerPrimaryService.RemoveRelationPrimary();
	}
	//测试移除关系关系
	@Test
	public void testRemoveRelationNoPrimary(){
		customerPrimaryService.RemoveRelationNoPrimary();
	}
	//无外键方,不可以删除
	@Test
	public void testDeleteNoForeign(){
		customerPrimaryService.DeleteNoForeign();
	}
	// 有外键方 可以删除,删除是删除两个表的信息
	@Test
	public void testDeleteForeign(){
		customerPrimaryService.DeleteForeign();
	}
	//测试获取列表信息
	@Test
	public void testGetCustomerPrimarys(){
		for(CustomerPrimary c:customerPrimaryService.getCustomerPrimarys()){
			System.out.println(c.getName());
		}
	}
	//测试获取列表信息
	@Test
	public void testGetPrimaryReferees(){
		for(RefereePrimary r:customerPrimaryService.getRefereePrimarys()){
			System.out.println(r.getName());
		}
	}
}

四、采用基于外键一对一关联关系(重点,一般采用此种方式)
1、EntityBean

@Entity
@Table(name="t_customer")
public class Customer {
	private int id;
	private String name;
	private Referee referee;
	@Id
	@GenericGenerator(name = "GenericGenerator", strategy = "sequence",
	parameters = { @Parameter(value = "seq_t_customer", name = "sequence") })
	@GeneratedValue(generator="GenericGenerator")
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * 默认外键名referee_id
	 * @OneToOne
	 * 	public Referee getReferee() {
		return referee;
		}
	 * @return
	 */
	
	/**
	 * /使用新的外键名:referee1_id
	 * 	@OneToOne
		@JoinColumn(name="referee1_id")
		public Referee getReferee() {
			return referee;
		}
	 * @return
	 */
	@OneToOne
	@JoinColumn(name="referee_id")
	public Referee getReferee() {
		return referee;
	}
	/**
	 * 从上面的代码可以看出,getReferee方法使用了@OneToOne进设置
	 * 在装载Customer对象的同时,Referee对象会被同时装载,而默认的外键字段就是Customer类中的referee属性名+"_"+id
	 * 也就是referee_id
	 * @param referee
	 */
	public void setReferee(Referee referee) {
		this.referee = referee;
	}
}

Referee:

@Entity
@Table(name="t_referee")
public class Referee {
	private int id;
	private String name;
	private Customer customer;
	
	@Id
	@GenericGenerator(name = "GenericGenerator", strategy = "sequence",
	parameters = { @Parameter(value = "seq_t_referee", name = "sequence") })
	@GeneratedValue(generator="GenericGenerator")
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@OneToOne(mappedBy="referee")
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
}

2、Service

@Service("customerService")
@Transactional
public class CustomerService {
	@Resource
	private SessionFactory sessionFactory;

	public void saveForgin() {

		Customer customer = new Customer();
		customer.setName("微软");

		Referee referee = new Referee();
		referee.setName("赵军");
		customer.setReferee(referee);
		referee.setCustomer(customer);
		// 先保存无外键方
		sessionFactory.getCurrentSession().persist(referee);
		sessionFactory.getCurrentSession().persist(customer);

	}

	public Customer getCustomer(int id) {
		return (Customer) sessionFactory.getCurrentSession().get(
				Customer.class, id);
	}

	public Referee getReferee(int id) {
		return (Referee) sessionFactory.getCurrentSession().get(Referee.class,
				id);
	}

	/**
	 * 外键方可以维护关系 移除关联关系
	 */
	public void RemoveRelationForeign() {
		Customer customer = (Customer) sessionFactory.getCurrentSession().get(
				Customer.class, 1);
		customer.setReferee(null);
		sessionFactory.getCurrentSession().persist(customer);
	}

	/**
	 * 无外键方,无法维护关系 ,不可以维护关联关系,所以删除Referee时,如果有关联的Customer,就会抛异常 导致双方都删除不成功
	 */
	public void RemoveRelationNoForeign() {
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession().get(Referee.class, 1));
	}
	/**
	 * 外键方可以维护关系,
	 * 会先移除关联关系
	 * 删除有外键方,
	 */
	public void RemoveRelationForeignOne()  {
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession().get(Customer.class, 1));
	}
	public void DeleteNoForeignOne(){
		////先删除有外键方
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession().get(Referee.class, 1));
	}
	public void DeleteForeignOne(){
		////先删除有外键方
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession().get(Customer.class, 1));
	}
	public void DeleteForeignTow()   {
		////先删除有外键方
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession().get(Customer.class, 1));
		//再删除无外键方
		sessionFactory.getCurrentSession().delete(
				sessionFactory.getCurrentSession().get(Referee.class, 1));
	}
	@SuppressWarnings("unchecked")
	public List<Customer> getCustomers(){
		return sessionFactory.getCurrentSession().createQuery("from Customer").list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Referee> getReferees(){
		return sessionFactory.getCurrentSession().createQuery("from Referee").list();
	}
}

3、Junit测试

public class CustomerServiceTest {
	private static CustomerService customerService;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		try {
			ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
					"beans.xml");
			customerService = (CustomerService) applicationContext
					.getBean("customerService");
		} catch (RuntimeException e) {
			e.printStackTrace();
		}
	}

	// 测试保存
	@Test
	public void testSaveForgin() {
		customerService.saveForgin();
	}

	// 测试获取关联对象的属性值
	@Test
	public void testGetCustomer() {
		Customer customer = customerService.getCustomer(1);
		System.out.println(customer.getReferee().getName());
	}

	// 测试获取关联对象的属性值
	@Test
	public void testGetReferee() {
		Referee referee = customerService.getReferee(1);
		System.out.println(referee.getCustomer().getName());
	}

	// 测试移除关联有关系
	// 外键方可以维护关系 移除关联关系
	@Test
	public void testRemoveRelationForeign() {
		customerService.RemoveRelationForeign();
	}

	// 测试移除关联有关系
	// 无外键方,无法维护关系 ,不可以维护关联关系,所以删除Referee时,如果有关联的Customer,就会抛异常 导致双方都删除不成功
	@Test
	public void testRemoveRelationNoForeign() {
		customerService.RemoveRelationNoForeign();

	}
	//删除无外键方,不能删除
	@Test
	public void testDeleteNoForeignOne(){
		customerService.DeleteNoForeignOne();
	}
	//删除有外键方,可以删除
	@Test
	public void testDeleeteForeignOne(){
		customerService.DeleteForeignOne();
	}
	//两个再时删除,先删除有外键方,再删除无外键方
	@Test
	public void testDeleteForeignTow() {
		customerService.DeleteForeignTow();
	}
	@Test
	public void testGetReferees(){
		for(Referee r:customerService.getReferees()){
			System.out.println(r.getName());
		}
	}
	
	@Test
	public void testGetCustomers(){
		for(Customer c:customerService.getCustomers()){
			System.out.println(c.getName());
		}
	}
}




EnityBean一对一关联关系,布布扣,bubuko.com

EnityBean一对一关联关系

标签:des   blog   http   java   使用   os   

原文地址:http://blog.csdn.net/u012750578/article/details/38023341

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!