在本文中,我们将带你了解@ManyToManyJPA2复杂查询在这篇文章中,我们将为您详细介绍@ManyToManyJPA2复杂查询的方方面面,并解答jpa实现复杂查询常见的疑惑,同时我们还将给您一些
在本文中,我们将带你了解@ManyToMany JPA 2复杂查询在这篇文章中,我们将为您详细介绍@ManyToMany JPA 2复杂查询的方方面面,并解答jpa实现复杂查询常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的@ ManyToMany / @ OneToMany mappingby属性用于双向关联、@OneToMany、@ManyToOne以及@ManyToMany讲解、@OneToMany、@ManyToOne以及@ManyToMany讲解(五)、django 模型ManyToMany 关联的添加,删除,查询。
本文目录一览:- @ManyToMany JPA 2复杂查询(jpa实现复杂查询)
- @ ManyToMany / @ OneToMany mappingby属性用于双向关联
- @OneToMany、@ManyToOne以及@ManyToMany讲解
- @OneToMany、@ManyToOne以及@ManyToMany讲解(五)
- django 模型ManyToMany 关联的添加,删除,查询
@ManyToMany JPA 2复杂查询(jpa实现复杂查询)
我有以下ManyToMany映射。
@Entitypublic class Class1 {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@ManyToMany(fetch = FetchType.LAZY)@JoinTable(name = "class1_class2", joinColumns = @JoinColumn(name = "class1Id"), inverseJoinColumns = @JoinColumn(name = "class2Id"))private List<Class2> class2;}@Entitypublic class Class2 {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;}
我想检索与Classe2实体有关系的所有Class1实体,其中class2Id = 1和class2Id = 2和class2Id = 3。{1,2,3}
或者,要过滤在其class2列表上具有的Classe1实体,请使用具有以下值的Class2实体:class2Id = 1和class2Id =
2和class2Id = 3
例如:
如果在联接表上,我有以下值。
class1Id class2Id 1 1 1 2 1 3 1 4 6 1 6 2 6 3 4 1 5 2
对于该示例,结果将是Class1Id为1和6的Class1。因为Class1Id =
1的Class1实体的classe2Id为1,2,3,4,Class1Id = 2的Class1实体的classe2Id为1。 ,2,3
是否可以通过JPA2(谓词)获得正确的实体?
有没有更好的映射来处理这种情况?
目前,我提出了以下SQL查询:
select v1.class1Id from class1_class2 v1inner join class1_class2 v2 on v1.class1Id=v2.class1Idinner join class1_class2 v3 on v2.class1Id=v3.class1Idwhere v1.classe2Id=1 and v2.classe2Id=2 and v3.classe2Id=3;
答案1
小编典典这是可以提供帮助的查询:
select c1 from Class1 c1 join c1.class2 c2 where c2.id in (1,2,3)group by c1having count(c1)=3 ;
@ ManyToMany / @ OneToMany mappingby属性用于双向关联
我正在为我的实习工作开发JPA兼容套件…该套件的一部分涉及测试极端情况的正确实现。
@ManyToMany
具有mapedBy属性。JPA指出:
字符串mappingBy-拥有关系的字段或属性。除非关系是单向的,否则为必需。
没有给出默认值-默认列为空。
给定双向@ManyToMany
-此示例来自JPA 2.0 JSR-317规范本身!
顾客
@ManyToMany
@JoinTable(name="CUST_PHONES")
public Set<PhoneNumber> getPhones() { return phones; }
电话号码
@ManyToMany(mappedBy="phones")
public Set<Customer> getCustomers() { return customers; }
尚未在@ManyToMany
of的中定义mapledBy属性Customer
!我不知道的双向映射有默认值吗?
我查看了类似的情况,发现: @OneToOne
-mappingBy是可选的,没有默认值
@OneToMany
-完全相同@ManyToMany
(mappedBy对于双向是可选的,没有默认值)
简而言之,我的问题是:
对于@ManyToMany
和@OneToMany
,应在关系的拥有方(Customer
例如)中将其放置在mappedBy属性中?
@OneToMany、@ManyToOne以及@ManyToMany讲解
一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:
create table customer (
id int(20) not null auto_increment,
name varchar(100),
primary key(id)
)
create table address (
id int(20) not null auto_increment,
province varchar(50),
city varchar(50),
postcode varchar(50),
detail varchar(50),
customer_id int(20),
primary key (id)
)
注意此时外键定义在多的一方,也就是address表中。
此时,表customer映射为实体CustomerEO,代码如下:
@Entity
@Table (name="customer")
public class CustomerEO implements java.io.Serializable {
@OneToMany(cascade={ CascadeType.ALL })
@JoinColumn(name="customer_id")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
注释@OneToMany的定义代码如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
使用时要注意一下几点问题:
a、targetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class。
b、mappedBy属性用于标记当实体之间是双向时使用。
(2) 映射策略---表关联
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下:
--客户地址关系表
create table ref_customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
此时表customer映射为CustomerEO实体,代码如下:
@Entity
@Table(name = "customer")
public class CustomerEO implements java.io.Serializable {
...
@OneToMany(cascade = { CascadeType.ALL })
@JoinTable(name="ref_customer_address",
joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")})
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
表关联@JoinTable,定义如下:
@Target({METHOD,FIELD})
public @interface JoinTable {
String name() default "";
String catalog() default "";
String schema() default "";
JoinColumn[] joinColumns() default {};
JoinColumn[] inverseJoinColumns() default {};
UniqueConstraint[] uniqueConstraints default {};
}
其中:
a、该标记和@Table相似,用于标注用于关联的表。
b、name属性为连接两张表的表名。默认的表名为:“表名1”+“-”+“表名2”,上面例子默认的表名为customer_address。
c、joinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
d、inverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。
(3) 默认关联
在数据库底层为两张表添加约束,如下:
create table customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id);
alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);
这样,在CustomerEO中只需要在标注@OneToMany即可!
二、多对一@ManyToOne
1、单向多对一模型。
(1) 外键关联
配置AddressEO实体如下:
@Entity
@Table(name="address")
public class AddressEO implements java.io.Serializable {
@ManyToOne(cascade = { CascadeType.ALL })
@JoinColumn(name="customer_id")
private CustomerEO customer;
// ...
}
@ManyToOne定义如下:
@Target({METHOD,FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fatch() default EAGER;
boolean optional() default true;
}
(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne
三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,而CustomerEO实体修改为:
@Entity
@Table(name="customer")
public class CustomerEO {
@OneToMany(mappedBy="customer")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
// ...
}
其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。
四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fecth() default LAZY;
String mappedBy() default "";
}
五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有Collection、Set、List和Map,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
如Collection可以初始化为ArrayList或HashSet;
Set可以初始化为HashSet;
List可以初始化为ArrayList;
Map可以初始化为HashMap.
2、集合类的选择
Collection类是Set和List的父类,在未确定使用Set或List时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有key和value值的集合。
@OneToMany、@ManyToOne以及@ManyToMany讲解(五)
一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:
create table customer (
id int(20) not null auto_increment,
name varchar(100),
primary key(id)
)
create table address (
id int(20) not null auto_increment,
province varchar(50),
city varchar(50),
postcode varchar(50),
detail varchar(50),
customer_id int(20),
primary key (id)
)
注意此时外键定义在多的一方,也就是address表中。
此时,表customer映射为实体CustomerEO,代码如下:
@Entity
@Table(name="customer")
public class CustomerEO implements java.io.Serializable {
@OneToMany(cascade={ CascadeType.ALL })
@JoinColumn(name="customer_id")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
注释@OneToMany的定义代码如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
使用时要注意一下几点问题:
a、targetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class。
b、mappedBy属性用于标记当实体之间是双向时使用。
(2) 映射策略---表关联
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下:
--客户地址关系表
create table ref_customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
此时表customer映射为CustomerEO实体,代码如下:
@Entity
@Table(name = "customer")
public class CustomerEO implements java.io.Serializable {
...
@OneToMany(cascade = { CascadeType.ALL })
@JoinTable(name="ref_customer_address",
joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")})
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
表关联@JoinTable,定义如下:
@Target({METHOD,FIELD})
public @interface JoinTable {
String name() default "";
String catalog() default "";
String schema() default "";
JoinColumn[] joinColumns() default {};
JoinColumn[] inverseJoinColumns() default {};
UniqueConstraint[] uniqueConstraints default {};
}
其中:
a、该标记和@Table相似,用于标注用于关联的表。
b、name属性为连接两张表的表名。默认的表名为:“表名1”+“-”+“表名2”,上面例子默认的表名为customer_address。
c、joinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
d、inverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。
(3) 默认关联
在数据库底层为两张表添加约束,如下:
create table customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id);
alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);
这样,在CustomerEO中只需要在标注@OneToMany即可!
二、多对一@ManyToOne
1、单向多对一模型。
(1) 外键关联
配置AddressEO实体如下:
@Entity
@Table(name="address")
public class AddressEO implements java.io.Serializable {
@ManyToOne(cascade = { CascadeType.ALL })
@JoinColumn(name="customer_id")
private CustomerEO customer;
// ...
}
@ManyToOne定义如下:
@Target({METHOD,FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fatch() default EAGER;
boolean optional() default true;
}
(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne
三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,而CustomerEO实体修改为:
@Entity
@Table(name="customer")
public class CustomerEO {
@OneToMany(mappedBy="customer")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
// ...
}
其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。
四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fecth() default LAZY;
String mappedBy() default "";
}
五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有Collection、Set、List和Map,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
如Collection可以初始化为ArrayList或HashSet;
Set可以初始化为HashSet;
List可以初始化为ArrayList;
Map可以初始化为HashMap.
2、集合类的选择
Collection类是Set和List的父类,在未确定使用Set或List时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有key和value值的集合。
django 模型ManyToMany 关联的添加,删除,查询
models.py文件内容:
from django.db import models
class person(models.Model):
name = CharField(max_length=30)
class book(models.Model):
auther = ManyToManyField(person)
假设p为一个person对象,b为一个book对象:
#添加关联
b.auther.add(p)
#去除关联
b.auther.remove(p)
#返回所有作者
b.auther.all()
#反向查询,返回这个人写的所有书,book即为反向查询的模型名
p.book_set.all()
如果模型中models.py文件内容:
from django.db import models
class person(models.Model):
name = CharField(max_length=30)
class book(models.Model):
#当关联同一个模型的字段大于一个时,要使用related_name参数来指定表名
auther = ManyToManyField(person,related_name="auther")
translater = ManyToManyField(person,related_name="translater")
此时反向查询p.book_set.all()不可用,取而代之的为
#返回该人写的所有书,book_set被related_name中指定的表名代替
p.auther.all()
#返回该人翻译的所有书
p.translater.all()
我们今天的关于@ManyToMany JPA 2复杂查询和jpa实现复杂查询的分享就到这里,谢谢您的阅读,如果想了解更多关于@ ManyToMany / @ OneToMany mappingby属性用于双向关联、@OneToMany、@ManyToOne以及@ManyToMany讲解、@OneToMany、@ManyToOne以及@ManyToMany讲解(五)、django 模型ManyToMany 关联的添加,删除,查询的相关信息,可以在本站进行搜索。
本文标签: