才高行厚的hibernate(2)---hibernate的映射

集合映射

1.使用xml

集合类:
一下类全部省略getter和setter方法
package hibernate.senssic.mapping;


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


public class CollectionMapping {
	private String cid;
	private String desc;
	private Set<Student> studs;
	private List<Teacher> lteach;
	private Map<String, String> mtuds;
	private Set<Student> bagstuds;
	private List<Teacher> idbagltuds;
	private String[] strs;

}
辅助类student:
package hibernate.senssic.mapping;


import java.util.Date;


public class Student {
	private String id;
	private Date name;

}

辅助类teacher类:
package hibernate.senssic.mapping;


public class Teacher {
	private String id;
	private String name;
	private int inx;

}
xml映射:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="hibernate.senssic.mapping">
    <!-- 上面已经配置package,下面的class只需要写类名即可 -->
      <class name="CollectionMapping">
         <id name="cid">
           <!--有这么几种设置:
increment用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。
identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。
sequence
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
hilo
使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
seqhilo
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
uuid
用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
native
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
assigned
让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。
select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
foreign
使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。 -->
           <generator class="uuid"></generator>
         </id>
         <property name="desc" column="des" length="200" ></property>
         <!-- 数组的映射 -->
         <array name="strs" table="aray" >
         <key column="aryid"></key>
            <index column="strinx"></index>
            <element column="str" type="string"></element>
         </array>
         <!-- set映射不可重复,不记录顺序 -->
         <set name="studs" table="sstudent"  >
           <key column="cid" not-null="true"></key>
           <element column="name" type="java.util.Date"></element>
         </set>
         <!-- List映射可重复,但需记录顺序,需要有记录索引 -->
         <list name="lteach" table="teacher">
           <key column="cid"  not-null="true"></key>
           <index column="inx" type="int"></index>
           <element column="name" type="string"></element>
         </list>
         <!-- map映射需要对应的key和value映射 -->
         <map name="mtuds" table="mstudent" >
           <key column="cid" not-null="true"></key>
          <map-key type="string" column="mkey"></map-key>
          <element type="string" column="value"></element>
         </map>
         <!-- bag映射可重复,且不记录顺序。 -->
         <bag name="bagstuds">
           <key column="cid"  not-null="true"></key>
            <element column="name" type="java.util.Date"></element>
         </bag>
         <!-- idbag映射集合映射的一种扩展。可以在定义Bag映射时,为每一个添加的对象指定“id”,让Hibernate可以直接确定要更新的数据。 -->
         <idbag name="idbagltuds">
          <collection-id type="int" column="inx">
             <generator class="uuid"></generator>
           </collection-id>
            <key column="cid" ></key>
            <element column="name" type="java.util.Date"></element>
         </idbag>
         
      </class>
    </hibernate-mapping>

2.使用注解

在hibernate配置文件中加入:
<mapping class="hibernate.senssic.mapping.CollectionMapping"/> 
       <mapping class="hibernate.senssic.mapping.Student"/> 
       <mapping  class="hibernate.senssic.mapping.Teacher"/>
主类Collectionmapping类:
package hibernate.senssic.mapping;

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

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.IndexColumn;

@Entity
@Table(name = "collectionmap")
public class CollectionMapping {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;

	@Column(length = 200)
	private String des;
	@OneToMany(mappedBy = "cid")
	private Set<Student> studs;
	@OneToMany(mappedBy = "cid")
	@IndexColumn(name = "id")
	private List<Teacher> teacher;
	@OneToMany(mappedBy = "cid")
	@MapKey
	private Map<Integer, Student> mapts;
	@OneToMany(mappedBy = "cid")
	@IndexColumn(name = "id")
	private Student[] stuts;

	
}
辅类student类:
package hibernate.senssic.mapping;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Student {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	@Column(name = "sdate")
	private Date name;
	@ManyToOne
	@JoinColumn(name = "cid", nullable = false, referencedColumnName = "id")
	private CollectionMapping cid;

	
}

辅类Teacher类:
package hibernate.senssic.mapping;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Teacher {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	@Column
	private String name;
	@Column
	private int inx;
	@ManyToOne
	@JoinColumn(name = "conid", referencedColumnName = "id", nullable = false)
	private CollectionMapping cid;

}

组件映射

特点:一个表映射多个类

1.使用xml配置

主类User类:
package hibernate.senssic.component;

public class User {
	private int id;
	private String name;
	private String pasd;
	private Pro pro;

}
辅类Pro类:
package hibernate.senssic.component;

