Hibernate OneToMany等注解详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25218095/article/details/79558253

cascade属性: 指定级联操作的行为(可多选)

CascadeType.PERSIST 级联新增(又称级联保存):
 
获取A对象里也同时也重新获取最新的B时的对象。即会重新查询数据库里的最新数据,并且,只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为 持久态),对应EntityManager的presist方法,调用JPA规范中的persist(),不适用于Hibernate的save()方法

CascadeType.MERGE 级联合并(又称级联更新) 

指A类新增或者变化,会级联B对象(新增或者变化) ,对应EntityManager的merge方法,调用JPA规范中merge()时,不适用于Hibernate的update()方法

CascadeType.REMOVE 级联删除 

只有A类删除时,会级联删除B类,即在设置的那一端进行删除时,另一端才会级联删除,对应EntityManager的remove方法,调用JPA规范中的remove()时,适用于Hibernate的delete ()方法

CascadeType.REFRESH 级联刷新 

获取order(一或多)对象里也同时也重新获取最新的items(多)的对象,对应EntityManager的refresh(object),调用JPA规范中的refresh()时,适用于Hibernate的flush()方法

CascadeType.ALL 

包含所有持久化方法

hibernate中openSession和getCurrentSession的区别
Session session = sessionFactory.openSession();永远打开一个新的session 需要session.close();
session = sessionFactory.getCurrentSession();如果上下文(在配置文件hibernate.cfg.xml里)
有session就不用创建没有就新建一个session,不用session.close(),自动close,
在没提交前都是同一个,提交后就不一样了session.beginTransaction(),开始事务session.getTransaction.comit();提交事务
Sessiion session=sessionfactory.getcurrentsession();

用这种方法得到session是不需要写session.close()的,事务提交后自动关闭.

使用SessionFactory.getCurrentSession()需要在hibernate.cfg.xml中如下配置:
   
* 如果采用jdbc独立引用程序配置如下:
             <property name="hibernate.current_session_context_class">thread</property>
      * 如果采用了JTA事务配置如下  
             <property name="hibernate.current_session_context_class">jta</property>

如果是和spring合并的话,在web.xml里添加如下代码帮你管理session的开和关
<!-- Spring提供的过滤器-打开和关闭session -->
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
  <param-name>singleSession</param-name>
  <param-value>true</param-value>
</init-param>
</filter>  
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
  <url-pattern>/*</url-pattern>

  </filter-mapping>


mappedBy: 

1>只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;


============================================================================

@OnetoOne
user表
@OneToOne
@JoinColumn(name="account")
private Account account;


account表
@OneToOne(mappedBy="account")
private User userId;

形成的表是在user表中有个@JoinColumn(name="account")名字的外键,指向account表

============================================================================

@OneToMany


user表
@OneToMany(cascade= {CascadeType.ALL},mappedBy="userId")
private List<BankCard> bankCards = new ArrayList<BankCard>();

bankcard表
@ManyToOne
@JoinColumn(name="user_Id")
private User userId;


这样形成的是在bankcard表中有个指向user表的外键

user表
@OneToMany
@Column(name = "bank_cards")
private List<BankCard> bankCards = new ArrayList<BankCard>();

这样写,会生成一个中间表,保存userId和bandcardId之间的对应关系,只写一遍,默认只有一边.


============================================================================

@ManytoMany

user表
@ManyToMany(cascade= {CascadeType.ALL})
@JoinTable(name = "union_user_room", joinColumns = { @JoinColumn(name ="user_id" )}, 
inverseJoinColumns = { @JoinColumn(name = "room_id") })
@OrderBy("userId")
private Set<ClassRoom> rooms = new LinkedHashSet<ClassRoom>();

classroom表

@ManyToMany(mappedBy="rooms",cascade= {CascadeType.ALL})
private Set<User> users = new LinkedHashSet<User>();

形成一个中间表,名字为JoinTable注解的name,第一个为user表中的id名称,第二个为classroom表中的id名称.


============================================================================

举个例子:

        人跟身份证双向关联 
    在Person里面定义的注解: 
@OneToOne(cascade = CascadeTye.ALL,optional = true)
public IDCard getIdCard(){
  return idCard;
}

@OneToOne(cascade = CascadeType.ALL,mappedBy = "idCard",optional = false)
public Person getPerson(){
  return person;
}

我们也可以看到在Person里面的IDCard是注释optional=true,也就是说一个人是可以没有身份证的,但是一个身份证是不可以没有人的,所以在IDCard里面注释Person的时候, optional=false了,这样就可以防止一个空的身份证记录进数据库。

============================================================================









































































猜你喜欢

转载自blog.csdn.net/qq_25218095/article/details/79558253
今日推荐