这种方法是单向的还是双向的

时间:2017-12-08 09:04:24

标签: hibernate jpa one-to-many many-to-one

考虑以下实体

UserDetails(含车辆)

@Entity
public class UserDetails {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
private String userName;

@OneToMany(mappedBy="user",cascade=CascadeType.ALL,orphanRemoval=true)
private List<Vehicle> vehicleList = new ArrayList<>();

//getter setters
}

车辆

@Entity
public class Vehicle {

@Id 
@GeneratedValue(strategy=GenerationType.AUTO)
private int vehicleId;
private String vehicleName;

@ManyToOne
@JoinColumn(name="user_id")
private UserDetails user;

//getter setters
}
  1. 如果我们可以使用下面的代码实现相同的db表,为什么我们应该使用上面的@OneToMany代码?这里使用@OneToMany只是提供了从用户端访问车辆的解决方案 如果我没有要求为任何用户访问车辆,这是正确的配置吗?

  2. 由于它提供了与双向相同的表配置,因此 我们应该说它是单向还是双向的方法?我认为根据代码我们无法从用户端访问车辆,但用户从车辆侧访问,所以它是一种单向的吗?

  3. UserDetails(不含车辆)

    @Entity
    public class UserDetails {
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int userId;
    private String userName;
    
    //getter setters
    }
    

    表用户详细信息

    mysql> select * from userdetails;
    +--------+------------+
    | userId | userName   |
    +--------+------------+
    |        | First User |
    +--------+------------+
    1 row in set (0.00 sec)
    

    表格工具

    mysql> select * from vehicle;
    +-----------+-------------+---------+
    | vehicleId | vehicleName | user_id |
    +-----------+-------------+---------+
    |         2 | karizma     |         |
    |         3 | scooty-pep  |         |
    +-----------+-------------+---------+
    2 rows in set (0.00 sec)
    

3 个答案:

答案 0 :(得分:0)

非常好的观察和问题。

是的,如果真的需要,你应该问@OneToMany。问题是该列表中将包含多少元素以及如何在UI上使用元素。我的经验法则是10个元素。

假设您有银行帐户和@OneToMany笔交易。在某些起始页面的用户界面中,您只显示最新的10个,甚至在您进入历史记录时,您或者希望始终是一个已过滤的列表。你几乎从不想看到所有的交易。但是@OneToMany集合并没有给你任何控制权 - 你不能对它进行过滤,排序或分页。只需加载所有(或FetchType.LAZY的情况下没有任何内容)。

通过JPQL查询删除集合并加载实体会更灵活,更好:

@Query("SELECT v FROM Vehicle v WHERE v.userDetails = :userDetails")
List<Vehicle> getVehicles(UserDetails userDetails); 

此类查询可以对其进行分页,排序和过滤。您还可以在业务案例需要时加入FETCH特定属性。

因此,总而言之,Query方法为集合提供了更多的控制和性能。查询方法的缺点是你必须编写更多的代码,并且导航域模型更难。

答案 1 :(得分:0)

回答-afaik-就像你说的那样

  

在这里使用@OneToMany只是提供了访问的解决方案   来自用户方的车辆

所以这个

  

如果我没有要求访问   任何用户的车辆,这是正确的配置?

它可能不是正确的配置。我只能想到它为什么不会影响性能:如果有很多import React from 'react'; import { View, Text } from 'react-native'; import MultiSlider from '@ptomasroos/react-native-multi-slider'; class RangeSlider extends React.Component { state = { values: [3, 7], }; multiSliderValuesChange = (values) => { this.setState({ values, }); } render() { return ( <View> <MultiSlider values={[this.state.values[0], this.state.values[1]]} sliderLength={280} onValuesChange={this.multiSliderValuesChange} min={0} max={10} step={1} /> <Text style={styles.text}>Two Markers:</Text> <Text style={styles.text}>{this.state.values[0]}</Text> <Text style={styles.text}>{this.state.values[1]}</Text> </View> ) } } s有很多UserDetail s,那么在填充车辆列表时。

可以为Vehicle设置FetchType.LAZY,但取决于JPA实现如何进行内部优化&amp;可能并不总是遵守缓存。

答案 2 :(得分:0)

1)即使对于架构生成List<Vehicle>工具,单向也足够了。请注意,您还可以使用仅定义h2ddl的单向映射。

2)除了获得对该集合的访问权限之外,最重要的原因是能够将@OneToMany操作级联到UserDetails实体上,当你从Vehicle集合中清除它们时删除车辆......我想你不想做逻辑推理。

3)单向的唯一缺点是您需要编写自定义查询才能获得用户的所有车辆。通过双向,您可以找到一个用户,车辆集合已经准备好进行延迟加载。

就个人而言,我会保留vehicleList,但会移除OneToManycascading选项。