Hibernate基于注解的双向one-to-many映射关系的实现

来源:互联网 发布:劳丽诗淘宝店叫什么 编辑:程序博客网 时间:2024/05/21 15:41

2、Hibernate基于注解的双向one-to-many映射关系的实现

项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现,但是公司的大部分都是基于注解的,因此自己参考之前的代码捣鼓了基于注解的一对多的映射关系实现。

背景:
一的一端:QingAoCenterInfo:青奥场所信息,
多的一端:QingAoPlaceInfo:青奥场馆信息,
其中一个青奥场所下可以包含多个青奥场馆

one端:QingAoCenterInfo,持有QingAoPlaceInfo的List引用,
通过注解@OneToMany(mappedBy=”qingAoCenterInfo”,cascade= CascadeType.ALL)

mappedBy:定义类之间的双向关系。如果类之间是单向关系,不需要提供定义,如果类和类之间形成双向关系,我们就需要使用这个属性进行定义, 否则可能引起数据一致性的问题。要由One的一方指向Many的一方,并且,这个属性应该等于Many的一方中含有One类的属性的属性名,否则会出错啦
cascade:CascadeType[]类型。该属性定义类和类之间的级联关系。
定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。
举个例子:Order 和OrderItem有级联关系,那么删除QingAoCenterInfo时将同时删除它所对应的QingAoPlaceInfo对象。而如果QingAoPlaceInfo还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。
cascade的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。还有一个选择是使用CascadeType.ALL,表示选择全部四项。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
package com.yuqiaotech.nttelcom.model;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
* 青奥重点场所信息表。
*
*/
@Entity(name=”QING_AO_CENTER_INFO”)
@Table(name=”QING_AO_CENTER_INFO”)
public class QingAoCenterInfo {
private Long id;
private String centerName; //重点场所名称
private Long alarmNum; //告警数
private String note; //备注
private String iconName; //图标名称
private String cityName; //所在城市
private String type; //重点场所、活动保障
private Date createTime;
private List qingAoPlaceInfo; //场所拥有的场馆
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
* @searchItem
* displayType=”text”
*
* 重点场所名称
* @return
*/
public String getCenterName() {
return centerName;
}
public void setCenterName(String centerName) {
this.centerName = centerName;
}
/**
* 告警数
* @return
*/
public Long getAlarmNum() {
return alarmNum;
}
public void setAlarmNum(Long alarmNum) {
this.alarmNum = alarmNum;
}
/**
* 备注
* @return
*/
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
/**
* 图标名称
* @return
*/
public String getIconName() {
return iconName;
}
public void setIconName(String iconName) {
this.iconName = iconName;
}

public String getCityName() {      return cityName;  }  public void setCityName(String cityName) {      this.cityName = cityName;  }  public String getType() {      return type;  }  public void setType(String type) {      this.type = type;  }  public Date getCreateTime() {      return createTime;  }  public void setCreateTime(Date createTime) {      this.createTime = createTime;  }  @OneToMany(mappedBy="qingAoCenterInfo",cascade= CascadeType.ALL)  public List<QingAoPlaceInfo> getQingAoPlaceInfo() {      return qingAoPlaceInfo;  }  public void setQingAoPlaceInfo(List<QingAoPlaceInfo> qingAoPlaceInfo) {      this.qingAoPlaceInfo = qingAoPlaceInfo;  }  

}

