欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java鬼混笔记:Hibernate:3、一对一关系之外键单向和双向关联

程序员文章站 2022-04-22 16:10:51
...

这次的笔记是 一对一外键关联,包含单向和双向,用 人和身份证来举例,一个人一个身份证。直接上代码,代码里头有注释说明。gogogo

单向关联:(person有card,card中没有person)

Person.java

package com.ywj.TestHibernate.e;

import java.io.Serializable;

public class Person implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -3189538608590684635L;

	private Long id;
	private String name;
	private Card card;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Card getCard() {
		return card;
	}
	public void setCard(Card card) {
		this.card = card;
	}	
}


Person.hbm.xml

<?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 package="com.ywj.TestHibernate.e">
	<class name="Person" table="person" >
		<id name="id" column="id">
			<generator class="identity" /><!-- 自增长 外键关联了, 和主键id没关系 -->
		</id>
		<property name="name" column="name" type="java.lang.String"/>
		<!-- 这里用many-to-one,对多一,但是这个多对一要设置成独立的,独立了也是就意味着只有一个person对应一个card -->
		<many-to-one  name="card"  column="card" unique="true" cascade="all" fetch="join"/>
		<!-- unique="true":person表中的字段card是独立的唯一的,对应card表中的ID -->
		<!-- 
		fetch="join" 的意思是当我查询person表时,它会left join card 表去查询,同时加载card表信息,就只执行一条sql,也就是查询person或者通过person查询card要1条sql 但是lazy懒加载会失效
		fetch="select" 的意思是当我查询person表时,它只查person表,当我们从person中获取card时他会重新执行一条sql 去从card表中查一次。也就是通过person查询card要2条sql -->
	</class>
</hibernate-mapping>

Card.java

package com.ywj.TestHibernate.e;

import java.io.Serializable;

public class Card implements Serializable{

	private static final long serialVersionUID = 5451125658782668299L;

	private Long id;
	private String number;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
}


Card.hbm.xml

<?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 package="com.ywj.TestHibernate.e">
	<!--普通的创建就行-->
	<class name="Card" table="card" >
		<id name="id" column="id">
			<generator class="identity" />
		</id>
		<property name="number" column="number" type="java.lang.String"/>
	</class>
</hibernate-mapping>

Test.java

package com.ywj.TestHibernate.test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.ywj.TestHibernate.e.Card;
import com.ywj.TestHibernate.e.Person;

public class Test {

	public static void main(String[] args) {
		
		Session s = HibernateUtils.getCurrentSession();
		Transaction t  = null;
		
		try {
			
			t = s.beginTransaction();
			// 添加
			/*Card c = new Card();
			c.setNumber("xxxxxxxxxxxx");
			
			Person p = new Person();
			p.setName("name");
			p.setCard(c);
			
			s.save(p);
			s.save(c);
			
			t.commit();*/
			// 查询
			/*Person p = (Person) s.load(Person.class, 1L);
			System.out.println(p.getName());
			
			Card c = p.getCard();
			System.out.println(c.getNumber());*/
			
			//删除 连card也删除 因为person.hbm.xml配置了cascade="all",person的任何的操作都会影响表card
			/*Person p = (Person) s.load(Person.class, 2L);
			s.delete(p);
			t.commit();*/
			
		} catch (Exception e) {
			e.printStackTrace();
			t.rollback();
		} finally {
			s.close();
		}
		
	}

}


接下来是 

双向关联

Person.java

package com.ywj.TestHibernate.e;

import java.io.Serializable;

public class Person implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -3189538608590684635L;

	private Long id;
	private String name;
	private Card card;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Card getCard() {
		return card;
	}
	public void setCard(Card card) {
		this.card = card;
	}	
}

Person.hbm.xml
<?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 package="com.ywj.TestHibernate.e">
	<class name="Person" table="person" >
		<id name="id" column="id">
			<generator class="identity" /><!-- 自增长 外键关联了, 和主键id没关系 -->
		</id>
		<property name="name" column="name" type="java.lang.String"/>
		<!-- 问题来了, 这里和一对一主键关联不一样,这里用many-to-one,对多一,但是这个多对一要设置成独立的,独立了也是就意味着只有一个person对应一个card -->
		<many-to-one  name="card"  column="card" unique="true"/><!-- unique="true":person表中的字段是独立的,对应card表中的ID -->
	</class>
</hibernate-mapping>

Card.java

package com.ywj.TestHibernate.e;

import java.io.Serializable;

public class Card implements Serializable{

	private static final long serialVersionUID = 5451125658782668299L;

	private Long id;
	private String number;
	private Person person;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
}

Card.hbm.xml

<?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 package="com.ywj.TestHibernate.e">
	<class name="Card" table="card" >
		<id name="id" column="id">
			<generator class="identity" />
		</id>
		<property name="number" column="number" type="java.lang.String"/>
		<!-- 
		card这里使用one-to-one 证明和person是一对一的,核心是property-ref="card",
		意思是card怎么和person形成一对一?card是通过person(class="Person")来找到person.card属性(property-ref="card" :参照person中的card属性,这个有点像spring...)
		 -->
		<one-to-one name="person" class="Person" property-ref="card"/>
	</class>
</hibernate-mapping>

Test.java

package com.ywj.TestHibernate.test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.ywj.TestHibernate.e.Card;
import com.ywj.TestHibernate.e.Person;

public class Test {

	public static void main(String[] args) {
		
		Session s = HibernateUtils.getCurrentSession();
		Transaction t  = null;
		
		try {
			
			t = s.beginTransaction();
			// 添加
			/*Card c = new Card();
			c.setNumber("xxxxxxxxxxxx");
			
			Person p = new Person();
			p.setName("name");
			p.setCard(c);
			
			s.save(p);
			s.save(c);
			
			t.commit();*/
			// 查询
			/*Person p = (Person) s.load(Person.class, 1L);
			System.out.println(p.getName());
			Card c = p.getCard();
			System.out.println(c.getNumber());
			
			System.out.println("////////////////");
			
			Card c2 = (Card) s.load(Card.class, 3L);
			System.out.println(c2.getNumber());
			System.out.println(c2.getPerson().getName());*/


			//删除 连card也删除 因为person.hbm.xml配置了cascade="all",person的任何的操作都会影响表card
			/*Person p = (Person) s.load(Person.class, 2L);
			s.delete(p);
			t.commit();*/
			
		} catch (Exception e) {
			e.printStackTrace();
			t.rollback();
		} finally {
			s.close();
		}
		
	}

}