public class Pro {
	private String address;
	private int phon;

	
}
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="hibernate.senssic.component">
    <class name="User">
       <id name="id">
         <generator class="uuid"></generator>
       </id>
       <property name="name" ></property>
       <property name="pasd"></property>
       <component name="pro" class="Pro">
           <property name="address"></property>
           <property name="phon"></property>
       </component>
    </class>
    </hibernate-mapping>
若想实现双向关联,即从profile对象也可找到user对象,只需
在以上的基础上,改动两个地方:A.在profile类中增加user对象属性。B.在映射文件的<component></component>中增加一行
 <parent name="user"/>

2.使用注解

user类:
package hibernate.senssic.component;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	@Column
	private String name;
	@Column
	private String pasd;
	@Embedded
	private Pro pro;

	
}

Pro类:
package hibernate.senssic.component;

import javax.persistence.Column;
import javax.persistence.Embeddable;

import org.hibernate.annotations.Parent;

@Embeddable
public class Pro {
	@Parent
	private User user;
	@Column
	private String address;
	@Column
	private int phon;

	
}
组件集合映射
其实和集合映射类似,只是在将集合作为属性时,集合里的元素不是表中的一个字段(基本类型),而是由组件(复合类型:类)映射表示。
配置时,在<set></set>中添加:

 <set name="user" table="sstudent"  >
           <composite-element class="Pro">
             <property name="adderss"></property>
             <property name="phon"></property>
           </composite-element>
         </set>
如果也想实现双向关联除了在Pro中加入user还需要配置

<composite-element class="Pro">
              <parent name="user"/>
             <property name="adderss"></property>
             <property name="phon"></property>
           </composite-element>

关联映射

单向关联

一对一外键单向关联

类:
Person类
package hibernate.senssic.relevance;

public class Person {
	private int id;
	private String name;
	private Pro pro;

	
}
Pro类
package hibernate.senssic.relevance;

public class Pro {
	private int aid;
	private String address;
	private String phon;

	
}

配置文件:
person.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
          <generator class="uuid"></generator>
        </id>
        <property name="name"></property>
       <many-to-one name="pro" foreign-key="address"></many-to-one><!--一对一外键单向关联-->
      </class>
    </hibernate-mapping>
pro.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.senssic.relevance.Pro">
      <id name="aid">
       <generator class="uuid"></generator>
      </id>
      <property name="address"></property>
      <property name="phon"></property>
    </class>
    </hibernate-mapping>

一对一主键单向关联

需要改动的地方只有:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
            <!--一对一主键关联-->
          <generator class="foreign">
            <param name="property">pro</param>
          </generator>
        </id>
        <property name="name"></property>
       <one-to-one name="pro" constrained="true"></one-to-one>
      </class>
    </hibernate-mapping>

一对一非主键关联

两个类:
public class Person {
	private int id;
	private String name;
	private Pro pro;
}
public class Pro {
	private int aid;
	private String address;
	private String phon;
}

其中pro要关联的是Pro中的phon!,即两个非主属性关联
配置文件:
Person.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  <hibernate-mapping>
  
    <class name="hibernate.bean.Person">
       <id name="id">
         <generator class="increment"></generator>
       </id>
       <property name="name" ></property>
       <!-- 一对一非主键关联Pro中的phon -->
       <one-to-one name="pro" property-ref="phon" ></one-to-one>
    </class>
  </hibernate-mapping>
           
   

Pro.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.bean.Pro">
    <id name="aid">
      <generator class="increment"></generator>
    </id>
    <property name="address"  ></property>
    <property name="phon" not-null="true"></property>
    </class>
    </hibernate-mapping>

一对多非主键关联

两个实体类:
public class Person {
	private int id;
	private String name;
	private Set<Pro> pro;
}

public class Pro {
	private int aid;
	private String address;
	private String phon;
}

一对多关联Person中的name非主字段
映射文件
Person.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  <hibernate-mapping>
  
    <class name="hibernate.bean.Person">
       <id name="id">
         <generator class="increment"></generator>
       </id>
       <property name="name" ></property>
       <!-- 一对多非主键关联Person中的name -->
  <set name="pro" table="pro">
     <key column="proid" property-ref="name"></key>
     <one-to-many  class="hibernate.bean.Pro"/>
  </set>
    </class>
  </hibernate-mapping>
           
   
Pro.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.bean.Pro">
    <id name="aid">
      <generator class="increment"></generator>
    </id>
    <property name="address"  ></property>
    <property name="phon" not-null="true"></property>
    </class>
    </hibernate-mapping>

一对多外键单向关联

两个类:
package hibernate.senssic.relevance;

