多语言数据库,具有默认后备

2024-01-25

我知道,我有一个问题已经被广泛讨论,但在我看来,有一个方面仍然需要澄清。

我正在创建一个带有多语言数据库的网络应用程序,我已经找到了一些好的实践文章(例如this https://web.archive.org/web/20141015195853/https://www.codeproject.com/Articles/752301/Multilanguage-Database-Design-in-MySQL)并在堆栈溢出中给出答案,例如this https://stackoverflow.com/questions/39562/how-do-you-build-a-multi-language-web-site.

因此,我决定使用一个包含我的项目 ID 的主表,另一个包含每个项目翻译的表,例如

Content
ContentTranslation

or

Category
CategoryTranslation

等等。

现在我在做什么?我只是从数据库中获取包含所有翻译的项目,然后迭代每个项目以根据当前用户的本地语言查找正确的翻译,如果找到正确的本地语言,我会将其设置到页面翻译的主要对象中渲染,否则我只会得到标记为“默认”翻译。

但是,对于大量的对象和翻译,服务器响应时间可能会增加,即使用户可能没有注意到,我也不希望出现这种情况。

那么,这个用例有什么好的实践吗?例如,一些特定查询说“选择带有语言环境“it”的翻译,但如果找不到它,只需获取设置了“默认”标志的翻译?

现在对于技术,我将 Spring MVC 与 Hibernate 和 JPA 一起使用(通过 JPARepository)。

我的对象都扩展了我这样创建的基本可翻​​译类

@MappedSuperclass
public abstract class Translatable<T extends Translation> extends BaseDTO {

    private static final long serialVersionUID = 562001309781752460L;

    private String title;

    @OneToMany(fetch=FetchType.EAGER, orphanRemoval=true, cascade=CascadeType.ALL)
    private Set<T> translations = new HashSet<T>();

    @Transient private T currentLocale;

    public void addLocale(T translation, boolean edit) {
        if (!edit)
            getTranslations().add(translation);
    }

    public void remLocale(String locale) {
        T tr = null;
        for (T candidate: getTranslations()) {
            if (candidate.getLocale().equals(locale))
                tr = candidate;
        }

        getTranslations().remove(tr);
    }

    public T getLocaleFromString(String locale) {
        if (locale == null)
            return null;
        for (T trans: translations) {
            if (trans.getLocale().equals(locale))
                return trans;
        }
        return null;
    }

    public T getDefaultLocale() {
        for (T tr: translations) {
            if (tr.isDefaultLocale())
                return tr;
        }
        return null;
    }

    public Set<T> getTranslations() {
        return translations;
    }

    public void setTranslations(Set<T> translations) {
        this.translations = translations;
    }

    public T getCurrentLocale() {
        return currentLocale;
    }

    public void setCurrentLocale(T currentLocale) {
        this.currentLocale = currentLocale;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

因此,在我的控制器中,我迭代翻译,找到具有正确区域设置的翻译并填充“currentLocale”属性,在我的页面中,我只需采用该属性,用户就可以按预期获得正确的语言。

我希望我已经说得清楚而不是混乱,但如果您需要更多信息,我很乐意告诉您更多信息。


前面的一些注释:

  • 我的回答更多的是补充我对这个问题的回答 https://stackoverflow.com/a/929430/19635,您在其中添加了一条评论,然后引发了这个问题
  • 在我的回答中,我使用 C# 和 MS SQL Server(并且我将省略任何 OR 映射特定代码)

在我的应用程序中,我根据用例使用两种不同的方法来加载多语言数据:

管理/增删改查

在用户输入数据或编辑现有数据(例如带有翻译的产品)的情况下,我使用与您在上面的问题中显示的相同的方法,例如:

public class Product
{
    public int ID {get; set;}
    public string SKU {get; set;}
    public IList<ProductTranslation> Translations {get; set;}
}
public class ProductTranslation
{
    public string Language {get; set;}
    public bool IsDefaultLanguage {get; set;}
    public string Title {get; set;}
    public string Description {get; set;}
}

IE。我将让 OR 映射器加载产品实例及其所有附加翻译。然后我迭代翻译并选择需要的翻译。

前端/只读

在这种情况下,主要是前端代码,我通常只是向用户显示信息(最好以用户的语言),我使用不同的方法:

首先,我使用的是不同的数据模型,它不支持/不知道多重翻译的概念。相反,它只是以当前用户的“最佳”语言表示产品:

public class Product
{
    public int ID {get; set;}
    public string SKU {get; set;}

    // language-specific properties
    public string Title {get; set;}
    public string Description {get; set;}
}

为了加载这些数据,我使用了不同的查询(或存储过程)。例如。加载带有 ID 的产品@Id在语言中@Language,我会使用以下查询:

SELECT
    p.ID,
    p.SKU,
    -- get title, description from the requested translation,
    -- or fall back to the default if not found:
    ISNULL(tr.Title, def.Title) Title,
    ISNULL(tr.Description, def.Description) Description
  FROM Products p
  -- join requested translation, if available:
  LEFT OUTER JOIN ProductTranslations tr
    ON p.ID = tr.ProductId AND tr.Language = @Language
  -- join default language of the product:
  LEFT OUTER JOIN ProductTranslations def
    ON p.ID = def.ProductId AND def.IsDefaultLanguage = 1
  WHERE p.ID = @Id

如果存在该语言的翻译,则会返回所请求语言的产品标题和描述。如果不存在翻译,则将返回默认语言的标题和描述。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多语言数据库,具有默认后备 的相关文章

  • Keycloak - 如何获取某个领域的所有用户并将其保存到应用程序数据库?

    我正在使用 Spring Boot 构建 REST API 并使用 Keycloak 进行身份验证和授权 由于用户是由Keycloak管理的 所以我的应用程序数据库没有用户的数据 但我想将 Keycloak 中的用户实体的一些属性存储在我的
  • JPA 中所有命名查询的列表

    我想获取应用程序中所有 NamedQueries 的列表 并且我还想在运行时一般调用它们 是否有一个选项可以获取列表以及某种元数据 一般来说是某种反射 另一个线程为 NHibernate 提供了某种解决方案 即使使用 Hibernate 作
  • 在java中实现你自己的阻塞队列

    我知道这个问题之前已经被问过并回答过很多次了 但我只是无法根据互联网上找到的示例找出窍门 例如this http tutorials jenkov com java concurrency blocking queues html or t
  • 如何获取 WebElement 的父级[重复]

    这个问题在这里已经有答案了 我试过了 private WebElement getParent final WebElement webElement return webElement findElement By xpath 但我得到
  • Java 服务器-客户端 readLine() 方法

    我有一个客户端类和一个服务器类 如果客户端向服务器发送消息 服务器会将响应发送回客户端 然后客户端将打印它收到的所有消息 例如 如果客户端向服务器发送 A 则服务器将向客户端发送响应 1111 所以我在客户端类中使用 readLine 从服
  • 用于从字段中查找最大值的 MongoTemplate 方法或查询

    我正在使用 MongoTemplate 进行数据库操作 现在我想从所选结果中获取最大字段值 有人可以指导我如何编写查询 以便当我将查询传递给 find 方法时 它将返回我所需的文档最大字段 提前致谢 问候 可以在spring data mo
  • 如何在没有 web.xml 的情况下将 Struts2 添加到 Web 应用程序?

    有人可以帮助我使用 Spring Boot 和 Struts2 进行最小项目设置吗 我已经使用 H2 数据库创建了一个 Spring Boot 应用程序 我还添加了一个h2Configuration类 以便我能够访问数据库localhost
  • 隐式超级构造函数 Person() 未定义。必须显式调用另一个构造函数?

    我正在开发一个项目 但收到错误 隐式超级构造函数 Person 未定义 必须显式调用另一个构造函数 我不太明白它 这是我的人物课程 public class Person public Person String name double D
  • Java 数组的最大维数

    出于好奇 在 Java 中数组可以有多少维 爪哇language不限制维数 但是JavaVM规范将维度数限制为 255 例如 以下代码将无法编译 class Main public static void main String args
  • Java 收集返回顶级项目的映射的嵌套流

    我有以下模型 class Item String name List
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • Espresso 和 Proguard 的 Java.lang.NoClassDefFoundError

    我对 Espresso 不太有经验 但我终于成功地运行了它 我有一个应用程序需要通过 Proguard 缩小才能处于 56K 方法之下 该应用程序以 3 秒的动画开始 因此我需要等到该动画结束才能继续 这就是我尝试用该方法做的事情waitF
  • 如何通过 Inno Setup for NetBeans 使用自定义 .iss 文件

    我将 Inno Setup 5 与 NetBeans 8 一起使用 并且我已经能够创建一个安装程序来安装该应用程序C users username local appname 但是我希望将其安装在C Programfiles 我如何在 Ne
  • 对象锁定私有类成员 - 最佳实践? (爪哇)

    I asked 类似的问题 https stackoverflow com questions 10548066 multiple object locks in java前几天 但对回复不满意 主要是因为我提供的代码存在一些人们关注的问题
  • 如何在 Quartz 调度程序中每 25 秒运行一次?

    我正在使用 Java 的 Quartz Scheduling API 你能帮我使用 cron 表达式每 25 秒运行一次吗 这只是一个延迟 它不必总是从第 0 秒开始 例如 序列如下 0 00 0 25 0 50 1 15 1 40 2 0
  • 解决错误javax.mail.AuthenticationFailedException

    我不熟悉java中发送邮件的这个功能 我在发送电子邮件重置密码时遇到错误 希望你能给我一个解决方案 下面是我的代码 public synchronized static boolean sendMailAdvance String emai
  • 挂钩 Eclipse 构建过程吗?

    我希望在 Eclipse 中按下构建按钮时能够运行一个简单的 Java 程序 目前 当我单击 构建 时 它会运行一些 JRebel 日志记录代码 我有一个程序可以解析 JRebel 日志文件并将统计信息存储在数据库中 是否可以编写一个插件或
  • Android - 9 补丁

    我正在尝试使用 9 块图片创建一个新的微调器背景 我尝试了很多方法来获得完美的图像 但都失败了 s Here is my 9 patch 当我用Draw 9 patch模拟时 内容看起来不错 但是带有箭头的部分没有显示 或者当它显示时 这部
  • 在android中跟踪FTP上传数据?

    我有一个运行 Android 的 FTP 系统 但我希望能够在上传时跟踪字节 这样我就可以在上传过程中更新进度条 安卓可以实现这个功能吗 现在 我正在使用org apache common net ftp我正在使用的代码如下 另外 我在 A
  • 迭代 pandas 数据框的最快方法?

    如何运行数据框并仅返回满足特定条件的行 必须在之前的行和列上测试此条件 例如 1 2 3 4 1 1 1999 4 2 4 5 1 2 1999 5 2 3 3 1 3 1999 5 2 3 8 1 4 1999 6 4 2 6 1 5 1

随机推荐

  • Rails 3 - nil 的未定义方法“map”:NilClass 用于我自己的验证

    我遇到了很奇怪的问题 我有Timetable模型并尝试编写我的自定义验证 所以 现在我只是尝试为字段添加测试错误以确保一切正常 但这不起作用 因此 我尝试更新时间表模型的对象 但是当我不使用测试自定义验证时 一切都很完美 否则我会得到这样的
  • 将 geom_text 中的图例文本颜色与符号匹配[重复]

    这个问题在这里已经有答案了 我正在尝试将图例的文本与分解变量生成的文本的颜色进行颜色匹配geom text 这是一个最小的工作示例 df lt data frame a rnorm 10 b 1 10 c letters 1 10 d c
  • Swift 三个双引号

    我是斯威夫特的新手 该文档说 对于占用多行的字符串 请使用三个双引号 只要与结束引号的缩进相匹配 每个带引号的行开头的缩进就会被删除 例如 let quotation Even though there s whitespace to th
  • 类型错误:“list”和“int”实例之间不支持“>=”

    嗨 我遇到了上述错误 问题出在最后一个函数 get student average 上 如果 results 存储 get average student 值 为什么它不能返回 get letter grade results 的结果 ll
  • 求 pi 的值直到 50 位

    我想计算 PI 的值直到 50 位 如何在java中实现小数点后50位 您无法使用默认数据类型执行此操作 因为您需要 50 位数字 50 log 2 log 10 166 位 这里 BigDecimal 是您可以使用的一种类型 但您应该记住
  • nil 的 Ruby 用例,相当于 Python None 或 JavaScript undefined

    鲁比的怎么样nil体现在代码中 例如 在 Python 中 当默认参数引用另一个参数时 您可以使用 None 作为默认参数 但在 Ruby 中 您可以引用 arg 列表中的其他参数 请参阅这个问题 https stackoverflow c
  • npm 发布 - 从 package.json 中删除脚本?

    在发布我的脚本之前 我在 package json 下有许多脚本来编译咖啡脚本 打字稿和仅限开发人员的命令 一旦发布就没有任何意义 我想知道是否有删除 package json 下某些脚本的程序 考虑到在发布包时 它也会发布 package
  • 在 Matter.js 中旋转相机

    我正在开发一款以太空为背景的自上而下的物理游戏 我希望旋转到视图时始终显示玩家的船朝上 即使船可以旋转 我搜索了文档 但没有找到任何有关旋转世界或渲染器的信息 但我可能不知道要查找的正确术语 这对于 Matter js 来说是可能的吗 我不
  • 使用 ng-template 在 Angular 10 中仅显示博客中的相关条目

    我有一个用 Strapi 制作的博客后端 您可以在其中添加一些内容类型 例如标题字段 描述字段和内容字段 我还有一个布尔内容类型来设置博客是否相关 我在 Angular 中设置了一个 ngFor 来显示我所有的博客条目 但我只想展示相关的内
  • 为什么不同 Android 版本的 apk 大小会增加

    我创建了一个简单的应用程序 由 android studio 生成的 apk 大小为 1 MB 然后我安装在android 2 3版本大小增加到3 48 MB 然后我安装在android 5 0版本大小增加至 5 48 MB 我的问题只是为
  • socket.error:[errno 99] 无法分配请求的地址:flask 和 python

    我有同样的问题 and here https stackoverflow com questions 19246103 socket errorerrno 99 cannot assign requested address and nam
  • 单向来源困境

    我在用OneWayToSource绑定 它似乎总是将我的源属性设置为 null 为什么会这样 这给我带来了麻烦 因为我需要源属性中目标属性的值而不是 null 这是我的代码 MyViewModel cs public class MyVie
  • 使用 Aeson 解析嵌套 JSON 中的数组

    我正在尝试写一个FromJSON埃森的功能 JSON total 1 movies id 771315522 title Harry Potter and the Philosophers Stone Wizard s Collection
  • 在Android中使用notifyItemRemoved或notifyDataSetChanged与RecyclerView

    我正在创建一个要使用 RecyclerView 显示的卡片列表 其中每张卡片都有一个用于从列表中删除该卡片的按钮 当我使用通知项目已删除 要删除 RecyclerView 中的卡片 它会删除该项目并进行良好的动画处理 但列表中的数据未正确更
  • 在 PyYAML 中格式化自定义类输出

    我正在这里研究一个简单的示例 但文档仍然让我有点困惑 这是示例代码 class A yaml YAMLObject yaml tag u A def init self val self val val if name main t dat
  • XamlParseException:自定义控件中的属性丢失,但已定义!

    I 有时我的自定义控件出现以下异常 XamlParseException occurred Unknown attribute Points in element SectionClickableArea Line 10 Position
  • 将 MariaDB 与实体框架结合使用

    最近 我读到一则新闻 说 MariaDB 是 MySQL 的替代品 因为MySQL 对集群 企业版的定价不友好 http www theregister co uk 2013 09 12 google mariadb mysql migra
  • Node X-ray 从 url 集合中爬取数据

    我正在尝试在网站中抓取一个列表 该列表会指向具有相同格式的其他页面 我能够创建所有 a 标签的集合 但是当我尝试访问页面集合时 我尝试用它创建的密钥不会添加到返回的对象中 这是我尝试对堆栈溢出执行的操作的示例 var Xray requir
  • 如何在 Mac 操作系统上永久删除 Xampp?

    我用过Xampp 然后把它删除了 然后 我尝试使用Mamp 有一个错误我不明白 Mamp 作为网络服务器运行得非常完美 但是如果我想使用phpmyadmin 它就不起作用了 例如 我向数据库插入一些内容 它没有显示在 phpmyadmin
  • 多语言数据库,具有默认后备

    我知道 我有一个问题已经被广泛讨论 但在我看来 有一个方面仍然需要澄清 我正在创建一个带有多语言数据库的网络应用程序 我已经找到了一些好的实践文章 例如this https web archive org web 2014101519585