jpa关联关系注解 入门教程(二)
jpa关联关系注解 入门教程(一)
jpa关联关系注解 入门教程(二)
@OrderBy关联查询时排序
一般和@OneToMany一起使用。
(1)源码语法如下:
public @interface OrderBy {
/**
* 要排序的字段,格式如下:
* orderby_list::= orderby_item [,orderby _item]*
* orderby_item::= [property_or_field_name] [ASC | DESC]
* 字段可以是实体属性,也可以是数据字段,默认ASC。
*/
String value() default "";
}
(2)用法示例:
@Entity
@Table(name="user")
public class User implements Serializable{
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="user")
@OrderBy("role_name DESC")
private Set<role> setRole;
...
}
@JoinTable关联关系表
如果对象与对象之间有一个关联关系表的时候,就会用到@JoinTable,一般和@ManyToMany一起使用。
(1)源码语法如下:
public @interface JoinTable {
//中间关联关系表名
String name() default "";
//表的catalog
String catalog() default "";
//表的schema
String schema() default "";
//主链接表的字段
JoinColumn[] joinColumns() default {};
//被链接的表外键字段
JoinColumn[] inverseJoinColumns() default {};
...
}
(2)假设Blog和Tag是多对多的关系,有一个关联关系表blog_tag_relation,表中有两个属性blog_id和tag_id,那么Blog实
体里面的写法如下:
@Entity
public class Blog{
@ManyToMany
@JoinTable(name="blog_tag_relation",
joinColumns=@JoinColumn(name="blog_id",referencedColumnName="id"),
inverseJoinColumn=@JoinColumn(name="tag_id",referencedColumnName="id"))
private List<Tag> tags = new ArrayList<Tag>();
}
这里也可以直接使用@OneToMany根据blog_id关联blog_tag_relation对象,然后再去java方法中根据这个对象再获取tag的列表。
@ManyToMany关联关系
(1)源码语法如下:
public @interface ManyToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default FetchType.LAZY;
String mappedBy() default "";
}
@ManyToMany表示多对多,和@OneToOne、@ManyToOne一样也有单向、双向之分。单向双向和注解没有关系,只看实体类之间是否相互引用。
(2)示例:一个博客可以拥有多个标签,一个标签也可以使用在多个博客上,Blog和Tag就是多对多关系。
单向多对多
@Entity
public class Blog{
@Id
@Column(name = "id")
private Integer id;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name="blog_tag_relation",
joincolumns=@Joincolumn(name="blog_id",referencedColumnName="id"),
inverseJoinColumn=@JoinColumn(name="tag_id",referencedColumnName="id"))
private List<Tag> tags = new ArrayList<Tag>();
...
}
@Entity
public class BlogTagRelation{
@Column(name = "blog_id")
private Integer blogId;
@Column(name = "tag_id")
private Integer tagId;
...
}
@Entity
public class Tag{
@Id
@Column(name = "id")
private Integer id;
...
}
双向多对多
@Entity
public class Blog{
@ManyToMany(cascade-CascadeType.ALL)
@JoinTable(
name="blog_tag_relation",joinColumns=@Joincolumn (name="blog_id",referencedColumnName="id"),
inverseJoinColumn=@JoinColumn(name="tag_id", referencedcolumnName="id")
private List<Tag> tags = new ArrayList<Tag>();
}
@Entity
public class Tag{
@ManyToMany(mappedBy="BlogTagRelation")
private List<Blog> blogs = new ArrayList<Blog>():
}
提示
BlogTagRelation为中间关联关系表blog_tag_relation对应的实体。
关于关系查询的一些坑
(1)所有的注解要么全配置在字段上,要么全配置在get方法上,不能混用,混用就会启动不起来,但是语法配置没有问题。
(2)所有的关联都是支持单向关联和双向关联的,视具体业务场景而定。JSON序列化的时候使用双向注解会产生死循环,需要人为手动转化一次,或者使用@JsonIgnore。
(3)在所有的关联查询中,表一般是不需要建立外键索引的。@mappedBy的使用需要注意。
(4)级联删除比较危险,建议考虑清楚,或者完全掌握。
(5)不同的关联关系的配置,@JoinColumn里面的name、referencedColumnName代表的意思是不一样的,很容易弄混,可以根据打印出来的SQL做调整。
(6)当配置这些关联关系的时候建议大家直接在表上面,把外键建好,然后通过idea Persistence工具直接生成,这样可以减少自己调试的时间。