many端:QingAoPlaceInfo,持有QingAoCenterInfo的引用
通过@ManyToOne(fetch=FetchType.LAZY ) @JoinColumn(name=”f_center_id”)设置关联关系
@ManyToOne指明QingAoPlaceInfo和QingAoCenterInfo之间为多对一关系,多个QingAoPlaceInfo实例关联的都是同一个QingAoCenterInfo对象
fetch和lazy是用来定义级联查询的方式:
fetch:官方文档里对fetch有如下描述,Hibernate3 定义了如下几种抓取策略:
连接抓取(Join fetching):hibernate 通过在 SELECT 语句使用 OUTER JOIN(外连接)来获得对象的关联实例或者关联集合。
查询抓取(Select fetching):另外发送一条 SELECT 语句抓取当前对象的关联实体或集合。除非你显式的指定 lazy=”false” 禁止 延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条 select 语句。
子查询抓取(Subselect fetching):另外发送一条 SELECT 语句抓取在前面查询到(或者抓取到)的所有实体对象的关联集合。除非你显式的指定 lazy=”false” 禁止延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条 select 语句。
批量抓取(Batch fetching):对查询抓取的优化方案,通过指定一个主键或外键列表,Hibernate 使用单条 SELECT 语句获取一批对象实例或集合。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
package com.yuqiaotech.nttelcom.model;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
* 场馆信息。
*
*/
@Entity(name=”QING_AO_PLACE_INFO”)
@Table(name=”QING_AO_PLACE_INFO”)
public class QingAoPlaceInfo {
private Long id;
private QingAoCenterInfo qingAoCenterInfo;// 重点场所id
private String placeName;// 场馆名称
private String note;// 备注
private String openStat;// 开通状态
private Long displayOrder;
private String cityName;
private Date createTime;
private List qingAoPlaceCdmaSector;//拥有的cdma
private List qingAoPlaceLteSector;//拥有的Lte
private List qingAoAp; //拥有的Ap

@Id  @GeneratedValue(strategy = GenerationType.AUTO)  public Long getId() {      return id;  }  public void setId(Long id) {      this.id = id;  }  @ManyToOne(fetch=FetchType.LAZY )  @JoinColumn(name="f_center_id")  public QingAoCenterInfo getQingAoCenterInfo() {      return qingAoCenterInfo;  }  public void setQingAoCenterInfo(QingAoCenterInfo qingAoCenterInfo) {      this.qingAoCenterInfo = qingAoCenterInfo;  }  /**  * @searchItem  * displayType="text"  * 场所名称  * @return  */  public String getPlaceName() {      return placeName;  }  public void setPlaceName(String placeName) {      this.placeName = placeName;  }  public String getNote() {      return note;  }  public void setNote(String note) {      this.note = note;  }  public String getOpenStat() {      return openStat;  }  public void setOpenStat(String openStat) {      this.openStat = openStat;  }  public Long getDisplayOrder() {      return displayOrder;  }  public void setDisplayOrder(Long displayOrder) {      this.displayOrder = displayOrder;  }  public String getCityName() {      return cityName;  }  public void setCityName(String cityName) {      this.cityName = cityName;  }  public Date getCreateTime() {      return createTime;  }  public void setCreateTime(Date createTime) {      this.createTime = createTime;  }  @OneToMany(mappedBy="qingAoPlaceInfo",cascade= CascadeType.ALL)  public List<QingAoPlaceCdmaSector> getQingAoPlaceCdmaSector() {      return qingAoPlaceCdmaSector;  }  public void setQingAoPlaceCdmaSector(          List<QingAoPlaceCdmaSector> qingAoPlaceCdmaSector) {      this.qingAoPlaceCdmaSector = qingAoPlaceCdmaSector;  }  @OneToMany(mappedBy="qingAoPlaceInfo",cascade= CascadeType.ALL)  public List<QingAoPlaceLteSector> getQingAoPlaceLteSector() {      return qingAoPlaceLteSector;  }  public void setQingAoPlaceLteSector(          List<QingAoPlaceLteSector> qingAoPlaceLteSector) {      this.qingAoPlaceLteSector = qingAoPlaceLteSector;  }  @OneToMany(mappedBy="qingAoPlaceInfo",cascade= CascadeType.ALL)  public List<QingAoAp> getQingAoAp() {      return qingAoAp;  }  public void setQingAoAp(List<QingAoAp> qingAoAp) {      this.qingAoAp = qingAoAp;  }  

}

