mappedBy声明于关系的被维护方,声明的值为关系的维护方的关系对象属性名。
在实例中,mappedBy被声明于Course类中,其值为Student类中的Set对象"courses"。即,Student为关系维护方,Course为被维护方。
动态查询:
注意:gt ge like ...注意类型转换 as
一个小规范:
实体类中的集合属性 最好再实体类中先初始化,防止脑残 空指针
一对多:一的房会维护外键,从表维护外键不会发送多余sql
放弃维护外键:提高效率
多对多放弃维护权:
被动一方放弃
Demo:
一对多:
描述:Custom与LinkMan的关系:一对多;
主要的配置:
LinkMan.java
@ManyToOne(targetEntity = Custom.class)
@JoinColumn(name = "linkman_custom_ref" ,referencedColumnName = "cust_id")
private Custom custom;
Custom.java
@OneToMany(mappedBy = "custom")
private List<LinkMan> linkManList = new ArrayList<>();
测试方法:
@org.junit.Test
@Transactional
@Rollback(false)
public void test_create(){
LinkMan linkMan = new LinkMan();
Custom custom = new Custom();
custom.setCustName("changSieTest");
linkMan.setLkmName("changSie");
custom.getLinkManList().add(linkMan);
linkMan.setCustom(custom);
customerDao.save(custom);
linkManDao.save(linkMan);
}
个人理解:
原生sql中,一对多关系的生成依靠多的那一方(本例中的linkMan)建立外键.所以 @ManyToOne和@JoinColumn中的referencedColumnName,表明了外键指向的位置,@JoinColumn的name指定了外键的名字.
当linkman不指定custom对象时,执行调用没有问题,
当linkman中指定custom对象时,只调用linkManDao中的save方法,会报错
个人理解是,当linkman中有对应custom,必须将custom对象也保存到数据库才符合正常逻辑,
另外,在执行保存操作时,先保存一的,在保存多的,否则还会有一次update语句的执行,原因是多的先执行没有外键值,应该是框架再执行 customerDao.save(custom);时,把返回的id付给了custom对象
级联配置:
只需要再@OneToMany注解中添加cascade = CascadeType.ALL, 但是级联操作太危险,所以一般不用
一对多比较标准的写法:
两端都配置
custom.java
@OneToMany(targetEntity = LinkMan.class,cascade = CascadeType.ALL)
@JoinColumn(name = "linkman_custom_ref" ,referencedColumnName = "cust_id")
private List<LinkMan> linkManList = new ArrayList<>();
这样的配置执行时,拥有外键权,会执行update,不用update,把@JoinCloumn删掉,再@oneToMany()mappedBy
其实测试感觉不写mappedBy也可以,只要把@JoinColumn删掉就可以
linkMan.java
@ManyToOne(targetEntity = Custom.class)
@JoinColumn(name = "linkman_custom_ref" ,referencedColumnName = "cust_id")
private Custom custom;
多对多:
情形:user和role是多对多的关系
User.java
@ManyToMany(targetEntity = Role.class)
@JoinTable(name = "user_role_ref",
inverseJoinColumns= {@JoinColumn(name = "sys_role_id",referencedColumnName = "id")},
joinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "id")}
)
Role.java
@ManyToMany(targetEntity = User.class)
@JoinTable(name = "user_role_ref",
joinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "id")}
)
List<User> users = new ArrayList<>();
上面两个类都这么配置的时候,会多执行一次向中间表插入数据,
这会导致两种结果:没有组成联合主键的时候,插入两次重复数据
有联合主键,报错
所以多对多的表必须有一方放弃维护外键,删除@JoinTable,@ManyToMany(mappedBy = "users")
注意多对多时,可能会出现StackOverFlow,原因是我两个类中执行了打印,用到了所以会继续查询,导致溢出
对象导航查询:
查多的,默认是延迟查询
查少的,默认是立即查询,
默认的很符合日常开发,不需要更改
网友评论