Hibernate多对多关联关系

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:orcl" />
		<property name="username" value="hibernate" />
		<property name="password" value="hibernate" />
		<!-- 连接池启动时的初始值 -->
		<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.many2many.bean.Address</value>
			    <value>com.entity.many2many.bean.Customer</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>


2.Entity(Address)

package com.entity.many2many.bean;

import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name = "addresses")
public class Address {
	private int id;
	private String addressLine;
	private String country;
	private String postCode;
	private Set<Customer> customers;

	@Id
	@GenericGenerator(name = "GenericGenerator", strategy = "sequence",
	parameters = { @Parameter(value = "seq_address", name = "sequence") })
	@GeneratedValue(generator="GenericGenerator")
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getAddressLine() {
		return addressLine;
	}

	public void setAddressLine(String addressLine) {
		this.addressLine = addressLine;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getPostCode() {
		return postCode;
	}

	public void setPostCode(String postCode) {
		this.postCode = postCode;
	}
	//本方可以维护关系 
	@ManyToMany(mappedBy = "addresses")
	public Set<Customer> getCustomers() {
		return customers;
	}

	public void setCustomers(Set<Customer> customers) {
		this.customers = customers;
	}

	@Override
	public String toString() {
		return "[Address: id=" + id + ", country=" + country + "]";
	}
	



}


3.Entity(Customer)

package com.entity.many2many.bean;
import java.util.Collection;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.criterion.Order;


@Entity
@Table(name = "customers")
public class Customer {
	private int id;
	private String name;
	private Set<Address> addresses;
	// @JoinTable注释用于指定连接表和t_customers及t_addresses表的连接字段关系。
	@Id
	@GenericGenerator(name = "GenericGenerator", strategy = "sequence", parameters = { @Parameter(value = "seq_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;
	}
	@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
	@JoinTable(name = "t_customers_addresses", joinColumns = @JoinColumn(name = "customer_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"))
	public Set<Address> getAddresses() {
		return addresses;
	}
	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "[Customer: id=" + id + ", name=" + name + "]";
	}

}


4.多对多关联图

从上面两个实体类,得到实体关联关系对照图

5.Service

package com.entity.many2many.service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.entity.many2many.bean.Address;
import com.entity.many2many.bean.Customer;

@Service("customerService")
@Transactional
public class CustomerService {
	@Resource
	private SessionFactory sessionFactory;
	//多对多保存
	public void save() {
		Customer customer = new Customer();
		customer.setName("微软11");
		Set<Address> addresses = new HashSet<Address>();
		Address address = new Address();
		address.setAddressLine("address1");
		address.setCountry("中国");
		address.setPostCode("12345678");
		addresses.add(address);
		address = new Address();
		address.setAddressLine("address2");
		address.setCountry("美国");
		address.setPostCode("4321");
		addresses.add(address);
		customer.setAddresses(addresses);
		sessionFactory.getCurrentSession().persist(customer);
	}