import java.util.Set;

public class Person {
	private int id;
	private String name;
	private Set<Pro> spro;

	
}

package hibernate.senssic.relevance;

public class Pro {
	private int aid;
	private String address;
	private String phon;

}

两个配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
          <generator class="uuid">
           
          </generator>
        </id>
        <property name="name"></property>
        <set name="pro" table="pro">
          <key column="proid"></key>
          <one-to-many class="hibernate.senssic.relevance.Pro"/>
        </set>
      </class>
    </hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.senssic.relevance.Pro">
      <id name="aid">
       <generator class="uuid"></generator>
      </id>
      <property name="address"></property>
      <property name="phon"></property>
    </class>
    </hibernate-mapping>

多对一外键单向关联

两个类省略setter和getter方法:
package hibernate.senssic.relevance;

import java.util.Set;

public class Person {
	private int id;
	private String name;
	private Pro pro;
}

package hibernate.senssic.relevance;

public class Pro {
	private int aid;
	private String address;
	private String phon;
}
只需要更改的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
          <generator class="uuid">
           
          </generator>
        </id>
        <property name="name"></property>
        <!-- 用来映射关联address在Pro表中的外键列名-->
    <many-to-one name="pro" column="address"></many-to-one>
      </class>
    </hibernate-mapping>

双向关联

一对一外键双向关联

两个类无getter和setter:
package hibernate.senssic.relevance;

public class Pro {
	private int aid;
	private Person person;
	private String address;
}
package hibernate.senssic.relevance;


public class Person {
	private int id;
	private String name;
	private Pro pro;
}
两个配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
          <generator class="uuid">
           
          </generator>
        </id>
        <property name="name"></property>
       <one-to-one name="pro" property-ref="person"></one-to-one>
    
      </class>
    </hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.senssic.relevance.Pro">
      <id name="aid">
       <generator class="uuid"></generator>
      </id>
      <property name="address"></property>
       <many-to-one name="person" column="personid"></many-to-one>
    </class>
    </hibernate-mapping>

一对一主键双向关联

值需要改:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.senssic.relevance.Pro">
      <id name="aid">
       <generator class="foreign">
         <param name="property">person</param>
       </generator>
      </id>
      <property name="address"></property>
     <one-to-one name="person" constrained="true"></one-to-one>
    </class>
    </hibernate-mapping>

一对多外键双向关联

类:
package hibernate.senssic.relevance;

import java.util.Set;

public class Person {
	private int id;
	private String name;
	private Set<Pro> pro;
}
package hibernate.senssic.relevance;

public class Pro {
	private int aid;
	private Person person;
	private String address;
}

配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
          <generator class="uuid">
           
          </generator>
        </id>
        <property name="name"></property>
       <set name="pro" inverse="true">
         <key column="addid"></key>
          <one-to-many class="hibernate.senssic.relevance.Pro"/>
       </set>
    
      </class>
    </hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.senssic.relevance.Pro">
      <id name="aid">
       <generator class="foreign">
         <param name="property">person</param>
       </generator>
      </id>
      <property name="address"></property>
     <many-to-one  name="person"></many-to-one>
    </class>
    </hibernate-mapping>

多对多双向关联

两个类:
package hibernate.senssic.relevance;

import java.util.Set;

public class Pro {
	private int aid;
	private Set<Person> person;
	private String address;
}

package hibernate.senssic.relevance;

import java.util.Set;

public class Person {
	private int id;
	private String name;
	private Set<Pro> pro;
}

配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="hibernate.senssic.relevance.Pro">
      <id name="aid">
       <generator class="foreign">
         <param name="property">person</param>
       </generator>
      </id>
      <property name="address"></property>
       <set name="pro">
         <key column="proid"></key>
         <many-to-many column="person" class="hibernate.senssic.relevance.Person"></many-to-many>
       </set>
    </class>
    </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="hibernate.senssic.relevance.Person">
        <id name="id">
          <generator class="uuid">
           
          </generator>
        </id>
        <property name="name"></property>
       <set name="pro" inverse="true">
         <key column="personid"></key>
        <many-to-many column="addreid" class="hibernate.senssic.relevance.Pro"></many-to-many>
       </set>
    
      </class>
    </hibernate-mapping>

使用注解实现关系映射:

实例的实体是user和role,主键分别是userid和roleid
 1)一对一外键关联映射(单向)
 @OneToOne(cascade=CascadeType.ALL)  //一对一外键关联,使用@OneToOne,并设置了级联操作
 @JoinColumn(name="userid",unique=true)   //@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id。外键的值是唯一的(unique),不可重复,与另一类的主键一直
 
 2)一对一外键关联映射(双向)
 @OneToOne(mappedBy=" role",cascade=CascadeType.ALL)  //一对一双向关联关系,使用@OneToOne。注意:需要加上mappedBy="role",如果不加上的话, role 也会生成一个外键(user_id),mappedby="role"需要指向与他关联对象的一个属性,说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的,主体端负责维护联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明,mappedBy的值指向主体的关联属性
 //规律:只有是双向关联关系,都加上mappedby,cascade=CascadeType.ALL级联


  3)一对一主键关联映射(不重要)
 在实际中很少用,使用注解@PrimaryKeyJoinColumn,意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。因为在实际开发中一对一很少用,主键关联就更少了


 4)多对一关联映射
 多端配置
 @ManyToOne(targetEntity=role.class)  //多对一注解@ManyToOne;targetEntity指定了关联对象
 @JoinColumn(name="userid")  //@JoinColumn(name="userid")指定生产的外键的字段名,默认是org_id


 5)一对多关联映射(单向)
 @OneToMany   //一对多注解@OneToMany(单向),如果只写@OneToMany的话,hibernate会建一张中间表来维护他们之间的关系
 @JoinColumn(name="roleid")    //加上@JoinColumn(name="roleid"),则不会建中间表,他会在多的一端加上外键roleid,来维护他们之间的关系


 6)一对多关联映射(双向)
 一端配置
 @OneToMany(mappedBy="role")  //一对多双向,在一的一端中设置mappedBy,说明多的一端为主导
 @JoinColumn(name="roleid")  //如果指定了外键字段名称,则多的一端也需要指定相同的字段名称
 多端配置
 @ManyToOne  //一对多双向
 @JoinColumn(name=" roleid ") //需要指定外键与一的一端给的外键名称一致,@JoinColumn(name=" roleid "),也可以不指定,如果在多的一端不指定,则一的一端也不能指定,否则为生成两个外键


 7)多对多关联映射(单向)
 @ManyToMany  //多对多映射:注解@ManyToMany(单向),默认情况下,hibernate会自动的创建一张中间表来维护多对多关系
  默认中间表的名称 :user_role中间表,字段的名称user_id role_id,如果想更换表名和字段名称,注解如下:
 @JoinTable(name="t_u_r",joinColumns={@JoinColumn(name="u_id")},inverseJoinColumns={@JoinColumn(name="r_id")})
 
 8)多对多关联映射(双向)
 user端
 @ManyToMany  //多对多映射:注解@ManyToMany(单向);默认情况下,hibernate会自动的创建一张中间表,来维护多对多关系;默认中间表的名称 :user_role中间表,字段的名称user_id role_id
 如果想更换表名和字段名称,注解如下:
 @JoinTable(name="t_u_r",joinColumns={@JoinColumn(name="u_id")},inverseJoinColumns={@JoinColumn(name="r_id")})  //@JoinTable(name="t_u_r"),指定中间表的表名;joinColumns={@JoinColumn(name="u_id")},指定当前对象的外键;inverseJoinColumns={@JoinColumn(name="r_id")},指定关联对象的外键
 role端
 @ManyToMany(mappedBy="role")   //多对多,双向关联映射

继承映射

关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据中,

Hibernate为我们提供了3中方案:

假设有这么三个类:

public class People
{
    /*父类所拥有的属性*/
    private String id;
    private String name;
    private String sex;
    private String age;
    private Timestamp birthday;
    
    /*get和set方法*/
}



public class Student extends People
{
    /*学生独有的属性*/
    private String cardId;//学号

    public String getCardId()
    {
        return cardId;
    }

    public void setCardId(String cardId)
    {
        this.cardId = cardId;
    }
}

public class Teacher extends People
{
    /*Teacher所独有的属性*/
    private int salary;//工资

    public int getSalary()
    {
        return salary;
    }

    public void setSalary(int salary)
    {
        this.salary = salary;
    }
}

第一种方案:一个子类对应一张表。

<?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>
    <class name="hibernate.senssic.People" abstract="true">
        <id name="id" type="string">
            <column name="id"></column>
            <generator class="uuid"></generator>
        </id>

        <property name="name" column="name" type="string"></property>
        <property name="sex" column="sex" type="string"></property>
        <property name="age" column="age" type="string"></property>
        <property name="birthday" column="birthday" type="timestamp"></property>

        <!-- 
        <union-subclass name="hibernate.senssic.Student" table="student"> 
            <property name="cardId" column="cardId" type="string"></property> 
        </union-subclass> 
        <union-subclass name="hibernate.senssic.Teacher" table="teacher"> 
            <property name="salary" column="salary" type="integer"></property> 
        </union-subclass> 
        -->
    </class>
    <union-subclass name="hibernate.senssic.Student"
        table="student" extends="hibernate.senssic.People">
        <property name="cardId" column="cardId" type="string"></property>
    </union-subclass>

    <union-subclass name="hibernate.senssic.Teacher"
        table="teacher" extends="hibernate.senssic.People">
        <property name="salary" column="salary" type="integer"></property>
    </union-subclass>
