2012-08-14 12 views
5

मैं डेटा वर्ग/तालिका "उपयोगकर्ता" स्तंभ "वरीयताएं" है किजेपीए और हाइबरनेट का उपयोग कर JSON स्ट्रिंग को स्वचालित रूप से क्रमबद्ध और deserialize कैसे करें?

CREATE table "user"; 
ALTER TABLE "user" ADD COLUMN preferences 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); 

मुझे लगता है कि कुछ जैक्सन एनोटेशन हो सकता है कि मैं कर सकता हूं dd उतारने का

तरह
@JsonGenerate 
public String preferences; 

मैं जेपीए के लिए काफी नया हूँ और प्रलेखन खड़ी है।

मेरा मानना ​​है कि मेरा मामला काफी आम है। क्या कोई कोई उदाहरण दे सकता है?

+0

इस डेटा को JSON स्ट्रिंग्स के रूप में संग्रहीत करना और अलग-अलग, अलग-अलग फ़ील्ड (यहां, प्रकार के बूलियन और एनम) के रूप में स्टोर करना चाहते हैं? – Samuel

+0

तर्क यह है कि मैं प्रत्येक कुंजी-मूल्य वरीयता को अलग फ़ील्ड के रूप में समर्थन नहीं देना चाहता हूं। वरीयता कुंजी: मूल्य बढ़ रहे हैं और हैंग और उनमें से बहुत सारे हैं। मॉडल बदलना या उनमें से प्रत्येक के लिए डेटाबेस में फ़ील्ड जोड़ना एक ओवरकिल है। – Roman

+0

क्या आपने मूल्यों की कहानी के लिए एक विशेषता तालिका का उपयोग करने पर विचार किया है? उपयोग का मामला वास्तव में आम है, लेकिन आपका प्रस्तावित समाधान एक संबंधपरक मॉडल में काफी उपयुक्त नहीं है। – Samuel

उत्तर

6

ईमानदारी से मुझे लगता है कि आपका सबसे अच्छा समाधान आपकी संपत्तियों के लिए एक अलग तालिका (वरीयता) बनाना है।

+------------+ 
| 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 के रूप में प्राथमिकताओं को संग्रहीत करने की तरह 'रचनात्मक समाधान' के साथ चारों ओर मूर्ख की जरूरत नहीं है ।

+0

व्यापक विवरण प्रदान करने के लिए धन्यवाद। मैं कोशिश करुंगा! – Roman

+7

यह ऐसा नहीं करता है जिस तरह से सवाल ने अनुरोध किया था। –

+2

@HiramChirino मुझे प्रश्नकर्ता के लिए विकल्प प्रदान करने में कुछ भी गलत नहीं दिख रहा है। खासकर जब कोई विकल्प बेहतर समाधान प्रदान कर सकता है। प्रश्नकर्ता इस समाधान (सहायक) से संतुष्ट था, जवाब आसान या गलत नहीं है इसलिए मुझे मतदान करने का कोई कारण नहीं दिख रहा है। स्टैक ओवरफ्लो के लिए कृपया [वोट देने के लिए सहायता पृष्ठ देखें] (http://stackoverflow.com/help/privileges/vote-down)। – siebz0r

2

तुम सच में की तरह है कि सबसे recommendable आगे क्या करना है कुछ की जरूरत है:

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; 
    } 
} 

अतिरिक्त नोट्स:

  • हो सकता है कि निजी संपत्ति "वरीयताएं" हटाया जा सकता है और गेटर केवल का उपयोग और सेटर।
  • मैंने उस कोड का परीक्षण नहीं किया है।
  • उपरोक्त कोड का उद्देश्य जैक्सन ऑब्जेक्टमैपर और हाइबरनेट मॉड्यूल का उपयोग करना है।
+0

क्या आप कृपया JSON ऐरे का उदाहरण भी प्रदान कर सकते हैं। मैं annonion के साथ JSON ऐरे deserializing संघर्ष कर रहा हूँ। – Azerue

+0

क्या इसे 'प्राथमिकता' नामक कक्षा की आवश्यकता नहीं है जिसके लिए 'उपयोगकर्ता' की सभी अलग-अलग प्राथमिकताओं की आवश्यकता हो सकती है? – Christian

+0

हां। यदि आप कुछ गतिशील पसंद करते हैं, तो आप इसके बजाय नक्शे का बेहतर उपयोग करते हैं। –

6

जेपीए कनवर्टर का उपयोग करके इसे प्राप्त कर सकते हैं।

इकाई;

@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) { 
      // TODO Auto-generated catch block 
      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) { 
      // TODO Auto-generated catch block 
      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); 

मूल्य डीबी में स्टोर के रूप में

{"1":"three","2":"two"} 
0

जैसा कि मैंने this article में बताया गया है, यह करने के लिए बहुत आसान है Hibe का उपयोग कर JSON ऑब्जेक्ट जारी रखें rnate। ,

<dependency> 
    <groupId>com.vladmihalcea</groupId> 
    <artifactId>hibernate-types-52</artifactId> 
    <version>${hibernate-types.version}</version> 
</dependency> 

अधिक जानकारी के लिए hibernate-types open-source project की जाँच:

आप आप बस निम्नलिखित निर्भरता का उपयोग कर Maven सेंट्रल के माध्यम से उन्हें प्राप्त कर सकते हैं, मैन्युअल रूप से इन सभी प्रकार बनाने के लिए नहीं है।

@TypeDef(
    name = "jsonb-node", 
    typeClass = JsonNodeBinaryType.class 
) 

और इकाई मानचित्रण इस तरह दिखेगा:

अब, आप या तो कक्षा स्तर पर या एक package-info.java पैकेज स्तरीय descriptior में नए प्रकार की घोषणा करने की जरूरत है:

@Type(type = "json-node") 
@Column(columnDefinition = "json") 
private JsonNode preferences; 

यही है!

संबंधित मुद्दे