	public void sayHello() {
		System.out.println("say Hello");
	}
	//根据id获取customer信息
	public Customer getCustomer(Integer id) {
		return (Customer) sessionFactory.getCurrentSession().get(
				Customer.class, id);
	}
	//根据id获取address信息
	public Address getAddress(Integer id) {
		return (Address) sessionFactory.getCurrentSession().get(Address.class,
				id);
	}
	//根据address id 获取address与customer信息 内连接
	public List getCustomsAlls(Integer id) {
		return sessionFactory
				.getCurrentSession()
				.createQuery(
						" select DISTINCT o from Address o inner join fetch o.customers where o.id='"+id+"' order by o.id ")
				.list();
	}
	//根据customer id获取customer与address信息
	public List getAddressesAlls(Integer id) {
		return sessionFactory
				.getCurrentSession()
				.createQuery(
						" select DISTINCT o from Customer o inner join fetch o.addresses where o.id='"+id+"' order by o.id ")
				.list();
	}
	//获取所有的customer与address信息
	public List getAlls() {
		return sessionFactory
				.getCurrentSession()
				.createQuery(
						" select DISTINCT o from Customer o inner join fetch o.addresses order by o.id ")
				.list();
	}
	//这个方式无法移除关联关系
	public void RemoveRelationCustomerNull(Integer id){
		Address address=(Address) sessionFactory.getCurrentSession().get(Address.class, id);
		address.setCustomers(null);
		sessionFactory.getCurrentSession().persist(address);
	}
	//这个方式无法移除关联关系
	public void RemoveRelationAddressNull(Integer id){
		Customer customer=(Customer) sessionFactory.getCurrentSession().get(Customer.class, id);
		customer.setAddresses(null);
		sessionFactory.getCurrentSession().persist(customer);
		
	}
	//移除customer
	public void RemoveRelationCustomer(Integer id){
		Customer customer=(Customer) sessionFactory.getCurrentSession().get(Customer.class, id);
		customer.getAddresses().clear();
	}
	public void RemoveRelationAddress(Integer id){
		Address address=(Address) sessionFactory.getCurrentSession().get(Address.class, id);
		address.getCustomers().clear();
	}
	public void deleteCustomer(Integer id){
		sessionFactory.getCurrentSession().delete(sessionFactory.getCurrentSession().get(Customer.class, id));
	}
	
	public void deleteAddress(Integer id){
		sessionFactory.getCurrentSession().delete(sessionFactory.getCurrentSession().get(Address.class, id));
	}
}


6.Test

package junit.test;

import java.util.List;
import java.util.Set;

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.entity.many2many.bean.Address;
import com.entity.many2many.bean.Customer;
import com.entity.many2many.service.CustomerService;

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 testSayHello() {
		customerService.sayHello();
	}

	@Test
	public void testSave() {
		customerService.save();
	}

	@Test
	public void testGetCustomer() {
		Customer customer = customerService.getCustomer(1);
		System.out.println(customer.getName());
	}

	@Test
	public void testGetAddress() {
		Address address = customerService.getAddress(1);
		System.out.println(address.getCountry());
	}

	@Test
	public void testGetAll() {
		List objects = customerService.getAlls();
		for (Customer c : (List<Customer>) objects) {
			System.out.println(c.getName());
			for (Address a : (Set<Address>) c.getAddresses()) {
				System.out.println(a.getCountry());
			}
		}
	}

	@Test
	public void testGetAddressesAlls() {
		List objects = customerService.getAddressesAlls(1);
		for (Customer c : (List<Customer>) objects) {
			System.out.println(c.getName());
			for (Address a : (Set<Address>) c.getAddresses()) {
				System.out.println(a.getCountry());
			}
		}
	}

	@Test
	public void testGetCustomsAlls() {
		List objects = customerService.getCustomsAlls(1);
		for (Address c : (List<Address>) objects) {
			System.out.println(c.getCountry());
			for (Customer a : (Set<Customer>) c.getCustomers()) {
				System.out.println(a.getName());
			}
		}
	}

	// 移除关联关系,同时删除自己
	@Test
	public void testDeleteCustomes() {
		customerService.deleteCustomer(1);
	}

	// 不能删除本方
	// 不能移除关联关系
	@Test
	public void testDeleteAddress() {
		customerService.deleteAddress(22);
	}

	@Test
	public void tesetDeleteAll() {
		customerService.deleteCustomer(21);
		customerService.deleteAddress(21);
	}
	//移除关系成功
	@Test
	public void testRemoveRelationCustomer() {
		customerService.RemoveRelationCustomer(3);
	}
	//移除关系成功
	@Test
	public void testRemoveRelationAddress() {
		customerService.RemoveRelationAddress(2);
	}
	//无法移除
	@Test
	public void testRemoveRelationCustomerNull(){
		customerService.RemoveRelationCustomerNull(1);
	}
	//可以移除
	@Test
	public void testRemoveRelationAddressNull(){
		customerService.RemoveRelationAddressNull(2);
	}

}


 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。