一、工程架构:
工程资源下载地址:http://download.csdn.net/detail/u012750578/7660633
二、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;
}
}@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;
}
}@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();
}
}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;
}
}@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;
}
}@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();
}
}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
原文地址:http://blog.csdn.net/u012750578/article/details/38023341