8

列「設定」を持つデータクラス/テーブル「ユーザー」があります

CREATE table "user"; 
ALTER TABLE "user" ADD COLUMN preferences TEXT;

設定タイプは TEXT で、そこに JSON を保存しています。

public class User extends AbstractEntity{
public String preferences;
}

だからuser.preferences価値は"{notifyByEmail:1, favouriteColor:"blue" }"

次のようにアクセスできるように、注釈でラップするにはどうすればよいですか

user.preferences.notifyByEmail

またはデータオブジェクトにラップする必要なし

user.preferences.get("notifByEmail");
user.preferences.set("notifByEmail",true);

次のようにフィールドに追加できるジャクソンの注釈がいくつかあると思います

@JsonGenerate
public String preferences;

私はJPAにかなり慣れていないため、ドキュメントは急勾配です。

私のケースはかなり一般的だと思います。誰でも例を挙げることができますか?

4

4 に答える 4

14

JPAコンバーターを使用してこれを実現できます。

実在物;

@Id
@GeneratedValue
Long id;

@Column(name = "mapvalue")
@Convert(converter = MapToStringConverter.class)
Map<String, String> mapValue;

コンバータ:

@Converter
public class MapToStringConverter implements AttributeConverter<Map<String, String>, String> {

    ObjectMapper mapper = new ObjectMapper();

    @Override
    public String convertToDatabaseColumn(Map<String, String> data) {
        String value = "";
        try {
            value = mapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return value;
    }

    @Override
    public Map<String, String> convertToEntityAttribute(String data) {
        Map<String, String> mapValue = new HashMap<String, String>();
        TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {
        };
        try {
            mapValue = mapper.readValue(data, typeRef);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mapValue;
    }

}

データの保存:

Map<String, String> mapValue = new HashMap<String, String>();
mapValue.put("1", "one");
mapValue.put("2", "two");
DataEntity entity = new DataEntity();
entity.setMapValue(mapValue);
repo.save(entity);

値はDBに次のように保存されます

{"1":"three","2":"two"}
于 2017-01-05T08:39:11.173 に答える
5

正直なところ、最善の解決策は、プロパティ用に別のテーブル(設定)を作成することだと思います。

+------------+
| preference |
+------------+---------+------+-----+
| Field      | Type    | Null | Key |
+------------+---------+------+-----+
| user_id    | bigint  | NO   | PRI |
| key        | varchar | NO   | PRI |
| value      | varchar | NO   |     |
+------------+---------+------+-----+

これは、次のようにエンティティにマッピングできます。

@Entity
public class User
{
    @Id
    private Long id;

    @ElementCollection
    @MapKeyColumn(name = "key")
    @Column(name = "value")
    @CollectionTable(name = "preference",
        joinColumns = @JoinColumn(name = "user_id"))
    private Map<String, String> preferences;
}

このようにして、データベースはより正規化され、設定をJSONとして保存するような「創造的なソリューション」をいじくり回す必要はありません。

于 2012-08-15T13:14:27.433 に答える
2

そのようなものが本当に必要な場合、最も推奨されるのは次のことです。

public class User extends AbstractEntity{
  @JsonIgnore //This variable is going to be ignored whenever you send data to a client(ie. web browser)
  private String preferences;

  @Transient //This property is going to be ignored whenever you send data to the database
  @JsonProperty("preferences") //Whenever this property is serialized to the client, it is going to be named "perferences" instead "preferencesObj"
  private Preferences preferencesObj;

  public String getPreferences() {
    return new ObjectMapper().writeValueAsString(preferencesObj);
  }

  pbulic void setPreferneces(String preferences) {
    this.preferences = preferences;
    this.preferncesObj = new ObjectMapper().readValue(preferences, Preferences.class);
  }

  pubilc Preferences getPreferencesObj() {
    return preferencesObj;
  }

  public void setPreferencesObj(Preferences preferencesObj) {
    this.preferencesObj = preferencesObj;
  }
}

その他の注意事項:

  • おそらく、プライベート プロパティの「設定」を削除して、getter と setter のみを使用することができます。
  • 私はそのコードをテストしていません。
  • 上記のコードは、Jackson ObjectMapper と Hibernate モジュールを使用することを目的としています。
于 2014-10-19T18:34:28.670 に答える