3、Hibernate4 注解版关系案例
一对多和多对一
公司用的maven 所以我也是建的maven工程,导入hibernate4的jar包
[html] view plaincopy在CODE上查看代码片派生到我的代码片

org.hibernate
hibernate-core
4.1.6.Final

但是oracle的驱动包,好像要自己手动加。不知道有没有用maven直接从网上加的方法。
hibernate.cfg.xml 文件
[html] view plaincopy在CODE上查看代码片派生到我的代码片
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd”>


<!-- 数据库信息 -->  <property name="dialect">      org.hibernate.dialect.Oracle10gDialect  </property>  <property name="connection.url">jdbc:oracle:thin:@192.168.15.102:1521:ora11g</property>  <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  <property name="connection.username">iris_ecnu_dev</property>  <property name="connection.password">iris_ecnu_dev</property>  <!-- 其他配置 -->  <property name="show_sql">true</property>  <property name="hbm2ddl.auto">update</property>  <property name="format_sql">true</property>  <!-- 导入映射配置  -->  <mapping class="cn.lzg.Order" />  <mapping class="cn.lzg.Person" />  


Order.java 文件
[java] view plaincopy在CODE上查看代码片派生到我的代码片
package cn.lzg;

import java.util.Date;

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

@Entity
@Table(name = “order_lzg”)
public class Order {

@Id  @SequenceGenerator(name = "order_lzg", sequenceName = "o_seq", allocationSize = 1)  @GeneratedValue(generator = "order_lzg", strategy = GenerationType.SEQUENCE)  private Long order_id;  @Column(name = "submit_time")  private Date submit_time;  @ManyToOne(fetch = FetchType.LAZY)  @JoinColumn(name = "p_id")  // order_lzg表 里面 放person_lzg ID的列  private Person person_lzg;  public Order() {  }  public Long getOrder_id() {      return order_id;  }  public void setOrder_id(Long order_id) {      this.order_id = order_id;  }  public Date getSubmit_time() {      return submit_time;  }  public void setSubmit_time(Date submit_time) {      this.submit_time = submit_time;  }  public Person getPerson_lzg() {      return person_lzg;  }  public void setPerson_lzg(Person person_lzg) {      this.person_lzg = person_lzg;  }  

}

Person.java 文件
[java] view plaincopy在CODE上查看代码片派生到我的代码片
package cn.lzg;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = “person_lzg”)
public class Person {

@Id  @SequenceGenerator(name = "person_lzg", sequenceName = "p_seq", allocationSize = 1)  @GeneratedValue(generator = "person_lzg", strategy = GenerationType.SEQUENCE)  private Long p_id;  @Column(name = "name")  private String name;  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person_lzg")  // mappedBy的值,是Order对象里面存Person对象的属性的值  private Set<Order> orderSet = new HashSet<Order>();  public Long getp_id() {      return p_id;  }  public void setp_id(Long p_id) {      this.p_id = p_id;  }  public String getName() {      return name;  }  public void setName(String name) {      this.name = name;  }  public Set<Order> getOrderSet() {      return orderSet;  }  public void setOrderSet(Set<Order> orderSet) {      this.orderSet = orderSet;  }  

}

