標籤:多對多實體關聯 many2many
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.OracleDialecthibernate.hbm2ddl.auto=updatehibernate.show_sql=truehibernate.format_sql=truehibernate.cache.use_second_level_cache=truehibernate.cache.use_query_cache=falsehibernate.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;}@Overridepublic 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;}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "[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")@Transactionalpublic class CustomerService {@Resourceprivate 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);}//移除customerpublic 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;@BeforeClasspublic static void setUpBeforeClass() throws Exception {try {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");customerService = (CustomerService) applicationContext.getBean("customerService");} catch (RuntimeException e) {e.printStackTrace();}}@Testpublic void testSayHello() {customerService.sayHello();}@Testpublic void testSave() {customerService.save();}@Testpublic void testGetCustomer() {Customer customer = customerService.getCustomer(1);System.out.println(customer.getName());}@Testpublic void testGetAddress() {Address address = customerService.getAddress(1);System.out.println(address.getCountry());}@Testpublic 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());}}}@Testpublic 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());}}}@Testpublic 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());}}}// 移除關聯關係,同時刪除自己@Testpublic void testDeleteCustomes() {customerService.deleteCustomer(1);}// 不能刪除本方// 不能移除關聯關係@Testpublic void testDeleteAddress() {customerService.deleteAddress(22);}@Testpublic void tesetDeleteAll() {customerService.deleteCustomer(21);customerService.deleteAddress(21);}//移除關係成功@Testpublic void testRemoveRelationCustomer() {customerService.RemoveRelationCustomer(3);}//移除關係成功@Testpublic void testRemoveRelationAddress() {customerService.RemoveRelationAddress(2);}//無法移除@Testpublic void testRemoveRelationCustomerNull(){customerService.RemoveRelationCustomerNull(1);}//可以移除@Testpublic void testRemoveRelationAddressNull(){customerService.RemoveRelationAddressNull(2);}}
Hibernate多對多關聯關係