`
lihengzkj
  • 浏览: 45033 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

JPA初探06---多对多的双向关联

 
阅读更多
多对多的关系,在项目中一定会遇到,而我们在项目中一定会遇到的权限控制。
在权限控制中: 角色和权限的关系就是多对多的关系

下面我们来看看是怎么样进行JPA的配置的

【Java类设计】

package ManyToMany;

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.ManyToMany;
import javax.persistence.Table;

/**
 * 权限类
 * @author 青山
 * @date 2014年10月19日
 * @file name: RightBean.java
 * 
 * 	create table t_right(
		rightid int primary key auto_increment,
		rightname varchar(45)
	);
 */
@Entity
@Table(name="t_right")
public class RightBean {
	@Id
	@Column(name="rightid")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="rightname")
	private String rname;
	
	//many端默认的就是延迟加载
	@ManyToMany(cascade={CascadeType.REFRESH},mappedBy="rightSet",fetch=FetchType.LAZY)//这里RightBean被选为关系的被维护端,用mappedBy表示,填写的值是维护关系的属性的名称
	private Set<RoleBean> roleSet;
	
	
	public Set<RoleBean> getRoleSet() {
		return roleSet;
	}
	public void setRoleSet(Set<RoleBean> roleSet) {
		this.roleSet = roleSet;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getRname() {
		return rname;
	}
	public void setRname(String rname) {
		this.rname = rname;
	}
	
	
}


package ManyToMany;

import java.util.Set;

import javax.persistence.CascadeType;
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.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

/**
 * 角色类
 * @author 青山
 * @date 2014年10月19日
 * @file name: RoleBean.java
 * 
 * 	create table t_role(
		roleid int primary key auto_increment,
		rolename varchar(45)
	);
	
	双向关系:是对等关系,关系维护端是自由选择的,当然一旦选定,以后只能由已选择的里维护
	在这里:角色被选为关系维护端
	
	中间表:
		create table t_role_right(
			role_id int,
			right_id int
		);

 * 
 */
@Entity
@Table(name="t_role")
public class RoleBean {
	@Id
	@Column(name="roleid")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="rolename")
	private String rname;
	
	@ManyToMany(cascade=CascadeType.REFRESH)
	//多对多关系处理使用中间表使用注解JoinTable
	//inverseJoinColumns: (inverse表示被维护端) ,针对被维护端的外键的定义
	//joinColumns: 关系维护端的定义
	@JoinTable(name="t_role_right",
			inverseJoinColumns=@JoinColumn(name="right_id"),
			joinColumns=@JoinColumn(name="role_id")) 
	private Set<RightBean> rightSet;

	
	public int getId() {
		return id;
	}


	public void setId(int id) {
		this.id = id;
	}


	public String getRname() {
		return rname;
	}


	public void setRname(String rname) {
		this.rname = rname;
	}


	public Set<RightBean> getRightSet() {
		return rightSet;
	}


	public void setRightSet(Set<RightBean> rightSet) {
		this.rightSet = rightSet;
	}
	
	
}
【测试】

package ManyToMany;

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

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import util.JPAManagerFactory;

/**
 * 
 * @author 青山
 * @date 2014年10月19日
 * @file name: ManyTest.java
 */
public class ManyTest {
	public static void main(String[] args) {
		EntityManager manager = JPAManagerFactory.getMFInstance().getManager();
		EntityTransaction t = manager.getTransaction();
		t.begin();
		
//		add(manager);
//		query(manager);
		
//		remove(manager);
		
		
		remove2(manager);
		
		
		t.commit();
		manager.close();
	}

	static void remove2(EntityManager manager) {
//		RightBean right = manager.find(RightBean.class, 1);
//		manager.remove(right);
		/**
		 * result: error com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
		 * 		   Cannot delete or update a parent row: a foreign key constraint fails 
		 * 		   (`world`.`t_role_right`, CONSTRAINT `fk_right_id` FOREIGN KEY (`right_id`) 
		 * 			REFERENCES `t_right` (`rightid`) ON DELETE NO ACTION ON UPDATE NO ACTION)
		 * 原因:删除的权限记录是关系的被维护端,它是没有权利去维护关系的,也就是说没有权利去删除中间表
		 * 解决方案:首先需要断开联系,再来进行删除;或者是先删除中间表的记录,再来删除权限表的记录
		 */
		
		
		RightBean right = manager.find(RightBean.class, 1);
		//由于RightBean没有关系的操作权限,而RoleBean又权限,所以只需要在所有和需要删除的权限有关系的RoleBean中的权限列表的权限移除就可以了
		Set<RoleBean> set = right.getRoleSet();
		for(RoleBean role : set){
			role.getRightSet().remove(right);
		}
		
		manager.remove(right);
	}

	static void remove(EntityManager manager) {
		/**
		 * 因为RoleBean是关系的维护端,所有能够JPA先删除了中间表的记录,然后再删除角色记录
		 */
		RoleBean role = manager.find(RoleBean.class, 1);
		manager.remove(role);
		/**
		 * result:
		 *  Hibernate: select rolebean0_.roleid as roleid1_7_0_, rolebean0_.rolename as rolename2_7_0_ from t_role rolebean0_ where rolebean0_.roleid=?
			Hibernate: delete from t_role_right where role_id=?
			Hibernate: delete from t_role where roleid=?
		 */
	}

	static void query(EntityManager manager) {
		 RoleBean role = manager.find(RoleBean.class, 1);
		System.out.println(role.getRname());
		Set<RightBean> set = role.getRightSet();
		for(RightBean right : set){
			System.out.println(right.getRname());
		}
		/**
		 * result:
		 * Hibernate: select rolebean0_.roleid as roleid1_7_0_, rolebean0_.rolename as rolename2_7_0_ from t_role rolebean0_ where rolebean0_.roleid=?
			二级管理员
			Hibernate: select rightset0_.role_id as role_id1_7_0_, rightset0_.right_id as right_id2_8_0_, rightbean1_.rightid as rightid1_6_1_, rightbean1_.rightname as rightnam2_6_1_ from t_role_right rightset0_ inner join t_right rightbean1_ on rightset0_.right_id=rightbean1_.rightid where rightset0_.role_id=?
			普通权限
		 */
	}

	static void add(EntityManager manager) {
		 RoleBean r1 = new RoleBean();
			RoleBean r2 = new RoleBean();
			
			r1.setRname("一级管理员");
			r2.setRname("二级管理员");
			
			RightBean r11 = new RightBean();
			RightBean r12 = new RightBean();
			
			r11.setRname("超级权限");
			r12.setRname("普通权限");
			
			Set<RightBean> s1 = new HashSet<RightBean>();
			Set<RightBean> s2 = new HashSet<RightBean>();
			
			Set<RoleBean> s11 = new HashSet<RoleBean>();
			Set<RoleBean> s22 = new HashSet<RoleBean>();
			
			s1.add(r12);
			s1.add(r11);
			
			s2.add(r12);
			
			s11.add(r1);
			s11.add(r2);
			
			s22.add(r1);
			
			r1.setRightSet(s1);
			r2.setRightSet(s2);
			
			r11.setRoleSet(s11);
			r12.setRoleSet(s22);
			
			manager.persist(r12);
			manager.persist(r11);
			manager.persist(r2);
			manager.persist(r1);
			
			
	}
	
	 
}

 

分享到:
评论

相关推荐

    hibernate-jpa-2.1-api-1.0.2.Final-API文档-中文版.zip

    赠送jar包:hibernate-jpa-2.1-api-1.0.2.Final.jar; 赠送原API文档:hibernate-jpa-2.1-api-1.0.2.Final-javadoc.jar; 赠送源代码:hibernate-jpa-2.1-api-1.0.2.Final-sources.jar; 赠送Maven依赖信息文件:...

    hibernate-jpa-2.1-api-1.0.2.Final-API文档-中英对照版.zip

    赠送jar包:hibernate-jpa-2.1-api-1.0.2.Final.jar; 赠送原API文档:hibernate-jpa-2.1-api-1.0.2.Final-javadoc.jar; 赠送源代码:hibernate-jpa-2.1-api-1.0.2.Final-sources.jar; 赠送Maven依赖信息文件:...

    hibernate-jpa-2.1-api-1.0.0.final-sources.jar

    hibernate-jpa-2.1-api-1.0.0.final-sources.jar 源码 hibernate-jpa-2.1-api-1.0.0.final-sources.jar 源码

    hibernate-jpa-2.0-api-1.0.1.Final.jar

    hibernate-jpa-2.0-api-1.0.1.Final.jar

    hibernate-jpa-2.0-api-1.0.1.Final-sources.jar

    hibernate-jpa-2.0-api-1.0.1.Final-sources.jar hibernate jpa 源代码

    hibernate-jpa-2.1-api-1.0.0.final.jar.zip

    `hibernate-jpa-2.1-api-1.0.0.final.jar`是Hibernate对JPA 2.1规范的实现库,它使得开发者能够使用Hibernate的高效功能同时遵循JPA规范。 **1. Hibernate与JPA的关系** Hibernate最初作为一个独立的ORM框架,后来...

    hibernate-jpa-2.1-api-1.0.0.Final.jar

    hibernate-jpa-2.1-api-1.0.0.Final.jar官方下载,请放心使用

    hibernate-jpa-2.0-api-1.0.0-CR-1.jar

    java.lang.NoClassDefFoundError: javax/persistence/spi/ProviderUtil 或javax/persistence/entitylistener问题

    hibernate-jpa-2.1-api-1.0.2.Final.jar

    java运行依赖jar包

    hibernate-jpa-2.0-api-1.0.1.Final-sources

    总之,深入研究"hibernate-jpa-2.0-api-1.0.1.Final-sources"源码不仅可以增强我们对JPA规范的理解,也能帮助我们在实际开发中更好地利用Hibernate,提高代码质量和项目效率。通过分析源码,我们可以找到优化点,...

    hibernate-jpa-2.1-api-1.0.0.final-sources.jar.zip

    本篇文章将重点围绕“hibernate-jpa-2.1-api-1.0.0.final-sources.jar.zip”这一压缩包,深入解析Hibernate对JPA 2.1 API的实现,以期帮助读者深入理解其内部机制。 JPA(Java Persistence API)是Java平台上的一个...

    hibernate-jpa-2.1-api 1.0.0.Final API

    6. **关系映射**:包括一对一、一对多、多对一和多对多的关系,使用@OneToOne, @OneToMany, @ManyToOne 和 @ManyToMany 注解来定义。 7. **懒加载(Lazy Loading)**:一种优化策略,关联的对象在需要时才从数据库...

    JPA学习笔记-EJB-04JPA关联映射总结

    4. `@ManyToMany`:多对多关系,多个实体可以关联多个其他实体,通常需要一个中间表来存储关系。 在实际应用中,JPA的关联映射不仅可以简化对象关系映射的配置,还能提供诸如级联操作(`@CascadeType`)和懒加载(`...

    querydsl-jpa-codegen-3.3.3.zip

    《Querydsl-JPA-Codegen 3.3.3与JBugmenot开源项目解析》 在IT领域,开源项目是推动技术发展的重要力量。本文将深入探讨两个相关的开源项目——"querydsl-jpa-codegen-3.3.3.zip" 和 "JBugmenot.zip",它们分别在...

    JPA中的多对多双向关联实体定义与注解设置

    在这个主题中,我们将深入探讨如何在JPA中定义和配置双向多对多关联实体,并通过注解进行设置。 首先,我们需要了解JPA中的几个关键注解: 1. `@Entity`:标记一个类作为JPA的实体类,使得该类可以被JPA管理并映射...

    springboot-jpa-activiti-bootstrap-master

    总结来说,"springboot-jpa-activiti-bootstrap-master"项目是一个集成了SpringBoot、JPA和Activiti的实战案例,它涵盖了后端开发的多个重要环节,对于想要提升企业级应用开发能力的开发者来说,这是一个非常有价值...

    实用JPA开发指南----jpa核心技术(关联关系等的配置高级配置)

    4. **多对多(ManyToMany)**: 一个实体可以关联多个实体,反之亦然,如学生可以选修多门课程,课程也可以被多个学生选修。使用`@ManyToMany`注解,并通过`@JoinTable`定义中间表。 **高级配置**包括: 1. **懒...

Global site tag (gtag.js) - Google Analytics