多对多
其实它的和 一对多 差不多,但是按照网上写法出现了一个问题,使得 双向的关系变成了单向的。
Person类
[java] view plaincopy在CODE上查看代码片派生到我的代码片
package cn.lzg;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = “person_lzg”)
public class Person {

@Id  @SequenceGenerator(name = "person_lzg", sequenceName = "p_seq", allocationSize = 1)  @GeneratedValue(generator = "person_lzg", strategy = GenerationType.SEQUENCE)  private Long p_id;  @Column(name = "name")  private String name;  @ManyToMany(targetEntity = cn.lzg.Book.class, fetch = FetchType.LAZY)  @JoinTable(name = "lzgp_lzgb", joinColumns = { @JoinColumn(name = "p_id") }, inverseJoinColumns = { @JoinColumn(name = "b_id") })  // name中间表的名字,第一个自己的主键,第二个关联的主键  private List<Book> books = new ArrayList<Book>();  public Long getP_id() {      return p_id;  }  public void setP_id(Long p_id) {      this.p_id = p_id;  }  public String getName() {      return name;  }  public void setName(String name) {      this.name = name;  }  public List<Book> getBooks() {      return books;  }  public void setBooks(List<Book> books) {      this.books = books;  }  

}
Book类
[java] view plaincopy在CODE上查看代码片派生到我的代码片
package cn.lzg;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = “book_lzg”)
public class Book {
@Id
@SequenceGenerator(name = “book_lzg”, sequenceName = “b_seq”, allocationSize = 1)
@GeneratedValue(generator = “book_lzg”, strategy = GenerationType.SEQUENCE)
private Long b_id;

@Column(name = "name")  private String name;  @ManyToMany(targetEntity = cn.lzg.Person.class, fetch = FetchType.LAZY)  <span style="color:#FF0000;">// 如果在上面使用mappedBy后,就成单向的了.也就是mappedBy出现的位置所在的类,这个类是被维护端,它只能被别人级联,不能去保存别人.  // 这个问题搞了好久才发现,开始一直是单向的.</span>  @JoinTable(name = "lzgp_lzgb", joinColumns = { @JoinColumn(name = "b_id") }, inverseJoinColumns = { @JoinColumn(name = "p_id") })  private List<Person> persons = new ArrayList<Person>();  public Long getB_id() {      return b_id;  }  public void setB_id(Long b_id) {      this.b_id = b_id;  }  public String getName() {      return name;  }  public void setName(String name) {      this.name = name;  }  public List<Person> getPersons() {      return persons;  }  public void setPersons(List<Person> persons) {      this.persons = persons;  }  

}
注意
[java] view plaincopy在CODE上查看代码片派生到我的代码片
如果在上面ManyToMany注解中使用mappedBy,就成单向的了.因为mappedBy出现的位置所在的类,这个类是被维护端,它只能被别人级联,不能去保存别人

测试类

package cn.lzg;  

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test;

public class TestHibernate {
private static Configuration configuration = null;
private static SessionFactory sessionFactory = null;
private static ServiceRegistry serviceRegistry = null;
private static Session session = null;

static {      /**      * hibernate 4 貌失要这样获得sessionFactory 以前的configuration.buildSessionFactory();方法 过时了      */      configuration = new Configuration().configure();      serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())              .buildServiceRegistry();      sessionFactory = configuration.buildSessionFactory(serviceRegistry);      session = sessionFactory.openSession();  }  @Test  // 测试manytomany  public void testM2M() {      Person p1 = new Person();      p1.setName("张三");      Person p2 = new Person();      p2.setName("李四");      Person p3 = new Person();      p3.setName("王五");      List<Person> persons = new ArrayList<Person>();      persons.add(p1);      persons.add(p2);      persons.add(p3);      Book b1 = new Book();      b1.setName("书本1");      Book b2 = new Book();      b2.setName("书本2");      Book b3 = new Book();      b3.setName("书本3");      List<Book> books = new ArrayList<Book>();      books.add(b1);      books.add(b2);      books.add(b3);      p1.setBooks(books);      b3.setPersons(persons);      Transaction tx = session.beginTransaction();      session.save(p1);      session.save(p2);      session.save(p3);      session.save(b1);      session.save(b2);      session.save(b3);      tx.commit();      session.close();  }  

}

结果生成了中间表
[java] view plaincopy在CODE上查看代码片派生到我的代码片
lzgp_lzgb 里面的关系p1 有三本书, p1,p2,p3都有b3
HIbernate注解多对多关系要点总结
最近在公司做一个小项目,框架的持久层我选用的是Hibernate annotation,用户和他收藏的网站的关系是多对多的关系,一个用户可以收藏多个他喜爱的网站;反过来,一个网站也可以被多个用户收藏。
因此在设计类的时候,我设计了一个Sysuser(用户)类和一个Website(网站)类。

