首页 > 解决方案 > 使用弹簧数据 jpa 的关系的条件加载

问题描述

我正在开发一个多语言应用程序,我的表格也是为此目的而设计的。例如,我有一个这样的 Country 类:

@Entity
@Table(name = "province")
public class Province {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "country_id", nullable = false)
    private Country country;

    @OneToMany
    @JoinColumn(name = "province_id")
    private List<ProvinceTranslation> translations;
}

@Entity
@Table(name = "province_translation")
public class ProvinceTranslation {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    private Language language;

    @ManyToOne
    @JoinColumn(name = "province_id")
    private Province province;
}

我希望该translations字段仅加载指定语言的翻译,而国家/地区字段也加载指定语言的翻译(CountryCountryTranslation显然有一个列表!)。我不想编写查询,我希望 spring data jpa 加载与我明确指定的语言的关系。

标签: javaspringhibernatejpaspring-data

解决方案


在这种情况下,似乎需要编写一点JPA 查询。

因为countryTranslation缺课,所以我把重点放在了Province课堂上。

该类Language也是未知的,也许这是enum一个,像这样:

public enum Language {UNKNOWN, GERMAN, ENGLISH, SPAIN}

为了避免加载实体的所有翻译,您必须在从数据库中获取实体时根据给定的语言选择翻译。我更喜欢使用spring 存储库(我希望你已经参与其中)来做到这一点。在这样的ProvinceRepository声明中

    public interface ProvinceRepository extends CrudRepository<Province, Long> {
    ...
    }

您必须提供所需的查找或计数方法。

要获得具有特定翻译的所有省份的列表,您可以在以下代码中声明一个类似这样的函数ProvinceRepository

    @Query("SELECT new org.your.package.goes.here.Province(p.id, p.country, pt.name) FROM Province p inner join p.translations pt where pt.language = ?1")
    List<Province> findAllWithTranslation(Language language);

为了使其工作,必须存在一个接受三个参数的构造函数id, country, name。该name参数可以设置为translationProvince类的新属性,分别是创建的province对象。如果Language该类确实是一个enum类,则@Enumerated必须将注释添加到语言字段。

尽管如此,我相信翻译字符串的提供应该在国际化库 (i18n) 的帮助下更好地完成。


推荐阅读