有没有办法在没有 getter 或设置器的情况下制作推土机地图字段? (或者,什么映射器可以做到这一点?)
Is there a way to make Dozer map fields without getter or setters? (Or, what mapper can do this?)
这是一篇关于 Dozer 的文章:https://www.baeldung.com/dozer。它是一个映射器,使用反射将同名字段从一个对象映射到另一个对象(完全不相关的class)。
我想知道这是否可以灵活地用于私有字段、getters 和 setters。也就是说,
将 private String a
映射到另一个对象的 private String a
而没有任何 getters 或 setters 吗?
如果只有一侧有 getter 或 setter 怎么办(并且私有字段被命名为不同的名称以确保它不直接访问私有字段)?
如果一个 getter 而另一个 setter 完全不匹配私有字段怎么办? (但是 getter 和 setter 名称匹配。)
我在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();
}
}
注意运行以上代码必须添加maven依赖:
Group ID: net.sf.dozer
Artifact ID: dozer
Version: 5.5.1
而且您还必须尝试执行几次,因为随机超时取决于依赖项加载速度是否足够快。
无论如何,我的输出是:
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.
因此,看起来 Dozer 仅 通过源上的 getter 和目标上的 setter 工作,这令人失望。或者,我没有正确使用它!
有没有办法让Dozer更灵活?或者,另一个可以实现此目的的映射器库?
好的,这是我的发现。希望这对某人有所帮助。
Dozer 5.5.1 应该能够通过 "class-level is-accessible." 执行此操作,但是,有 a bug。它已为未来版本修复,例如 Dozer 6.1+。 (该包已移至新组,org.github.dozermapper
。)虽然步骤有点复杂,但最终我放弃尝试 ModelMapper,它更好。所以这是我的代码。
包括这个包:
Group ID: org.modelmapper
Artifact ID: modelmapper
Version: 2.3.2
使用方法如下:
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();
}
}
这是我的输出:
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.
第四个案例没有复制过来,但我真的不关心那个案例。我认为它可以通过不同的 ModelMapper 配置轻松实现。也许尝试松散复制。或者最坏的情况,在配置中手动绑定 getter 和 setter 方法。
Dozer 默认使用 getter 和 setter,但是您可以告诉 Dozer(通过映射)直接访问字段
http://dozer.sourceforge.net/documentation/custommethods.html
顺便说一句,Dozer 5 和 6 也包含基于 API 的映射。
这是一篇关于 Dozer 的文章:https://www.baeldung.com/dozer。它是一个映射器,使用反射将同名字段从一个对象映射到另一个对象(完全不相关的class)。
我想知道这是否可以灵活地用于私有字段、getters 和 setters。也就是说,
将
private String a
映射到另一个对象的private String a
而没有任何 getters 或 setters 吗?如果只有一侧有 getter 或 setter 怎么办(并且私有字段被命名为不同的名称以确保它不直接访问私有字段)?
如果一个 getter 而另一个 setter 完全不匹配私有字段怎么办? (但是 getter 和 setter 名称匹配。)
我在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();
}
}
注意运行以上代码必须添加maven依赖:
Group ID: net.sf.dozer
Artifact ID: dozer
Version: 5.5.1
而且您还必须尝试执行几次,因为随机超时取决于依赖项加载速度是否足够快。
无论如何,我的输出是:
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.
因此,看起来 Dozer 仅 通过源上的 getter 和目标上的 setter 工作,这令人失望。或者,我没有正确使用它!
有没有办法让Dozer更灵活?或者,另一个可以实现此目的的映射器库?
好的,这是我的发现。希望这对某人有所帮助。
Dozer 5.5.1 应该能够通过 "class-level is-accessible." 执行此操作,但是,有 a bug。它已为未来版本修复,例如 Dozer 6.1+。 (该包已移至新组,org.github.dozermapper
。)虽然步骤有点复杂,但最终我放弃尝试 ModelMapper,它更好。所以这是我的代码。
包括这个包:
Group ID: org.modelmapper
Artifact ID: modelmapper
Version: 2.3.2
使用方法如下:
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();
}
}
这是我的输出:
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.
第四个案例没有复制过来,但我真的不关心那个案例。我认为它可以通过不同的 ModelMapper 配置轻松实现。也许尝试松散复制。或者最坏的情况,在配置中手动绑定 getter 和 setter 方法。
Dozer 默认使用 getter 和 setter,但是您可以告诉 Dozer(通过映射)直接访问字段 http://dozer.sourceforge.net/documentation/custommethods.html
顺便说一句,Dozer 5 和 6 也包含基于 API 的映射。