在配置注解的时候,由于在用户和网站之前,用户是主控方,网站是被控方。所以我在Sysuser类的getWebsite()方法上加了下面一段内容进行注解。
[java] view plaincopy在CODE上查看代码片派生到我的代码片
@ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name=”user_web”,joinColumns=@JoinColumn(name=”userid”),
inverseJoinColumns=@JoinColumn(name=”webid”))
public Set getWebsite() {
return website;
}
public void setWebsite(Set website) {
this.website = website;
}

其中@ManyToMany就不用说了,指明用户和网站之前是多对多的关系。这里需要说的是,在主控方的get那个set集合的方法上面需要再加上@JoinTable进行注解,其中name=”user_web”就是指在数据库中体现多对多关系的中间表是user_web,指定之后在首次运行项目的时候会在数据库中自动生成这个中间表,而且这个中间表不需要写个类去对应,可以通过这两个有多对多关系的类去维护第三章表的数据。joinColumns=@JoinColumn(name=”userid”)这句话的意思是是定义中间表与Sysuser这个类外键关系,中间表是通过userid这一列产生外键关联的,而inverseJoinColumns是中间表参考另一张的表的主键生成的列。
在Website类的getSysuser()方法上加了下面一段内容进行注解
[java] view plaincopy在CODE上查看代码片派生到我的代码片
@ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST},mappedBy=”website”)
public Set getSysuser() {
return sysuser;
}
public void setSysuser(Set sysuser) {
this.sysuser = sysuser;
}

其中的@ManyToMany也不用说了,指明网站与用户之间是多对多的关系。需要说明的是在被控方,需要加上mappedBy,例如这里的mappedBy=”website”是产生关系的属性。
总结一下需要注意的几点:
1、只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
2、mappedBy标签一定是定义在the owned side(被控方,或者叫被拥有方),他指向the owning side(主控方,或者叫做拥有方);
3、mappedBy跟JoinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy这方定义的JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表。
Hibernate Annotation关系映射的几种类型映射用法及使用方法
[java] view plain copy 在CODE上查看代码片派生到我的代码片
Hibernate Annotation关系映射的几种类型映射用法及使用方法(说明:以前实例的实体是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 Annotation笔记

在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。
  传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。
在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。
即利用hibernate注解后,可不用定义持久化类对应的*.hbm.xml文件,直接以注解方式写入在持久化类中来实现。
Hibernate annotation使用了ejb JPA的注解,所以,下面安装配置hibernate annotation环境时,需要导入ejb的包。许多网上的资料都是jpa hibernate annotation方面的资料。
(2)
安装 Hibernate Annotation
第一步,
环境与jar包:
  要使用 Hibernate Annotation,您至少需要具备 Hibernate 3.2和Java 5。可以从 Hibernate 站点下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项之外,您还需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。
添加hibernate3.2.jar,hibernate-annotations-3.3.0.jar,hibernate-commons-annotations.jar和ejb3-persistence.jar 。这样就可以使用hibernate的annotation了。

如果您正在使用 Maven,只需要向 POM 文件添加相应的依赖项即可,如下所示:


org.hibernate
hibernate
3.2.1.ga


org.hibernate
hibernate-annotations
3.2.0.ga


javax.persistence
persistence-api
1.0

第二步,
获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工作与使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 类来建立会话工厂:
sessionFactory = new AnnotationConfiguration().buildSessionFactory();
第三步,
尽管通常使用 元素来声明持久性类,您还是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中声明持久性类:
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>






  近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用
AnnotationSessionFactoryBean 类轻松建立一个基于注释的 Hibernate 会话工厂,如下所示:

0 0
原创粉丝点击