JPA中实现双向多对多的关联关系(附代码下载)
场景
jpa入门简介与搭建helloworld(附代码下载):
https://blog.csdn.net/badao_liumang_qizhi/article/details/103473937
jpa中实现单向多对一的关联关系:
https://blog.csdn.net/badao_liumang_qizhi/article/details/103511623
jpa中实现单向一对多的关联关系:
https://blog.csdn.net/badao_liumang_qizhi/article/details/103520083
jpa中实现双向一对多的关联关系:
https://blog.csdn.net/badao_liumang_qizhi/article/details/103523564
jpa中实现双向一对一的关联关系:
https://blog.csdn.net/badao_liumang_qizhi/article/details/103530292
按照上面的流程实现以上映射关系后,怎样在jpa中实现双向多对多的映射关系。
比如说商品与分类就是双向多对多的关系。
一个商品可以有多个分类,一个分类可以有多个商品。
在双向多对多关系中,我们必须指定一个关系维护端(owner side),可以通过 @manytomany 注释中指定 mappedby 属性来标识其为关系维护端。
注:
博客主页:
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
首先连接数据库,为了构建出双向多对多的关系,我们需要新建三个表,商品表、分类表、映射关系表。
新建商品表jpa_items
其中id为自增非空主键
然后新建类别表jpa_caterories
其中id为自增非空主键
然后再新建关联表item_category
不要添加主键。
然后打开eclise中上面一直使用的jpa的项目,在包下新建实体类,这里选择使用item作为双向关系维护的一方。
新建item实体类
package com.badao.jpa.helloworld; import java.util.hashset; import java.util.set; 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; @table(name="jpa_items") @entity public class item { private integer id; private string itemname; private set<category> categories = new hashset<>(); @generatedvalue(strategy = generationtype.identity) @id public integer getid() { return id; } public void setid(integer id) { this.id = id; } @column(name="item_name") public string getitemname() { return itemname; } public void setitemname(string itemname) { this.itemname = itemname; } //使用 @manytomany 注解来映射多对多关联关系 //使用 @jointable 来映射中间表 //1. name 指向中间表的名字 //2. joincolumns 映射当前类所在的表在中间表中的外键 //2.1 name 指定外键列的列名 //2.2 referencedcolumnname 指定外键列关联当前表的哪一列 //3. inversejoincolumns 映射关联的类所在中间表的外键 @jointable(name="item_category", joincolumns={@joincolumn(name="item_id", referencedcolumnname="id")}, inversejoincolumns={@joincolumn(name="category_id", referencedcolumnname="id")}) @manytomany public set<category> getcategories() { return categories; } public void setcategories(set<category> categories) { this.categories = categories; } }
注:
在上面注释中已经说明怎样维护关联关系。
然后再新建类别实体类category
package com.badao.jpa.helloworld; import java.util.hashset; import java.util.set; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.manytomany; import javax.persistence.table; @table(name="jpa_categories") @entity public class category { private integer id; private string categoryname; private set<item> items = new hashset<>(); @generatedvalue(strategy = generationtype.identity) @id public integer getid() { return id; } public void setid(integer id) { this.id = id; } @column(name="category_name") public string getcategoryname() { return categoryname; } public void setcategoryname(string categoryname) { this.categoryname = categoryname; } @manytomany(mappedby="categories") public set<item> getitems() { return items; } public void setitems(set<item> items) { this.items = items; } }
在这方主要是通过 @manytomany(mappedby="categories")来指明关系,其中categories要与item中的属性名相对应。
然后打开persistense.xml配置文件,将此两个实体类进行添加
<class>com.badao.jpa.helloworld.item</class> <class>com.badao.jpa.helloworld.category</class>
添加位置如下
打开单元测试类,编写单元测试方法
//多对所的保存 @test public void testmanytomanypersist(){ item i1 = new item(); i1.setitemname("i-1"); item i2 = new item(); i2.setitemname("i-2"); category c1 = new category(); c1.setcategoryname("c-1"); category c2 = new category(); c2.setcategoryname("c-2"); //设置关联关系 i1.getcategories().add(c1); i1.getcategories().add(c2); i2.getcategories().add(c1); i2.getcategories().add(c2); c1.getitems().add(i1); c1.getitems().add(i2); c2.getitems().add(i1); c2.getitems().add(i2); //执行保存 entitymanager.persist(i1); entitymanager.persist(i2); entitymanager.persist(c1); entitymanager.persist(c2); }
运行单元测试,查看商品表
查看类别表
查看关联表
上面是测试的保存方法,再新建测试方法测试查询
//对于关联的集合对象, 默认使用懒加载的策略. //使用维护关联关系的一方获取, 还是使用不维护关联关系的一方获取, sql 语句相同. @test public void testmanytomanyfind(){ item item = entitymanager.find(item.class, 5); system.out.println(item.getitemname()); system.out.println(item.getcategories().size()); }
查询效果
示例代码下载
https://download.csdn.net/download/badao_liumang_qizhi/12054302