如何将I18n实现为JPA或Hibernate实体的JSON对象? [英] How can I implement I18n as a JSON object for a JPA or Hibernate entity?

查看:160
本文介绍了如何将I18n实现为JPA或Hibernate实体的JSON对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用JPAHibernateSpring-boot应用程序.您可以在 GitHub存储库上找到整个代码.

I have a Spring-boot application that uses JPA and Hibernate. You can find the whole code on this GitHub repository.

我的问题是如何使用JSON结构如何在没有任何外键的情况下向特定列添加国际化功能?

My question is how can I add internationalization functionality to a specific column without any foreign keys and by using JSON structure?

例如,我想这样定义一个JPA实体:

For example I would like to define a JPA entity like this:

@Entity
class Book {

    @Id
    private int id;

    private Author author;

    @I18n  //<- this annotation is something that I am looking for 
    private String title;

}

,然后将title列中的数据存储为ende区域设置,如下所示:

and then the data in title column would be stored like the following for en and de locales:

{"en":"Cologne","de":"Köln"}

然后,当当前语言环境是de时,Köln并且当en被设置为语言环境时,Cologne会在读取数据时获取!

And then when the current locale is de the Köln and when the en is set as locale then Cologne fetch in the time of reading data!

另外,当我们存储数据时,传递的字符串以JSON格式存储在相关属性中.例如,如果将语言环境设置为es,并且用户通过了Kolne,则我们必须在数据库中具有以下数据:

Also when we store the data, the passed string is stored in the relevant property in the JSON format. For example if the locale is set to es and user passes Kolne then we have to have the following data in the DB:

{"en":"Cologne","de":"Köln","es":"Kolne"}

对我来说很有趣的是,网络上用于hibernate和JPA的大多数解决方案都是基于我们拥有languagestranslations表的旧方法.像此处.

It is interesting for me that most of the solutions in the web for hibernate and JPA is based on an old method that we have languages and translations tables. Something like here or here.

但是我正在寻找的是一些解决方案,例如,这是为Laravel建议的并完全按照我的说明存储翻译(即在JSON对象和同一列中)!

However what I am looking for is some solutions like this one which is suggested for Laravel and store the translations exactly in the way that I explained (i.e. in a JSON object and in the same column)!

我发现的唯一可能与之相关的解决方案(不是100%)是这一个 ,但是当我尝试对其进行测试时它不起作用,并且似乎不再受支持!

The only solution that I found and could be somehow relevant (Not 100%) is this one, however it does not working when I tried to test it and it seems does not supported anymore!

推荐答案

几周后,我可以再次返回到我的

After some weeks I could return back again to my olingo2 odata server project.

我想做的比我预期的要简单.

What I wanted to do was simpler than what I expected.

Vlad Mihalcea 提出了解决方案,我对此表示赞赏,但是正如我在我需要一个在Olingo JPA库之外还可以使用的解决方案!但是,建议的解决方案存在Olingo无法处理JsonBinaryType的问题.

The solution has been suggested by Vlad Mihalcea is good and I appreciate it, however as I mentioned in the question I need a solution that works beside of the Olingo JPA library! However, the suggested solution has this problem that Olingo cannot handle JsonBinaryType.

这是我建议除Olingo JPA之外实施国际化的方法.

Here is my suggestion for implementing internationalization beside of Olingo JPA.

假设我们有一个像这样的BasicModel.java:

Assume we have a BasicModel.java like this:

import java.io.Serializable;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;

import java.io.IOException;

public abstract class BaseModel implements Serializable {
    private static final long serialVersionUID = 1L;
    private static ObjectMapper mapper = new ObjectMapper();

    @SuppressWarnings("unchecked")
    protected static Map<String, String> jsonToMap(String json) {
        Map<String, String> map = new HashMap<>();
        try {
            // convert JSON string to Map
            if (json != null) {
                map = (Map<String, String>) mapper.readValue(json, Map.class);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

    protected static String mapToJson(Map<String, String> map) {
        String json = "";
        try {
            // convert map to JSON string
            json = mapper.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return json;
    }

    protected static String getLang() {
        Locale currentLocale = LocaleContextHolder.getLocale();
        String[] localeStrings = (currentLocale.getLanguage().split("[-_]+"));
        return localeStrings.length > 0 ? localeStrings[0] : "en";
    }
}

此类为我们提供了一种将JSON字符串转换为Map以及反之亦然的机制.

This class provides a mechanism for us to convert JSON strings to Map and vice versa.

转换器代码已从

The code for converters had been adapted from here. For using this snippet of code we need to add this maven dependency:

  <!-- Convert JSON string to Map -->        
  <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
  </dependency>

最后,每当在JPA实体模型中,我们想要对字符串属性使用i18n时,我们只需要稍微修改setter和getter方法即可.例如:

Finally, whenever in a JPA entity model we want to have i18n for a string property we only need to modify setter and getter methods slightly. For example:


import javax.persistence.*;

import java.util.Map;
import java.util.Set;

/**
 * The persistent class for the actions database table.
 * 
 */
@Entity
@Table(name = "actions")
@NamedQuery(name = "Action.findAll", query = "SELECT a FROM Action a")
public class Action extends BaseModel {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id", unique = true, nullable = false, length = 255)
    private String id;

    @Column(nullable = false, length = 255)
    private String name;

    public Action() {
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        Map<String, String> map = jsonToMap(this.name);
        return map.get(getLang());
    }

    public void setName(String name) {
        Map<String, String> map = jsonToMap(this.name);
        map.put(getLang(), name);
        this.name = mapToJson(map);
    }

}

这篇关于如何将I18n实现为JPA或Hibernate实体的JSON对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