</hibernate-mapping>


第二种方案:使用一张表表示所有继承体系下的类的属性的并集。

<?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>
    <class name="hibernate.senssic.People" table="people">
        <id name="id" type="string">
            <column name="id"></column>
            <generator class="uuid"></generator>
        </id>

        <discriminator column="peopleType" type="string"></discriminator>

        <property name="name" column="name" type="string"></property>
        <property name="sex" column="sex" type="string"></property>
        <property name="age" column="age" type="string"></property>
        <property name="birthday" column="birthday" type="timestamp"></property>

        <subclass name="hibernate.senssic.Student" discriminator-value="student">
            <property name="cardId" column="cardId" type="string"></property>
        </subclass>
        
        <subclass name="hibernate.senssic.Teacher" discriminator-value="teacher">
            <property name="salary" column="salary" type="string"></property>
        </subclass>
    </class>
</hibernate-mapping>


第三种方案:每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来。

<?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>
    <class name="hibernate.senssic.People" table="people">
        <id name="id" type="string">
            <column name="id"></column>
            <generator class="uuid"></generator>
        </id>

        <property name="name" column="name" type="string"></property>
        <property name="sex" column="sex" type="string"></property>
        <property name="age" column="age" type="string"></property>
        <property name="birthday" column="birthday" type="timestamp"></property>
        
        <joined-subclass name="hibernate.senssic.Student" table="student">
            <key column="id"></key>
            <property name="cardId" column="cardId" type="string"></property>
        </joined-subclass>
        
        <joined-subclass name="hibernate.senssic.Teacher" table="teacher">
            <key column="id"></key>
            <property name="salary" column="salary" type="integer"></property>
        </joined-subclass>
    </class>
</hibernate-mapping>

使用注解来实现继承映射:

http://blog.csdn.net/senssic/article/details/13421201

hibernate的联合主键

如果使用联合主键,而不是实体对应的id自动生成,则需要抽象出联合主键为一个类,并需要实现序列化接口,和覆盖equals方法,最好覆盖hashCode方法(用于比较对象)。
1.使用xml
抽象主键类:
package hibernate.senssic.compositeid;

import java.io.Serializable;

public class ComposiTidPK implements Serializable {
	// 联合主键,使用name和email作为主键,需要实现序列化接口,和覆写hashCode和equals方法
	private String name;
	private String email;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ComposiTidPK other = (ComposiTidPK) obj;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

}

实体类:
package hibernate.senssic.compositeid;

import java.util.Date;

public class ComposiTid {
	private String adder;
	private Date date;
	private ComposiTidPK cPk;

	public String getAdder() {
		return adder;
	}

	public void setAdder(String adder) {
		this.adder = adder;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public ComposiTidPK getcPk() {
		return cPk;
	}

	public void setcPk(ComposiTidPK cPk) {
		this.cPk = cPk;
	}
}

xml映射文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
   <hibernate-mapping package="hibernate.senssic.compositeid">
     <class name="ComposiTid">
         <composite-id name="cPk">
              <key-property name="name"></key-property>
              <key-property name="email"></key-property>
          </composite-id>
          <property name="adder"></property>
          <property name="date"></property>
      </class>
   </hibernate-mapping>
2.使用注解
抽象联合主键类注解:
package hibernate.senssic.compositeid;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class ComposiTidPK implements Serializable {
	// 联合主键,使用name和email作为主键,需要实现序列化接口,和覆写hashCode和equals方法
	@Column
	private String name;
	@Column
	private String email;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ComposiTidPK other = (ComposiTidPK) obj;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

}

实体类:
package hibernate.senssic.compositeid;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class ComposiTid {
	@Column
	private String adder;
	@Column
	private Date date;
	@Id
	private ComposiTidPK cPk;

	public String getAdder() {
		return adder;
	}

	public void setAdder(String adder) {
		this.adder = adder;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public ComposiTidPK getcPk() {
		return cPk;
	}

	public void setcPk(ComposiTidPK cPk) {
		this.cPk = cPk;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值