web-dev-qa-db-ja.com

データベースにデータがあるSpringブートでのローカリゼーション(i18n)

私はSpring bootアプリをThymeleafで作成しています。これは2つの言語(またはそれ以上)をサポートするはずです。ロケールリゾルバーとmessages.propertiesを設定したので、アプリでロケールの変更時に静的メッセージを翻訳できるようになりました。

問題は、私のMySQLデータベースにテキストが含まれているデータがあるためです(たとえば、製品の説明)。このデータも翻訳する必要があります。

だから、私の質問は、これのための最良のアプローチは何ですか?すべてのエントリを複製し、2つのテーブルを用意し、言語ごとに2つの個別のアプリを用意しますか?

6
Miha Jamsek

私は自分で問題を解決することができました:

まず、エンティティを作成しました:

製品(ID、名前、価格、説明)

言語(id、lang)

Product_t(id、prod_id、lang_id、name、description)

次に、データベースに関数を作成しました:

FUNCTION `getLangOrder`(language INTEGER, locale varchar(5)) RETURNS int(11)
BEGIN
    case language 
        when (select id from language where lang=locale) then return 1; 
        when 2 then return 2;
        when 1 then return 3;
        else return 4;
    end case;
RETURN 5;
END

この関数は、最初に指定されたロケールで翻訳を順序付け(nullの場合はデフォルト)、それが私が定義した順序で欠落している場合(English(2)、Slovenian(1)、German(3))

次に、JPAのデフォルトのfindAll()関数を使用する代わりに、私のリポジトリで独自のクエリを定義しました。

select p.id
, ifnull((select t.description 
                  from product_t t where t.prod_id = p.id 
                  order by getLangOrder(lang_id, @lang) limit 1)
          , p.description 
  ) as description 
, ifnull((select t.name 
                 from product_t t where t.prod_id = p.proj_id 
                 order by getLangOrder(lang_id, @lang) limit 1)
          , p.name
  ) as name
, p.price 
from product p

ここで@ langは渡された引数です(ロケールはCookieから読み取られます)

次に、エンティティProductを含むリストを作成し、名前と説明を翻訳しました。

1
Miha Jamsek