Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

SEPARATOR कीवर्ड हाइबरनेट फॉर्मूला में ठीक से काम नहीं कर रहा है

आप SEPARATOR जोड़ सकते हैं कीवर्ड के रूप में। अपना खुद का DialectResolver लागू करें और कीवर्ड छोटे अक्षरों में जोड़ें परिणामी बोली के लिए:

public class MyDialectResolver implements DialectResolver {

    public Dialect resolveDialect(DialectResolutionInfo info) {
        for (Database database : Database.values()) {
            Dialect dialect = database.resolveDialect(info);
            if (dialect != null) {
                dialect.getKeywords().add("separator");
                return dialect;
            }
        }

        return null;
    }
}

हाइबरनेट संस्करणों के लिए पहले . के लिए भी ऐसा ही है 5.2.13 / 5.3.0:

public class MyDialectResolver extends StandardDialectResolver {

    protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
        Dialect dialect = super.resolveDialectInternal(metaData);
        dialect.getKeywords().add("separator");
        return dialect;
    }

}

फिर आपको हाइबरनेट को अपनी बोली रिज़ॉल्वर का उपयोग करने के लिए कहना होगा। उदाहरण के लिए जेपीए में आप इसे अपने हठ में कर सकते हैं।एक्सएमएल:

<persistence>
  <persistence-unit>
    ...
    <property name="hibernate.dialect_resolvers" value="mypackage.MyDialectResolver"/>
  </persistence-unit>
</persistence>

यही बात अन्य बोलियों में एकत्रीकरण कार्यों पर भी लागू होती है। उदाहरण के लिए Oracle में WITHIN कीवर्ड गुम है।

एक और विकल्प है, जो अधिक डेटाबेस स्वतंत्र है (और जिसे मैं पसंद करता हूं)। निम्नलिखित SQLFunction बनाएं :

public class ListAggFunction implements SQLFunction {

    /**
     * The pattern that describes how the function is build in SQL.
     *
     * Replacements:
     * {path} - is replaced with the path of the list attribute
     * {separator} - is replaced with the separator (defaults to '')
     * {orderByPath} - is replaced by the path that is used for ordering the elements of the list
     */
    private String pattern;

    /**
     * Creates a new ListAggFunction definition which uses the ANSI SQL:2016 syntax.
     */
    public ListAggFunction() {
        this("LISTAGG(DISTINCT {path}, {separator}) WITHIN GROUP(ORDER BY {orderByPath})");
    }

    /**
     * Creates a new ListAggFunction definition which uses a database specific syntax.
     *
     * @param pattern  The pattern that describes how the function is build in SQL.
     */
    public ListAggFunction(String pattern) {
        this.pattern = pattern;
    }

    public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
        return StringType.INSTANCE;
    }

    public boolean hasArguments() {
        return true;
    }

    public boolean hasParenthesesIfNoArguments() {
        return true;
    }

    public String render(Type firstArgumentType, List arguments,
            SessionFactoryImplementor factory) throws QueryException {
        if (arguments.isEmpty() || arguments.size() > 3) {
            throw new IllegalArgumentException(
                    "Expected arguments for 'listagg': path [, separator [, order by path]]");
        }

        String path = (String) arguments.get(0);
        String separator = arguments.size() < 2 ? "''" : (String) arguments.get(1);
        String orderByPath = arguments.size() <= 2 ? path : (String) arguments.get(2);

        return StringUtils.replaceEach(this.pattern, new String[] { "{path}", "{separator}", "{orderByPath}" },
                new String[] { path, separator, orderByPath });
    }

}

आप ऊपर दिए गए कीवर्ड की तरह ही इस फ़ंक्शन को DialectResolver में पंजीकृत कर सकते हैं:

 if ("MySQL".equals(info.getDatabaseName()) || "H2".equals(info.getDatabaseName())) {
   dialect.getFunctions().put("listagg", new ListAggFunction("GROUP_CONCAT(DISTINCT {path} ORDER BY {orderByPath} SEPARATOR {separator})"));
 } else {
   dialect.getFunctions().put("listagg", new ListAggFunction());
 }

अब आप बोली के सिंटैक्स के बारे में सोचे बिना अपने JPQL / HQL / मानदंड प्रश्नों में इस फ़ंक्शन का उपयोग कर सकते हैं:

 SELECT e.group, listagg(e.stringProperty, ', ') FROM Entity e GROUP BY e.group



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक ही आईडी में पंक्तियों को सरणी में मर्ज करें

  2. मैं एक MySQL तालिका में कई पंक्तियों को कैसे सम्मिलित कर सकता हूं और नई आईडी वापस कर सकता हूं?

  3. लेफ्ट जॉइन केवल पहली पंक्ति

  4. MySQL JDBC ड्राइवर कनेक्शन स्ट्रिंग क्या है?

  5. mysqli में कई मूल्यों को सम्मिलित करने का सबसे अच्छा तरीका?