Jdbi: عند استخدام lambda: "يجب استخدام RowMapper المكتوب بشكل ملموس هنا"

تم إنشاؤها على ٩ أبريل ٢٠١٨  ·  3تعليقات  ·  مصدر: jdbi/jdbi

بادئ ذي بدء: شكرا لهذه المكتبة الرائعة! نحن نهاجر ببطء من Hibernate إلى Jdbi ونحن راضون جدًا عنها حتى الآن ؛)

افترض أن لدي الكود التالي:

getHandle().createQuery("SELECT ...")
    .bind("id", id)
    .registerRowMapper((RowMapper<CatalogueJdbi>) (rs, ctx) -> {
        final CatalogueJdbi catalogue = FieldMapper.of(CatalogueJdbi.class, "c").map(rs, ctx);
        if (rs.getObject("mid") != null) {
            catalogue.setImage(FieldMapper.of(MediaFileJdbi.class, "m").map(rs, ctx));
        }

        return catalogue;
    })
    .mapTo(CatalogueJdbi.class)
    .collect(Collectors.toSet());

عند تسجيل RowMapper كما هو موضح أحصل عليه

java.lang.UnsupportedOperationException: Must use a concretely typed RowMapper here
    at org.jdbi.v3.core.mapper.InferredRowMapperFactory.lambda$new$0(InferredRowMapperFactory.java:38)
    at java.base/java.util.Optional.orElseThrow(Optional.java:385)
    at org.jdbi.v3.core.mapper.InferredRowMapperFactory.<init>(InferredRowMapperFactory.java:38)
    at org.jdbi.v3.core.mapper.RowMappers.register(RowMappers.java:63)
    at org.jdbi.v3.core.config.Configurable.lambda$registerRowMapper$16(Configurable.java:248)
    at org.jdbi.v3.core.config.Configurable.configure(Configurable.java:74)
    at org.jdbi.v3.core.config.Configurable.registerRowMapper(Configurable.java:248)
    at ...

ولكن عند الاستخدام

.registerRowMapper(new RowMapper<CatalogueJdbi>() {
                    <strong i="13">@Override</strong>
                    public CatalogueJdbi map(final ResultSet rs, final StatementContext ctx) throws SQLException {
                        final CatalogueJdbi catalogue = FieldMapper.of(CatalogueJdbi.class, "c").map(rs, ctx);
                        if (rs.getObject("mid") != null) {
                            catalogue.setImage(FieldMapper.of(MediaFileJdbi.class, "m").map(rs, ctx));
                        }

                        return catalogue;
                    }
                })

بدلا من ذلك كل شيء يعمل بشكل جيد.

اعتقدت أن لامدا كانت مجرد سكر نحوي وأن المترجم سوف يوسع الشفرة على أي حال؟

question

التعليق الأكثر فائدة

بسبب المحو العام ، تُفقد المعلمة <CatalogueJdbi> في وقت التشغيل ، لذلك لا يعرف Jdbi أي نوع يتم تعيينه.

هناك طريقة بديلة يمكنك استخدامها ، حيث تمرر النوع كمعامل منفصل:

.registerRowMapper(CatalogueJdbi.class, (rs, ctx) -> { ... })

هناك شيء واحد يجب ملاحظته: تسجيل مخطط الصف ثم استدعاء mapTo(type) يضيع جهدًا إذا لم تتم إعادة استخدام مصمم الخرائط في أي مكان آخر. يمكنك فقط استدعاء طريقة map(RowMapper<T>) وتمرير lambda مباشرةً إلى ذلك:

.map((rs, ctx) -> { ... })

ال 3 كومينتر

بسبب المحو العام ، تُفقد المعلمة <CatalogueJdbi> في وقت التشغيل ، لذلك لا يعرف Jdbi أي نوع يتم تعيينه.

هناك طريقة بديلة يمكنك استخدامها ، حيث تمرر النوع كمعامل منفصل:

.registerRowMapper(CatalogueJdbi.class, (rs, ctx) -> { ... })

هناك شيء واحد يجب ملاحظته: تسجيل مخطط الصف ثم استدعاء mapTo(type) يضيع جهدًا إذا لم تتم إعادة استخدام مصمم الخرائط في أي مكان آخر. يمكنك فقط استدعاء طريقة map(RowMapper<T>) وتمرير lambda مباشرةً إلى ذلك:

.map((rs, ctx) -> { ... })

كنت أعرف أنني كنت أفعل شيئًا خاطئًا :) شكرًا جزيلاً!

على سبيل المتابعة: عند إنشاء فئة داخلية مجهولة الهوية ، فأنت تقوم بإنشاء مصمم خرائط مكتوب بشكل ملموس.

ما نعنيه بالكتابة الملموسة هو أن Jdbi يمكنه الحصول على فئة مصمم الخرائط واكتشاف المعامل العام T لـ RowMapper<T> . سواء كنت تفعل ذلك عبر فصل دراسي كامل مثل class FooMapper implements RowMapper<Foo> { ... } أو عبر فئة داخلية مجهولة مثل new RowMapper<Foo>() { ... } ، يبدو الأمر مشابهًا لـ Jdbi.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات