Hibernate级联保存与删除

来源:互联网 发布:如何考核淘宝网店客服 编辑:程序博客网 时间:2024/05/01 20:46
   Hibernate为程序员提供一种级联操作,在编写程序时,通过Hibernate的级联功能可以很方便的操作数据库的主从表的数据,我们最常用的级联是级联保存和级联删除,下面分别来看一下级联保存和级联删除。

       我准备了MenuPanelMenu两个对象,先来看一下两个对象的关系

       从上图可以看出,MenuPanelMenu是一对多的关系,Menu表同时存在多个子节点,用parentId代表该节点的父节点。

 

    在JPA中,配置级联操作我们可以用cascade=CascadeType.ALL,意思是支持所有的级联操作,网上有很多文章说级联保存用CascadeType.PERSIST,这也是可以的,我们分别在代码中使用以上两个类型。在MenuPane的getChildren()方法中标上下面的注解:

      

@OneToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY,mappedBy="menu")public List<Menu> getChildren() {return children;}


       在MenugetChildren()的方法中标上下面的注解

@OneToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY,mappedBy="menu")public List<Menu> getChildren() {return children;}


 

       以上代码实现级联保存的配置,我们需要在业务逻辑中为对象设置关系,这样Hibernate才能自动实现级联保存,如果只是配置了级联操作,而没有在对象中设置对象之前的关系,Hibernate是无法实现级联保存的功能的。

       首先实例化MenuPanel

MenuPanel panel1 = new MenuPanel("基础设置");


      再实例化几个Menu

Menu menuCard=new Menu("会员卡设置","");menuCard.setLeaf(false);Menu menu1 = new Menu("卡类型设置", "basicOperation/queryCardType");Menu menu2 = new Menu("站点设定", "basicOperation/querySite");Menu menu3 = new Menu("操作员授权", "basicOperation/queryOperatorSet");Menu menu4 = new Menu("密码修改", "test.do");Menu menu5 = new Menu("消费项目管理", "test1.do");

    我们要把menuCard作为menu1的父节点,故作如下设置

List<Menu> cardChildMenus=new ArrayList<Menu>();cardChildMenus.add(menu1);menuCard.setChildren(cardChildMenus);//把卡类型设置作为会员卡设置的子菜单


    设置对象之间的关系,这一步很关键,直接影响保存结果

menu1.setMenu(menuCard);//为会员卡设置设置卡类型设置,以支持级联保存menuCard.setMenuPanel(panel1);//设置Menu属于MenuPanelmenu2.setMenuPanel(panel1);menu3.setMenuPanel(panel1);menu4.setMenuPanel(panel1);menu5.setMenuPanel(panel1);//将Menu添加到MenuPanelpanel1.getMenus().add(menuCard);panel1.getMenus().add(menu2);panel1.getMenus().add(menu3);panel1.getMenus().add(menu4);panel1.getMenus().add(menu5);


具体代码:

@Overridepublic boolean testAdd() {List<MenuPanel> menuPanels=new ArrayList<MenuPanel>();MenuPanel panel1 = new MenuPanel("基础设置");Menu menuCard=new Menu("会员卡设置","");menuCard.setLeaf(false);Menu menu1 = new Menu("卡类型设置", "basicOperation/queryCardType");Menu menu2 = new Menu("站点设定", "basicOperation/querySite");Menu menu3 = new Menu("操作员授权", "basicOperation/queryOperatorSet");Menu menu4 = new Menu("密码修改", "test.do");Menu menu5 = new Menu("消费项目管理", "test1.do");menu1.setMenu(menuCard);//为会员卡设置设置卡类型设置,以支持级联保存menuCard.setMenuPanel(panel1);menu2.setMenuPanel(panel1);menu3.setMenuPanel(panel1);menu4.setMenuPanel(panel1);menu5.setMenuPanel(panel1);List<Menu> cardChildMenus=new ArrayList<Menu>();cardChildMenus.add(menu1);menuCard.setChildren(cardChildMenus);//把卡类型设置作为会员卡设置的子菜单panel1.getMenus().add(menuCard);panel1.getMenus().add(menu2);panel1.getMenus().add(menu3);panel1.getMenus().add(menu4);panel1.getMenus().add(menu5);MenuPanel panel2 = new MenuPanel("日常操作");Menu menu10 = new Menu("发行新卡", "operate/cardList?type=add");Menu menu11 = new Menu("存款入卡", "operate/cardList?type=depositMoney");Menu menu12 = new Menu("卡中取款", "operate/cardList?type=drawMoney");Menu menu13 = new Menu("奖品管理", "operate/cardList?type=prize");Menu menu14 = new Menu("卡挂失", "operate/cardList?type=reportLoss");Menu menu15 = new Menu("卡解挂", "operate/cardList?type=cancelLoss");Menu menu16 = new Menu("并卡", "operate/cardList?type=mergeCard");Menu menu17 = new Menu("补办新卡", "operate/cardList?type=mendCard");Menu menu18 = new Menu("回收旧卡", "operate/cardList?type=recycleCard");Menu menu19 = new Menu("维护", "operate/cardList?type=maintain");menu10.setMenuPanel(panel2);menu11.setMenuPanel(panel2);menu12.setMenuPanel(panel2);menu13.setMenuPanel(panel2);menu14.setMenuPanel(panel2);menu15.setMenuPanel(panel2);menu16.setMenuPanel(panel2);menu17.setMenuPanel(panel2);menu18.setMenuPanel(panel2);menu19.setMenuPanel(panel2);panel2.getMenus().add(menu10);panel2.getMenus().add(menu11);panel2.getMenus().add(menu12);panel2.getMenus().add(menu13);panel2.getMenus().add(menu14);panel2.getMenus().add(menu15);panel2.getMenus().add(menu16);panel2.getMenus().add(menu17);panel2.getMenus().add(menu18);panel2.getMenus().add(menu19);menuPanels=new ArrayList<MenuPanel>();menuPanels.add(panel1);menuPanels.add(panel2);return menuPanelDao.add(menuPanels);}


       执行一下单元测试,看一下效果

@Testpublic void test(){//menuPanelService.delete();menuPanelService.testAdd();}Hibernate: insert into MENUPANEL (text, id) values (?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENUPANEL (text, id) values (?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)Hibernate: insert into MENU (leaf, parentId, menuPanelId, text, url, id) values (?, ?, ?, ?, ?, ?)

       大家可以看到数据全部保存到数据库中了,有图有真像。

       图一:MenuPanel表

      

 

图二:Menu

 

 

         再来看一下级联删除,级联删除可以用CascadeType.REMOVE,先在Menu中的getMenuPanel()方法中加上如下配置,由于我们已经在MenuPanel中配置了cascade=CascadeType.ALL,所以,下面的配置是可以忽略的,之所以这么做,是为了当从Menu中删除对象时能级联删除MenuPanel

@ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE}, targetEntity=MenuPanel.class)

      在getMenu()方法中也加上如下配置

@ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE}, targetEntity=Menu.class)


     同在要把对象之间的关系解除

menus.get(j).setMenuPanel(null);


     具体的代码

@Overridepublic boolean delete() {// TODO Auto-generated method stubSession session = null;try {session =getSession();Query query = session.createQuery("from MenuPanel");List<MenuPanel> list = query.list();for (int i = 0; i < list.size(); i++) {MenuPanel mp = list.get(i);List<Menu> menus = mp.getMenus();for (int j = 0; j < menus.size(); j++) {menus.get(j).setMenuPanel(null);clareChild(menus.get(j).getChildren());}super.delete(mp);}return true;} catch (Exception e) {e.printStackTrace();return false;} finally {//session.close();}}


 

       执行结果

Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENUPANEL where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENU where id=?Hibernate: delete from MENUPANEL where id=?


 

        POJO类的详细代码如下:

package com.mcs.user.pojo;import java.util.ArrayList;import java.util.List;import javax.persistence.CascadeType;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.OneToMany;import javax.persistence.Table;import com.mcs.pojo.base.GenericObject;/** * 这个是MenuPanel对应的是accordion菜单 * @author lishengbo * */@Entity@Table(name = "MENUPANEL")public class MenuPanel extends GenericObject {private String text;private List<Menu> menus=new ArrayList<Menu>();public MenuPanel() {}public MenuPanel(String text) {this.text = text;}public MenuPanel(long id,String text) {this.text = text;super.setId(id+"");}public String getText() {return text;}public void setText(String text) {this.text = text;}/** * 一对多关联Menu菜单,作为Tree中的根节点,这里使用立即加载和MenuPanel一起加载到客户端,注意,一定要使用立即加载 * @return */@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER,mappedBy="menuPanel")public List<Menu> getMenus() {return menus;}public void setMenus(List<Menu> menus) {this.menus = menus;}}package com.mcs.user.pojo;import java.util.List;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;import javax.persistence.Table;import com.mcs.pojo.base.GenericObject;@Entity@Table(name="MENU")public class Menu extends GenericObject{private String text;private String url;private boolean leaf=true;//默认是叶子节点private MenuPanel menuPanel;private List<Menu> children;private Menu menu;public Menu() {}public Menu(String text, String url) {super();this.text = text;this.url = url;}public Menu(long id,String text, String url,MenuPanel menuPanel) {super();super.setId(id+"");this.text = text;this.url = url;this.menuPanel=menuPanel;}public String getText() {return text;}public void setText(String text) {this.text = text;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}@ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE}, targetEntity=MenuPanel.class)@JoinColumn(name="menuPanelId",referencedColumnName="id",insertable=true,updatable=true)public MenuPanel getMenuPanel() {return menuPanel;}public void setMenuPanel(MenuPanel menuPanel) {this.menuPanel = menuPanel;}@Column(length=1000)public boolean isLeaf() {return leaf;}public void setLeaf(boolean leaf) {this.leaf = leaf;}@OneToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY,mappedBy="menu")public List<Menu> getChildren() {return children;}public void setChildren(List<Menu> children) {this.children = children;}@ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE}, targetEntity=Menu.class)@JoinColumn(name="parentId",referencedColumnName="id",insertable=true,updatable=true)public Menu getMenu() {return menu;}public void setMenu(Menu menu) {this.menu = menu;}}


 

0 0