简体   繁体   English

有没有一种方法可以使Dozer映射字段不使用getter或setter方法? (或者,哪个映射器可以做到这一点?)

[英]Is there a way to make Dozer map fields without getter or setters? (Or, what mapper can do this?)

Here's an article on Dozer: https://www.baeldung.com/dozer . 这是有关推土机的文章: https : //www.baeldung.com/dozer It's a mapper that uses reflection to map same-name fields from one object to another (of a completely unrelated class). 这是一个映射器,使用反射将同名字段从一个对象映射到另一个对象(完全不相关的类)。

I was wondering if this works flexibly with private fields, getters, and setters. 我想知道这是否可以灵活地用于私有字段,getter和setter。 That is, 那是,

  • Will private String a map to another object's private String a without either having any getters or setters? private String a映射到另一个对象的private String a而不具有任何获取器或设置器?

  • What if only one side has a getter or setter (and the private field is named something different to make sure it's not directly accessing private fields)? 如果只有一侧有一个getter或setter(并且私有字段被命名为其他名称以确保它不直接访问私有字段),该怎么办?

  • What if one has a getter and the other has a setter for totally mismatching private fields? 如果一个人有一个吸气剂而另一个人有一个用于完全不匹配私有字段的二传手怎么办? (But the getter and setter names match.) (但getter和setter的名称匹配。)

I wrote a test program to run in https://www.jdoodle.com/online-java-compiler : 我编写了一个在https://www.jdoodle.com/online-java-compiler中运行的测试程序:

import org.dozer.DozerBeanMapper;

public class Main {

    public static class MySource {

        // a -> a
        private String a;

        // getB() -> b
        private String hidden_b;
        public String getB() { return hidden_b; }

        // c -> setC(c)
        private String c;

        // getD() -> setD(d)
        private String hidden_d;

        // proper getters and setters on both sides
        private String proper;
        public String getProper() { return proper; }
        // public void setProper(String proper_) { proper = proper_; }

        public MySource() {
            a = "A Room with a View";
            hidden_b = "The Bridge of San Luis Rey";
            c = "Civilwarland in Bad Decline";
            hidden_d = "Darkness at Noon";
            proper = "This should copy, at minimum.";
        }

        public void print() {
            System.out.println("Source");
            System.out.println("================================");
            System.out.println("a        = " + a);
            System.out.println("hidden_b = " + hidden_b);
            System.out.println("c        = " + c);
            System.out.println("hidden_d = " + hidden_d);
            System.out.println("--------------------------------");
            System.out.println("proper   = " + proper);
            System.out.println("");
        }
    }

    public static class MyTarget {

        private String a;
        private String b;
        private String hidden_c;
        private String hidden_e;

        public void setC(String param) { hidden_c = param; }
        public void setD(String param) { hidden_e = param; }

        private String proper;
        // public String getProper() { return proper; }
        public void setProper(String proper_) { proper = proper_; }

        public MyTarget() {}

        public void print() {
            System.out.println("Target");
            System.out.println("================================");
            System.out.println("a        = " + a);
            System.out.println("b        = " + b);
            System.out.println("hidden_c = " + hidden_c);
            System.out.println("hidden_e = " + hidden_e);
            System.out.println("--------------------------------");
            System.out.println("proper   = " + proper);
            System.out.println("");
        }
    }

    public static void main(String args[]) {
        MySource s = new MySource();
        s.print();

        System.out.println("Now dozing...");
        System.out.println("");

        MyTarget t = new DozerBeanMapper().map(s, MyTarget.class);
        t.print();
    }
}

Note that to run the above code you must add a maven dependency: 请注意,要运行上面的代码,必须添加一个maven依赖项:

Group ID:    net.sf.dozer
Artifact ID: dozer
Version:     5.5.1

And also you must try executing a few times because of random timeouts depending on whether the dependency loads fast enough. 而且,由于随机超时,您还必须尝试执行几次,具体取决于依赖项加载的速度是否足够快。

Anyway, my output was: 无论如何,我的输出是:

Source
================================
a        = A Room with a View
hidden_b = The Bridge of San Luis Rey
c        = Civilwarland in Bad Decline
hidden_d = Darkness at Noon
--------------------------------
proper   = This should copy, at minimum.

Now dozing...

Target
================================
a        = null
b        = null
hidden_c = null
hidden_e = null
--------------------------------
proper   = This should copy, at minimum.

So, it appears Dozer only works through a getter on the source and a setter on the target, which is disappointing. 因此,Dozer看起来只能通过源上的吸气剂和目标上的setter来工作,这令人失望。 Or, I'm not using it correctly! 或者,我没有正确使用它!

Is there a way to make Dozer more flexible? 有没有办法使推土机更加灵活? Or, another mapper library that can achieve this? 或者,另一个可以实现此目标的映射器库?

Okay, here are my findings. 好的,这是我的发现。 Hopefully this helps someone. 希望这对某人有帮助。

Dozer 5.5.1 was supposed to be able to do this via "class-level is-accessible." 推土机5.5.1应该能够通过“类级别的可访问性”执行此操作。 However, there was a bug . 但是,有一个错误 It was fixed for future releases, eg Dozer 6.1+. 它已为将来的发行版( 例如 Dozer 6.1+)修复。 (The package moved to a new group, org.github.dozermapper .) The steps were a little complicated though, and eventually I gave up to try ModelMapper, which was much nicer. (程序包移至新组org.github.dozermapper 。)尽管步骤有些复杂,但最终我放弃了尝试ModelMapper,这更好了。 So here's my code. 所以这是我的代码。

Include this package: 包括此软件包:

Group ID:    org.modelmapper
Artifact ID: modelmapper
Version:     2.3.2

Here's how to use it: 使用方法如下:

import org.modelmapper.ModelMapper;
import org.modelmapper.config.Configuration;

public class Main {

    public static class MySource {

        // a -> a
        private String a;

        // getB() -> b
        private String hidden_b;
        public String getB() { return hidden_b; }

        // c -> setC(c)
        private String c;

        // getD() -> setD(d)
        private String hidden_d;

        // proper getters and setters on both sides
        private String proper;
        public String getProper() { return proper; }
        // public void setProper(String proper_) { proper = proper_; }

        public MySource() {
            a = "A Room with a View";
            hidden_b = "The Bridge of San Luis Rey";
            c = "Civilwarland in Bad Decline";
            hidden_d = "Darkness at Noon";
            proper = "This should copy, at minimum.";
        }

        public void print() {
            System.out.println("Source");
            System.out.println("================================");
            System.out.println("a        = " + a);
            System.out.println("hidden_b = " + hidden_b);
            System.out.println("c        = " + c);
            System.out.println("hidden_d = " + hidden_d);
            System.out.println("--------------------------------");
            System.out.println("proper   = " + proper);
            System.out.println("");
        }
    }

    public static class MyTarget {

        private String a;
        private String b;
        private String hidden_c;
        private String hidden_e;

        public void setC(String param) { hidden_c = param; }
        public void setD(String param) { hidden_e = param; }

        private String proper;
        // public String getProper() { return proper; }
        public void setProper(String proper_) { proper = proper_; }

        public MyTarget() {}

        public void print() {
            System.out.println("Target");
            System.out.println("================================");
            System.out.println("a        = " + a);
            System.out.println("b        = " + b);
            System.out.println("hidden_c = " + hidden_c);
            System.out.println("hidden_e = " + hidden_e);
            System.out.println("--------------------------------");
            System.out.println("proper   = " + proper);
            System.out.println("");
        }
    }

    public static void main(String args[]) {

        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
            .setFieldMatchingEnabled(true)
            .setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);

        MySource s = new MySource();
        s.print();

        System.out.println("Now dozing...");
        System.out.println("");

        MyTarget t = modelMapper.map(s, MyTarget.class);
        t.print();
    }
}

