首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Hibernate从关联(使用注解)

2012-10-28 
Hibernate自关联(使用注解)今天下午搞了个使用注解的自连接一对多,以前用的都是配置文件,突然间用注解,一

Hibernate自关联(使用注解)

今天下午搞了个使用注解的自连接一对多,以前用的都是配置文件,突然间用注解,一下子没找到方向,所以记录下来。

主要是现实一个多级菜单。

表结构:

create table SMS_MENU(  ID     NUMBER not null, --pk  NAME   VARCHAR2(255), --菜单名  LINK   VARCHAR2(255),--菜单链接  GRADE  NUMBER,--菜单等级  PID    NUMBER,  --fk reference SMS_MENU(ID) 父菜单id  MORDER NUMBER --同一级菜单的菜单顺序)

?节约点地方,有些没用的getter setter 就不写了。

entity:

?

/** * 用户的菜单 * @author kenshin * */@Entity@Table(name = "SMS_MENU")@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)public class Menu extends IdEntity {private String name;private String link;private Integer grade; //菜单等级private Integer morder; //同一级菜单中的顺序private Menu parentMenu;//子菜单列表private List<Menu> childMenu = new ArrayList<Menu>();public Menu() {super();}@Column(nullable = false, unique = true)public String getName() {return name;}@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "pid")public Menu getParentMenu() {return parentMenu;}@OneToMany(targetEntity = Menu.class, cascade = { CascadeType.ALL }, mappedBy = "parentMenu")@Fetch(FetchMode.SUBSELECT)@OrderBy("morder")public List<Menu> getChildMenu() {return childMenu;}}

?其实不同表的一对多,和自连接的一对多是一样的,只不过突然变成一张表,多方和一方都在一起,我的笨脑子突然没反应过来,所以折腾了多好久。

一个父菜单对应多个子菜单

先把Menu作为”一”的一方看(当做父菜单)

其实它应该有的属性是childMenu这个集合

所以在getChildMenu()方法上有如下如下注解

@OneToMany(targetEntity = Menu.class, cascade = { CascadeType.ALL }, mappedBy = "parentMenu")@Fetch(FetchMode.SUBSELECT)@OrderBy("morder")

OneToMany自然表示一对多

Menu dsd = entityDao.get(333L);Menu m3 = new Menu("A管理", "**", 1, 3);Menu m4 = new Menu("B管理", "**", 1, 4);dsd.addChild(m3);dsd.addChild(m4);entityDao.save(dsd);flush();?

如果你调试以上方法,你会发现每一条insert语句后,都会再多一句update语句,虽然在insert语句中已经把pid记录到数据库,但是由于一的一方要维护外键,所以又多了2条update的sql

Hibernate:     insert     into        sms_menu        (grade, link, morder, name, pid, id)     values        (?, ?, ?, ?, ?, ?)Hibernate:     insert     into        sms_menu        (grade, link, morder, name, pid, id)     values        (?, ?, ?, ?, ?, ?)Hibernate:     update        sms_menu     set        pid=?     where        id=?Hibernate:     update        sms_menu     set        pid=?     where        id=?

?这个非常影响性能

所以必须加上mappedBy="parentMenu"

这句话表示由多的一方自己来维护外键

在多的一方,也就是子菜单对应的Menu,中应该会有一个属性parentMenu指定他的父菜单对象,同时对应的表中的外键列,即PID

这样设置后,调试的结果就只剩下2句insert的sql

Hibernate:     insert     into        sms_menu        (grade, link, morder, name, pid, id)     values        (?, ?, ?, ?, ?, ?)Hibernate:     insert     into        sms_menu        (grade, link, morder, name, pid, id)     values        (?, ?, ?, ?, ?, ?)

?现在自关联就是把父菜单对应的Menu,和子菜单对应的Menu合并成一个对象,

好了自关联的Hibernate注解设置完成了。

?

1 楼 wpfwupengfeiwpf 2010-09-17   你好,我想请问一下,如果父类为NULL时,存储在数据库中的pid字段也为null,怎样把存储的值变为0而不是null呢?

热点排行