zoukankan      html  css  js  c++  java
  • Hibernate一对一关联

    一对一单向外键关联

    1.建Husband实体类和Wife实体类,添加Annotation注解,如下

    @Entity
    public class Husband {
    	private int id;
    	private String name;
    
    	private Wife wife;        
    	@Id
    	@GeneratedValue
    	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                   //Husband和Wife是一对一的关系
    	public Wife getWife() {
    		return wife;
    	}
    	public void setWife(Wife wife) {
    		this.wife = wife;
    	}
    }
    @Entity
    public class Wife {
    	private int id;
    	private String name;
    	@Id
    	@GeneratedValue
    	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;
    	}
    }

    2.在hibernate.cfg.xml中添加mapping语句

    <mapping class="com.hibernate.model.Husband"/> 
    <mapping class="com.hibernate.model.Wife"/>

    3.建Junit测试类

    public class ORMappingTest {
    
    	@Test
    	public void test() {
    		//生成表,输出建表语句
    		new SchemaExport(new Configuration().configure()).create(true, true);
    	}
    }

    程序至此结束,运行程序,在数据库中生成Husband表和Wife表,并在控制台输出建表语句。

    Husband表中会自动生成属性名为“wife_id”的外键,参考表为Wife表。

    如果想要使用自定义的外键属性名,可对Husband实体类的getWife方法添加Annotation注解,如下:

    @OneToOne   //Husband和Wife是一对一的关系
    @JoinColumn(name="wifeId")  // java默认生成的外键属性名为wife_id.设置此项后,可以任意设定其属性名,此处设置为wifeId.
    public Wife getWife() {
    	return wife;
    	}

    一对一双向外键关联

    1.建Husband实体类和Wife实体类,添加Annotation注解

    Husband类同上,只需在Wife类中增加一个Husband类型的变量,并添加@OneToOne注解即可,如下

    @Entity
    public class Wife {
    	private int id;
    	private String name;
    	
    	private Husband husband;   //建一个Husband类型的变量,并生成setter和getter方法 
    	
    	@Id
    	@GeneratedValue
    	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="wife")     //"wife"指的是Husband类中的private Wife wife;
    	public Husband getHusband() {
    		return husband;
    	}
    	public void setHusband(Husband husband) {
    		this.husband = husband;
    	}	
    }

    凡是双向关联,必设mappedBy

    2.在hibernate.cfg.xml中添加mapping语句----同上

    3.建Junit测试类----同上

    程序至此结束,运行程序,在数据库中生成Husband表和Wife表,并在控制台输出建表语句。

    联合主键

    联合主键(3种方式)
    
        将主键类注解为@Embeddable,并将主键(pk)的属性注解为@Id (不常用)
    
        将主键的属性注解为@EmbeddedId  
    
        将实体类注解为@IdClass(组件类.class),并将该实体类中所有属于主键的属性都注解为@Id

    示例:建Wife表,属性有id,name,age。其中id和name为联合主键

    1.建主键类WifePK

    /*
     * 建立主键类WifePK
     * 需实现Serializable接口,此接口用于把当前类的接口进行序列化
     * 需重写equals()和hashCode()方法,以保证对象的唯一性
     *  
     **/
    
    public class WifePK implements java.io.Serializable{
    	private int id;
    	private String name;
    	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;
    	}
    	
    	@Override
    	public boolean equals(Object o){
    		if(o instanceof WifePK){
    			WifePK pk = (WifePK) o;
    			if(this.id == pk.getId() && this.name.equals(pk.getName())){
    				return true;
    			}
    		}
    		return false;
    	}
    	
    	@Override
    	public int hashCode(){
    		return this.name.hashCode();
    	}
    }

    2.建实体类Wife

    第二种方式注解,@EmbeddedId

    @Entity
    public class Wife {
    	
    	private WifePK pk;    //增加WifePK类型的变量,并添加getter和setter方法
    	
    	private int age;
    	
    	@EmbeddedId              //将其注解为联合主键
    	public WifePK getPk() {
    		return pk;
    	}
    	public void setPk(WifePK pk) {
    		this.pk = pk;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    }

    第三种方式注解,@IdClass

    @Entity
    @IdClass(WifePK.class)   //将实体类注解为@IdClass
    public class Wife {	
    	private int id;
    	private String name;
    	private int age;
    
    	@Id               //将该实体类中属于主键的属性注解为@Id 
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	@Id                //将该实体类中属于主键的属性注解为@Id 
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    }

    3.写Junit测试类

    第二种方式注解,@EmbeddedId

    public class WifeTest {
    private static SessionFactory sf = null;
    	
    	@BeforeClass
    	public static void beforeClass() {
    		sf = new Configuration().configure().buildSessionFactory();
    	}
    	
    	@AfterClass
    	public static void afterClass() {
    		sf.close();
    	}
    
    	@Test
    	public void test() {
    		
    		WifePK pk = new WifePK();
    		pk.setId(1);
    		pk.setName("zhangsan");
    		
    		Wife wife = new Wife();
    		wife.setPk(pk);
    		wife.setAge(32);
    		
    		Session session = sf.getCurrentSession();
    		session.beginTransaction();
    		
    		session.save(wife);
    		
    		session.getTransaction().commit();
    
    	}
    }

    第三种方式注解,@IdClass,只需修改其test()方法,如下:

    @Test
    public void test() {
    		
    	Wife wife = new Wife();
    	wife.setId(1);
    	wife.setName("zhangsan");
    	wife.setAge(32);
    		
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    		
    	session.save(wife);
    		
    	session.getTransaction().commit();
    
    }

    程序至此结束,运行程序,在数据库中生成Wife表,id和name为主键,并将对象wife存入Wife表。

    联合主键关联

    示例:

             建Husband表,属性有id和name

             建Wife表,属性有id,name,age。其中id和name为联合主键

             设置联合主键关联,在Husband表中生成属性名为wife_id和wife_name的外键,分别参考Wife表中的id和name

            

    1.建Husband实体类、Wife实体类和WifePK主键类,添加Annotation注解

    Husband类,同上

    WifePK类,同上

    Wife类,同“联合主键”部分第三种方式注解的Wife实体类

    2.在hibernate.cfg.xml中添加mapping语句----同上

    3.建Junit测试类ORMappingTest----同上

    程序至此结束,运行程序,在数据库中生成Husband表和Wife表,并在控制台输出建表语句。

    Husband表中会自动生成属性名为“wife_id”和“wife_name”的外键,参考表为Wife表。

    如果想要使用自定义的外键属性名,可对Husband实体类的getWife方法添加Annotation注解,如下:

    @OneToOne
    @JoinColumns(
    		{
    			@JoinColumn(name="wifeId",referencedColumnName="id"),
    			@JoinColumn(name="wifeName",referencedColumnName="name")
    		}
    )
    public Wife getWife() {
    	return wife;
    }

    组件映射

    除了粗粒度的对象模型设计(一个表映射成一个持久化类)之外,还可以采用细粒度的对象模型,把一个表映射成两个或者多个类。

    被细化出来的类,可以称为组件(Component)。

    组件是某个实体的逻辑组成部分,它与实体的本质区别在于组件没有id,可以把组件当做值对象。

    举例来说:Husband类有id、name、wifeName、wifeAge等属性,将wifeName、wifeAge从Husband实体类中拿出来,单独建一个Wife类,这个类就叫做值对象,也就是所说的组件。表现在数据库中,将只有husband一张表,有id、name、wifeName、wifeAge属性。

    采用组件映射的优点:实现了对象细粒度的划分,层次更加分明,复用率高。

    1.建立Husband实体类和Wife组件类,添加Annotation注解

    Husband类同上,只是不需要添加@OneToOne注解,改为@Embedded注解,如下:

    @Embedded
    public Wife getWife() {
    	return wife;
    }

    Wife类无需添加任何注解,如下:

    public class Wife {
    	
    	private String wifeName;
    	private int wifeAge;
    
    	public String getWifeName() {
    		return wifeName;
    	}
    	public void setWifeName(String wifeName) {
    		this.wifeName = wifeName;
    	}
    	public int getWifeAge() {
    		return wifeAge;
    	}
    	public void setWifeAge(int wifeAge) {
    		this.wifeAge = wifeAge;
    	}	
    }

    2.在hibernate.cfg.xml中添加mapping语句

    只需添加Husband的mapping,Wife类不是实体类,无需添加。

    3.建Junit测试类ORMappingTest----同上

    程序至此结束,运行程序,在数据库中生成Husband表,并在控制台输出建表语句。

    Husband表中有id、name、wifeName、wifeAge属性。

  • 相关阅读:
    架构资料
    Node参考资料
    运维参考资料
    前端参考资料
    Python参考资料
    推荐几个工具型网站
    学好Mac常用命令,助力iOS开发
    git submodule相关操作
    HttpURLConnection传JSON数据
    【树莓派笔记3】安装配置samba 和Windows进行文件共享
  • 原文地址:https://www.cnblogs.com/weilunhui/p/3895852.html
Copyright © 2011-2022 走看看