Here's my output: 这是我的输出:

Source
================================
a        = A Room with a View
hidden_b = The Bridge of San Luis Rey
c        = Civilwarland in Bad Decline
hidden_d = Darkness at Noon
--------------------------------
proper   = This should copy, at minimum.

Now dozing...

Target
================================
a        = A Room with a View
b        = The Bridge of San Luis Rey
hidden_c = Civilwarland in Bad Decline
hidden_e = null
--------------------------------
proper   = This should copy, at minimum.

The fourth case didn't copy over but I don't really care about that case. 第四种情况没有复制,但我真的不在乎这种情况。 I think it can easily achieved with a different ModelMapper configuration though. 我认为可以使用其他ModelMapper配置轻松实现。 Maybe try LOOSE copying. 也许尝试LOOSE复制。 Or worst case, manually bind the getter and setter methods in the config. 最坏的情况是,在配置中手动绑定getter和setter方法。

Dozer by default uses getters and setters, however you can tell Dozer (via mapping) to access the fields directly http://dozer.sourceforge.net/documentation/custommethods.html 推土机默认情况下使用getter和setter,但是您可以告诉推土机(通过映射)直接访问字段http://dozer.sourceforge.net/documentation/custommethods.html

BTW, Dozer 5 and 6 contains an API based mapping as well. BTW,推土机5和6也包含基于API的映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM