मैंने इस प्रश्न पर कुछ कोणों से काम किया है और यहाँ मेरे निष्कर्ष हैं। चेतावनी:मैंने ये सभी जांच MyBatis-3.1.1 का उपयोग करके की थी, इसलिए हो सकता है कि चीजें पहले के संस्करणों में अलग तरह से व्यवहार करती हों।
सबसे पहले, MyBatis में एक अंतर्निहित EnumTypeHandler
है . डिफ़ॉल्ट रूप से, जब भी आप एक जावा एनम को परिणाम टाइप या पैरामीटर टाइप के रूप में निर्दिष्ट करते हैं, तो यह वह है जो उस प्रकार को संभालेगा। प्रश्नों के लिए, जब डेटाबेस रिकॉर्ड को जावा एनम में बदलने का प्रयास किया जाता है, तो EnumTypeHandler केवल एक तर्क लेता है और उस मान के अनुरूप जावा एनम मान को देखने का प्रयास करता है।
एक उदाहरण बेहतर ढंग से चित्रित करेगा। मान लीजिए कि उपरोक्त आपकी क्वेरी 2
returns लौटाती है और "Ready"
जब मैं तर्क के रूप में "तैयार" में जाता हूं। उस स्थिति में, मुझे त्रुटि संदेश मिलता है No enum constant com.foo.Status.2
. अगर मैं आपके सेलेक्ट स्टेटमेंट के क्रम को उलट दूं
SELECT ls.name, ls.id
तो त्रुटि संदेश है No enum constant com.foo.Status.Ready
. मुझे लगता है कि आप अनुमान लगा सकते हैं कि MyBatis क्या कर रहा है। ध्यान दें कि EnumTypeHandler क्वेरी से लौटाए गए दूसरे मान को अनदेखा कर रहा है।
अपनी क्वेरी को
. में बदलनाSELECT UPPER(ls.name)
इसे काम करने का कारण बनता है:Status.READY एनम वापस आ जाता है।
तो आगे मैंने स्टेटस एनम के लिए अपने खुद के टाइपहैंडलर को परिभाषित करने की कोशिश की। दुर्भाग्य से, जैसा कि डिफ़ॉल्ट EnumTypeHandler
. के साथ होता है , मैं सही एनम को संदर्भित करने के लिए केवल एक मान (आईडी या नाम) प्राप्त कर सकता हूं, दोनों नहीं। इसलिए यदि डेटाबेस आईडी आपके द्वारा ऊपर हार्डकोड किए गए मान से मेल नहीं खाता है, तो आपके पास एक बेमेल होगा। यदि आप सुनिश्चित करते हैं कि डेटाबेस आईडी हमेशा आपके द्वारा एनम में निर्दिष्ट आईडी से मेल खाती है, तो आपको डेटाबेस से केवल नाम की आवश्यकता है (ऊपरी मामले में परिवर्तित)।
तब मैंने सोचा कि मैं चतुर हो जाऊंगा और एक MyBatis ObjectFactory को लागू करूंगा, int id और String नाम दोनों को पकड़ूंगा और सुनिश्चित करूंगा कि वे जावा एनम में मेल खाते हैं जो मैं वापस पास करता हूं, लेकिन यह काम नहीं करता क्योंकि MyBatis एक के लिए ObjectFactory को कॉल नहीं करता है। जावा एनम प्रकार (कम से कम मैं इसे काम पर नहीं ला सका)।
तो मेरा निष्कर्ष यह है कि MyBatis में जावा एनम तब तक आसान है जब तक आपको डेटाबेस से नाम को एनम निरंतर नाम से मिलान करने की आवश्यकता होती है - या तो अंतर्निहित EnumTypeHandler का उपयोग करें या यदि आप UPPER (नाम) कर रहे हैं तो अपना खुद का परिभाषित करें SQL जावा एनम नामों से मेल खाने के लिए पर्याप्त नहीं है। कई मामलों में, यह पर्याप्त है, क्योंकि एन्यूमरेटेड वैल्यू सिर्फ एक कॉलम पर एक चेक बाधा हो सकती है और इसका केवल एक ही मान होता है, आईडी भी नहीं। यदि आपको एक इंट आईडी के साथ-साथ एक नाम का मिलान करने की आवश्यकता है, तो जावा एनम और/या डेटाबेस प्रविष्टियों को सेट करते समय आईडी को मैन्युअल रूप से मिलान करें।
अंत में, यदि आप इसका एक कार्यशील उदाहरण देखना चाहते हैं, तो मेरे MyBatis koans के कोन 23 को यहां देखें:https://github.com/midpeter444/mybatis-koans . यदि आप मेरा समाधान देखना चाहते हैं, तो पूर्ण-कोअन्स/koan23 निर्देशिका में देखें। मेरे पास जावा एनम के माध्यम से डेटाबेस में एक रिकॉर्ड डालने का एक उदाहरण भी है।